summaryrefslogtreecommitdiff
path: root/net/ipv4
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2026-04-02 10:57:09 -0700
committerJakub Kicinski <kuba@kernel.org>2026-04-09 13:20:59 -0700
commitb6e39e48469e37057fce27a1b87cf6d3e456aa42 (patch)
tree1aa6c06171088292548cf8ba04d4e9e0cf1b5b43 /net/ipv4
parent9700282a7ec721e285771d995ccfe33845e776dc (diff)
parenta55f7f5f29b32c2c53cc291899cf9b0c25a07f7c (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Cross-merge networking fixes after downstream PR (net-7.0-rc8). Conflicts: net/ipv6/seg6_iptunnel.c c3812651b522f ("seg6: separate dst_cache for input and output paths in seg6 lwtunnel") 78723a62b969a ("seg6: add per-route tunnel source address") https://lore.kernel.org/adZhwtOYfo-0ImSa@sirena.org.uk net/ipv4/icmp.c fde29fd934932 ("ipv4: icmp: fix null-ptr-deref in icmp_build_probe()") d98adfbdd5c01 ("ipv4: drop ipv6_stub usage and use direct function calls") https://lore.kernel.org/adO3dccqnr6j-BL9@sirena.org.uk Adjacent changes: drivers/net/ethernet/stmicro/stmmac/chain_mode.c 51f4e090b9f8 ("net: stmmac: fix integer underflow in chain mode") 6b4286e05508 ("net: stmmac: rename STMMAC_GET_ENTRY() -> STMMAC_NEXT_ENTRY()") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/nexthop.c41
-rw-r--r--net/ipv4/xfrm4_input.c5
2 files changed, 32 insertions, 14 deletions
diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index 9703e67d552a..904a060a7330 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -902,8 +902,7 @@ static int nla_put_nh_group(struct sk_buff *skb, struct nexthop *nh,
goto nla_put_failure;
if (op_flags & NHA_OP_FLAG_DUMP_STATS &&
- (nla_put_u32(skb, NHA_HW_STATS_ENABLE, nhg->hw_stats) ||
- nla_put_nh_group_stats(skb, nh, op_flags)))
+ nla_put_nh_group_stats(skb, nh, op_flags))
goto nla_put_failure;
return 0;
@@ -1004,16 +1003,32 @@ static size_t nh_nlmsg_size_grp_res(struct nh_group *nhg)
nla_total_size_64bit(8);/* NHA_RES_GROUP_UNBALANCED_TIME */
}
-static size_t nh_nlmsg_size_grp(struct nexthop *nh)
+static size_t nh_nlmsg_size_grp(struct nexthop *nh, u32 op_flags)
{
struct nh_group *nhg = rtnl_dereference(nh->nh_grp);
size_t sz = sizeof(struct nexthop_grp) * nhg->num_nh;
size_t tot = nla_total_size(sz) +
- nla_total_size(2); /* NHA_GROUP_TYPE */
+ nla_total_size(2) + /* NHA_GROUP_TYPE */
+ nla_total_size(0); /* NHA_FDB */
if (nhg->resilient)
tot += nh_nlmsg_size_grp_res(nhg);
+ if (op_flags & NHA_OP_FLAG_DUMP_STATS) {
+ tot += nla_total_size(0) + /* NHA_GROUP_STATS */
+ nla_total_size(4); /* NHA_HW_STATS_ENABLE */
+ tot += nhg->num_nh *
+ (nla_total_size(0) + /* NHA_GROUP_STATS_ENTRY */
+ nla_total_size(4) + /* NHA_GROUP_STATS_ENTRY_ID */
+ nla_total_size_64bit(8)); /* NHA_GROUP_STATS_ENTRY_PACKETS */
+
+ if (op_flags & NHA_OP_FLAG_DUMP_HW_STATS) {
+ tot += nhg->num_nh *
+ nla_total_size_64bit(8); /* NHA_GROUP_STATS_ENTRY_PACKETS_HW */
+ tot += nla_total_size(4); /* NHA_HW_STATS_USED */
+ }
+ }
+
return tot;
}
@@ -1048,14 +1063,14 @@ static size_t nh_nlmsg_size_single(struct nexthop *nh)
return sz;
}
-static size_t nh_nlmsg_size(struct nexthop *nh)
+static size_t nh_nlmsg_size(struct nexthop *nh, u32 op_flags)
{
size_t sz = NLMSG_ALIGN(sizeof(struct nhmsg));
sz += nla_total_size(4); /* NHA_ID */
if (nh->is_group)
- sz += nh_nlmsg_size_grp(nh) +
+ sz += nh_nlmsg_size_grp(nh, op_flags) +
nla_total_size(4) + /* NHA_OP_FLAGS */
0;
else
@@ -1071,7 +1086,7 @@ static void nexthop_notify(int event, struct nexthop *nh, struct nl_info *info)
struct sk_buff *skb;
int err = -ENOBUFS;
- skb = nlmsg_new(nh_nlmsg_size(nh), gfp_any());
+ skb = nlmsg_new(nh_nlmsg_size(nh, 0), gfp_any());
if (!skb)
goto errout;
@@ -3379,15 +3394,15 @@ static int rtm_get_nexthop(struct sk_buff *in_skb, struct nlmsghdr *nlh,
if (err)
return err;
- err = -ENOBUFS;
- skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
- if (!skb)
- goto out;
-
err = -ENOENT;
nh = nexthop_find_by_id(net, id);
if (!nh)
- goto errout_free;
+ goto out;
+
+ err = -ENOBUFS;
+ skb = nlmsg_new(nh_nlmsg_size(nh, op_flags), GFP_KERNEL);
+ if (!skb)
+ goto out;
err = nh_fill_node(skb, nh, RTM_NEWNEXTHOP, NETLINK_CB(in_skb).portid,
nlh->nlmsg_seq, 0, op_flags);
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index f28cfd88eaf5..c2eac844bcdb 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -50,6 +50,7 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
{
struct xfrm_offload *xo = xfrm_offload(skb);
struct iphdr *iph = ip_hdr(skb);
+ struct net_device *dev = skb->dev;
iph->protocol = XFRM_MODE_SKB_CB(skb)->protocol;
@@ -73,8 +74,10 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
}
NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,
- dev_net(skb->dev), NULL, skb, skb->dev, NULL,
+ dev_net(dev), NULL, skb, dev, NULL,
xfrm4_rcv_encap_finish);
+ if (async)
+ dev_put(dev);
return 0;
}