]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
authorJakub Kicinski <kuba@kernel.org>
Sat, 26 Jul 2025 18:44:23 +0000 (11:44 -0700)
committerJakub Kicinski <kuba@kernel.org>
Sat, 26 Jul 2025 18:49:45 +0000 (11:49 -0700)
Merge in late fixes to prepare for the 6.17 net-next PR.

Conflicts:

net/core/neighbour.c
  1bbb76a89948 ("neighbour: Fix null-ptr-deref in neigh_flush_dev().")
  13a936bb99fb ("neighbour: Protect tbl->phash_buckets[] with a dedicated mutex.")
  03dc03fa0432 ("neighbor: Add NTF_EXT_VALIDATED flag for externally validated entries")

Adjacent changes:

drivers/net/usb/usbnet.c
  0d9cfc9b8cb1 ("net: usbnet: Avoid potential RCU stall on LINK_CHANGE event")
  2c04d279e857 ("net: usb: Convert tasklet API to new bottom half workqueue mechanism")

net/ipv6/route.c
  31d7d67ba127 ("ipv6: annotate data-races around rt->fib6_nsiblings")
  1caf27297215 ("ipv6: adopt dst_dev() helper")
  3b3ccf9ed05e ("net: Remove unnecessary NULL check for lwtunnel_fill_encap()")

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
12 files changed:
1  2 
drivers/net/dsa/microchip/ksz8.c
drivers/net/dsa/microchip/ksz8_reg.h
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/phy/micrel.c
drivers/net/usb/usbnet.c
include/linux/usb/usbnet.h
net/core/neighbour.c
net/ipv6/ip6_fib.c
net/ipv6/route.c
tools/testing/selftests/drivers/net/hw/tso.py

Simple merge
Simple merge
Simple merge
index a8d50dd93d12c1e30ad2fe1ae53515af76785b2c,bc1d8631ffe01b69d67d3a7c94e2b1ebd2d11001..a38ffbf4b3f033d628609c692e49e0deec7f9be6
@@@ -1129,8 -1122,11 +1129,11 @@@ static void __handle_link_change(struc
                 * tx queue is stopped by netcore after link becomes off
                 */
        } else {
+               if (test_and_clear_bit(EVENT_LINK_CARRIER_ON, &dev->flags))
+                       netif_carrier_on(dev->net);
                /* submitting URBs for reading packets */
 -              tasklet_schedule(&dev->bh);
 +              queue_work(system_bh_wq, &dev->bh_work);
        }
  
        /* hard_mtu or rx_urb_size may change during link change */
Simple merge
index 4316ca3d987290e06dd3b3dc1dc7c6be4dd510e9,a8dc72eda2027136fbcfc71f8569669cea398725..bddfa389effa774b8f0427b8fe92ad559f4ada11
@@@ -389,37 -415,27 +426,29 @@@ static void neigh_flush_dev(struct neig
        dev_head = neigh_get_dev_table(dev, tbl->family);
  
        hlist_for_each_entry_safe(n, tmp, dev_head, dev_list) {
 -              if (skip_perm && n->nud_state & NUD_PERMANENT)
 +              if (skip_perm &&
 +                  (n->nud_state & NUD_PERMANENT ||
 +                   n->flags & NTF_EXT_VALIDATED))
                        continue;
  
-               hlist_del_rcu(&n->hash);
-               hlist_del_rcu(&n->dev_list);
-               write_lock(&n->lock);
-               neigh_del_timer(n);
-               neigh_mark_dead(n);
-               if (refcount_read(&n->refcnt) != 1) {
-                       /* The most unpleasant situation.
-                        * We must destroy neighbour entry,
-                        * but someone still uses it.
-                        *
-                        * The destroy will be delayed until
-                        * the last user releases us, but
-                        * we must kill timers etc. and move
-                        * it to safe state.
-                        */
-                       __skb_queue_purge(&n->arp_queue);
-                       n->arp_queue_len_bytes = 0;
-                       WRITE_ONCE(n->output, neigh_blackhole);
-                       if (n->nud_state & NUD_VALID)
-                               n->nud_state = NUD_NOARP;
-                       else
-                               n->nud_state = NUD_NONE;
-                       neigh_dbg(2, "neigh %p is stray\n", n);
-               }
-               write_unlock(&n->lock);
-               neigh_cleanup_and_release(n);
+               neigh_flush_one(n);
+       }
+ }
+ static void neigh_flush_table(struct neigh_table *tbl)
+ {
+       struct neigh_hash_table *nht;
+       int i;
+       nht = rcu_dereference_protected(tbl->nht,
+                                       lockdep_is_held(&tbl->lock));
+       for (i = 0; i < (1 << nht->hash_shift); i++) {
+               struct hlist_node *tmp;
+               struct neighbour *n;
+               neigh_for_each_in_bucket_safe(n, tmp, &nht->hash_heads[i])
+                       neigh_flush_one(n);
        }
  }
  
@@@ -435,10 -451,13 +464,15 @@@ static int __neigh_ifdown(struct neigh_
                          bool skip_perm)
  {
        write_lock_bh(&tbl->lock);
-       neigh_flush_dev(tbl, dev, skip_perm);
+       if (likely(dev)) {
+               neigh_flush_dev(tbl, dev, skip_perm);
+       } else {
+               DEBUG_NET_WARN_ON_ONCE(skip_perm);
+               neigh_flush_table(tbl);
+       }
 -      pneigh_ifdown_and_unlock(tbl, dev);
 +      write_unlock_bh(&tbl->lock);
 +
 +      pneigh_ifdown(tbl, dev, skip_perm);
        pneigh_queue_purge(&tbl->proxy_queue, dev ? dev_net(dev) : NULL,
                           tbl->family);
        if (skb_queue_empty_lockless(&tbl->proxy_queue))
Simple merge
index 3fbe0885c21c6e2dcab27d47b09dd71764762794,aaedc08607c01c409276032b3ac213bb1876c726..17c5b54ecad843234de479b3a7ce0256131cecfe
@@@ -5851,13 -5851,13 +5854,13 @@@ static int rt6_fill_node(struct net *ne
                    nla_put_in6_addr(skb, RTA_GATEWAY, &rt6->rt6i_gateway))
                        goto nla_put_failure;
  
 -              if (dst->dev && nla_put_u32(skb, RTA_OIF, dst->dev->ifindex))
 +              dev = dst_dev(dst);
 +              if (dev && nla_put_u32(skb, RTA_OIF, dev->ifindex))
                        goto nla_put_failure;
  
 -              if (dst->lwtstate &&
 -                  lwtunnel_fill_encap(skb, dst->lwtstate, RTA_ENCAP, RTA_ENCAP_TYPE) < 0)
 +              if (lwtunnel_fill_encap(skb, dst->lwtstate, RTA_ENCAP, RTA_ENCAP_TYPE) < 0)
                        goto nla_put_failure;
-       } else if (rt->fib6_nsiblings) {
+       } else if (READ_ONCE(rt->fib6_nsiblings)) {
                struct fib6_info *sibling;
                struct nlattr *mp;