Patch "ipv4: give an IPv4 dev to blackhole_netdev" has been added to the 6.11-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    ipv4: give an IPv4 dev to blackhole_netdev

to the 6.11-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     ipv4-give-an-ipv4-dev-to-blackhole_netdev.patch
and it can be found in the queue-6.11 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit ba80dfabf802f05b2e967732cf38508f09626fa6
Author: Xin Long <lucien.xin@xxxxxxxxx>
Date:   Wed Oct 9 14:47:13 2024 -0400

    ipv4: give an IPv4 dev to blackhole_netdev
    
    [ Upstream commit 22600596b6756b166fd052d5facb66287e6f0bad ]
    
    After commit 8d7017fd621d ("blackhole_netdev: use blackhole_netdev to
    invalidate dst entries"), blackhole_netdev was introduced to invalidate
    dst cache entries on the TX path whenever the cache times out or is
    flushed.
    
    When two UDP sockets (sk1 and sk2) send messages to the same destination
    simultaneously, they are using the same dst cache. If the dst cache is
    invalidated on one path (sk2) while the other (sk1) is still transmitting,
    sk1 may try to use the invalid dst entry.
    
             CPU1                   CPU2
    
          udp_sendmsg(sk1)       udp_sendmsg(sk2)
          udp_send_skb()
          ip_output()
                                                 <--- dst timeout or flushed
                                 dst_dev_put()
          ip_finish_output2()
          ip_neigh_for_gw()
    
    This results in a scenario where ip_neigh_for_gw() returns -EINVAL because
    blackhole_dev lacks an in_dev, which is needed to initialize the neigh in
    arp_constructor(). This error is then propagated back to userspace,
    breaking the UDP application.
    
    The patch fixes this issue by assigning an in_dev to blackhole_dev for
    IPv4, similar to what was done for IPv6 in commit e5f80fcf869a ("ipv6:
    give an IPv6 dev to blackhole_netdev"). This ensures that even when the
    dst entry is invalidated with blackhole_dev, it will not fail to create
    the neigh entry.
    
    As devinet_init() is called ealier than blackhole_netdev_init() in system
    booting, it can not assign the in_dev to blackhole_dev in devinet_init().
    As Paolo suggested, add a separate late_initcall() in devinet.c to ensure
    inet_blackhole_dev_init() is called after blackhole_netdev_init().
    
    Fixes: 8d7017fd621d ("blackhole_netdev: use blackhole_netdev to invalidate dst entries")
    Signed-off-by: Xin Long <lucien.xin@xxxxxxxxx>
    Reviewed-by: Eric Dumazet <edumazet@xxxxxxxxxx>
    Link: https://patch.msgid.link/3000792d45ca44e16c785ebe2b092e610e5b3df1.1728499633.git.lucien.xin@xxxxxxxxx
    Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index ddab151164542..4d0c8d501ab7c 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -288,17 +288,19 @@ static struct in_device *inetdev_init(struct net_device *dev)
 	/* Account for reference dev->ip_ptr (below) */
 	refcount_set(&in_dev->refcnt, 1);
 
-	err = devinet_sysctl_register(in_dev);
-	if (err) {
-		in_dev->dead = 1;
-		neigh_parms_release(&arp_tbl, in_dev->arp_parms);
-		in_dev_put(in_dev);
-		in_dev = NULL;
-		goto out;
+	if (dev != blackhole_netdev) {
+		err = devinet_sysctl_register(in_dev);
+		if (err) {
+			in_dev->dead = 1;
+			neigh_parms_release(&arp_tbl, in_dev->arp_parms);
+			in_dev_put(in_dev);
+			in_dev = NULL;
+			goto out;
+		}
+		ip_mc_init_dev(in_dev);
+		if (dev->flags & IFF_UP)
+			ip_mc_up(in_dev);
 	}
-	ip_mc_init_dev(in_dev);
-	if (dev->flags & IFF_UP)
-		ip_mc_up(in_dev);
 
 	/* we can receive as soon as ip_ptr is set -- do this last */
 	rcu_assign_pointer(dev->ip_ptr, in_dev);
@@ -337,6 +339,19 @@ static void inetdev_destroy(struct in_device *in_dev)
 	in_dev_put(in_dev);
 }
 
+static int __init inet_blackhole_dev_init(void)
+{
+	int err = 0;
+
+	rtnl_lock();
+	if (!inetdev_init(blackhole_netdev))
+		err = -ENOMEM;
+	rtnl_unlock();
+
+	return err;
+}
+late_initcall(inet_blackhole_dev_init);
+
 int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b)
 {
 	const struct in_ifaddr *ifa;




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux