]> www.infradead.org Git - users/willy/linux.git/commitdiff
net: Switch to skb_dstref_steal/skb_dstref_restore for ip_route_input callers
authorStanislav Fomichev <sdf@fomichev.me>
Mon, 18 Aug 2025 15:40:29 +0000 (08:40 -0700)
committerJakub Kicinski <kuba@kernel.org>
Wed, 20 Aug 2025 00:54:35 +0000 (17:54 -0700)
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>
net/ipv4/icmp.c
net/ipv4/ip_options.c

index 2ffe73ea644ff71add3911f213735e8ebda590c0..91765057aa1d62025500adb69b6d016b83261eb2 100644 (file)
@@ -544,14 +544,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) ? -EINVAL : 0;
 
                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)
index e3321932bec0dcb554826aad0c72a615b23e0699..be8815ce3ac242372eeae4a97091cda26d40ceb0 100644 (file)
@@ -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) ? -EINVAL : 0;
                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);