diff options
| author | Stanislav Fomichev <sdf@fomichev.me> | 2025-08-18 08:40:29 -0700 |
|---|---|---|
| committer | Sasha Levin <sashal@kernel.org> | 2026-03-04 07:19:45 -0500 |
| commit | cf5997253d980f58849ae9de1c55d749f23c10c6 (patch) | |
| tree | 49454151fa2fb2a0c251c801c7353982083acf64 /net | |
| parent | 93cd8312e1e73527772a8d2a48f9ad49004e96b5 (diff) | |
net: Switch to skb_dstref_steal/skb_dstref_restore for ip_route_input callers
[ Upstream commit e97e6a1830ddb5885ba312e56b6fa3aa39b5f47e ]
Going forward skb_dst_set will assert that skb dst_entry
is empty during skb_dst_set. skb_dstref_steal is added to reset
existing entry without doing refcnt. skb_dstref_restore should
be used to restore the previous entry. Convert icmp_route_lookup
and ip_options_rcv_srr to these helpers. Add extra call to
skb_dstref_reset to icmp_route_lookup to clear the ip_route_input
entry.
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20250818154032.3173645-5-sdf@fomichev.me
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 81b84de32bb2 ("xfrm: fix ip_rt_bug race in icmp_route_lookup reverse path")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net')
| -rw-r--r-- | net/ipv4/icmp.c | 7 | ||||
| -rw-r--r-- | net/ipv4/ip_options.c | 5 |
2 files changed, 6 insertions, 6 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index b17549c4e5de..9e1a574384aa 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -546,14 +546,15 @@ static struct rtable *icmp_route_lookup(struct net *net, struct flowi4 *fl4, goto relookup_failed; } /* Ugh! */ - orefdst = skb_in->_skb_refdst; /* save old refdst */ - skb_dst_set(skb_in, NULL); + orefdst = skb_dstref_steal(skb_in); err = ip_route_input(skb_in, fl4_dec.daddr, fl4_dec.saddr, dscp, rt2->dst.dev); dst_release(&rt2->dst); rt2 = skb_rtable(skb_in); - skb_in->_skb_refdst = orefdst; /* restore old refdst */ + /* steal dst entry from skb_in, don't drop refcnt */ + skb_dstref_steal(skb_in); + skb_dstref_restore(skb_in, orefdst); } if (err) diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index b4c59708fc09..d898e1523a45 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c @@ -615,14 +615,13 @@ int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev) } memcpy(&nexthop, &optptr[srrptr-1], 4); - orefdst = skb->_skb_refdst; - skb_dst_set(skb, NULL); + orefdst = skb_dstref_steal(skb); err = ip_route_input(skb, nexthop, iph->saddr, ip4h_dscp(iph), dev); rt2 = skb_rtable(skb); if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) { skb_dst_drop(skb); - skb->_skb_refdst = orefdst; + skb_dstref_restore(skb, orefdst); return -EINVAL; } refdst_drop(orefdst); |
