Skip to content
/ linux Public

Commit cf59972

Browse files
Stanislav FomichevSasha Levin
authored andcommitted
net: Switch to skb_dstref_steal/skb_dstref_restore for ip_route_input callers
[ Upstream commit e97e6a1 ] 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: 81b84de ("xfrm: fix ip_rt_bug race in icmp_route_lookup reverse path") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 93cd831 commit cf59972

File tree

2 files changed

+6
-6
lines changed

2 files changed

+6
-6
lines changed

net/ipv4/icmp.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -546,14 +546,15 @@ static struct rtable *icmp_route_lookup(struct net *net, struct flowi4 *fl4,
546546
goto relookup_failed;
547547
}
548548
/* Ugh! */
549-
orefdst = skb_in->_skb_refdst; /* save old refdst */
550-
skb_dst_set(skb_in, NULL);
549+
orefdst = skb_dstref_steal(skb_in);
551550
err = ip_route_input(skb_in, fl4_dec.daddr, fl4_dec.saddr,
552551
dscp, rt2->dst.dev);
553552

554553
dst_release(&rt2->dst);
555554
rt2 = skb_rtable(skb_in);
556-
skb_in->_skb_refdst = orefdst; /* restore old refdst */
555+
/* steal dst entry from skb_in, don't drop refcnt */
556+
skb_dstref_steal(skb_in);
557+
skb_dstref_restore(skb_in, orefdst);
557558
}
558559

559560
if (err)

net/ipv4/ip_options.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -615,14 +615,13 @@ int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev)
615615
}
616616
memcpy(&nexthop, &optptr[srrptr-1], 4);
617617

618-
orefdst = skb->_skb_refdst;
619-
skb_dst_set(skb, NULL);
618+
orefdst = skb_dstref_steal(skb);
620619
err = ip_route_input(skb, nexthop, iph->saddr, ip4h_dscp(iph),
621620
dev);
622621
rt2 = skb_rtable(skb);
623622
if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) {
624623
skb_dst_drop(skb);
625-
skb->_skb_refdst = orefdst;
624+
skb_dstref_restore(skb, orefdst);
626625
return -EINVAL;
627626
}
628627
refdst_drop(orefdst);

0 commit comments

Comments
 (0)