netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v2] net: vrf: don't down the interface when add slave
@ 2025-08-07  5:56 Menglong Dong
  2025-08-07 17:32 ` kernel test robot
  2025-08-10  7:41 ` Ido Schimmel
  0 siblings, 2 replies; 5+ messages in thread
From: Menglong Dong @ 2025-08-07  5:56 UTC (permalink / raw)
  To: idosch
  Cc: dsahern, andrew+netdev, davem, edumazet, kuba, pabeni, horms, sdf,
	kuniyu, ahmed.zaki, aleksander.lobakin, netdev, linux-kernel

For now, cycle_netdev() will be called to flush the neighbor cache when
add slave by downing and upping the slave netdev. When the slave has
vlan devices, the data transmission can interrupted.

Optimize it by introducing the NETDEV_VRF_MASTER event. When a net device
is added to the slave of the vrf, the NETDEV_VRF_MASTER event will be
triggered, and the neighbor cache will be flushed, and the routes will be
moved to the corresponding table.

The moving of the routes across tables is tested with following command:

  $ ip link add name dummy1 up type dummy
  $ sysctl -wq net.ipv6.conf.dummy1.keep_addr_on_down=1
  $ ip address add 192.0.2.1/24 dev dummy1
  $ ip address add 2001:db8:1::1/64 dev dummy1
  $ ip link add name vrf1 up type vrf table 100
  $ ip link set dev dummy1 master vrf1

  $ ip -6 r show table 100
  local 2001:db8:1::1 dev dummy1 proto kernel metric 0 pref medium
  2001:db8:1::/64 dev dummy1 proto kernel metric 256 pref medium
  local fe80::cc26:8ff:fe02:ae95 dev dummy1 proto kernel metric 0 pref medium
  fe80::/64 dev dummy1 proto kernel metric 256 pref medium
  multicast ff00::/8 dev dummy1 proto kernel metric 256 pref medium

  $ ip -4 r show table 100
  192.0.2.0/24 dev dummy1 proto kernel scope link src 192.0.2.1
  local 192.0.2.1 dev dummy1 proto kernel scope host src 192.0.2.1
  broadcast 192.0.2.255 dev dummy1 proto kernel scope link src 192.0.2.1

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
v2:
- introduce the NETDEV_VRF_MASTER
---
 drivers/net/vrf.c         | 6 ++----
 include/linux/netdevice.h | 1 +
 net/core/dev.c            | 2 +-
 net/ipv4/arp.c            | 1 +
 net/ipv4/fib_frontend.c   | 3 +++
 net/ipv6/addrconf.c       | 6 +++++-
 net/ipv6/ndisc.c          | 1 +
 7 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 3ccd649913b5..0fee1f46ef97 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -1042,15 +1042,13 @@ static int vrf_rtable_create(struct net_device *dev)
 static void cycle_netdev(struct net_device *dev,
 			 struct netlink_ext_ack *extack)
 {
-	unsigned int flags = dev->flags;
 	int ret;
 
 	if (!netif_running(dev))
 		return;
 
-	ret = dev_change_flags(dev, flags & ~IFF_UP, extack);
-	if (ret >= 0)
-		ret = dev_change_flags(dev, flags, extack);
+	ret = call_netdevice_notifiers(NETDEV_VRF_MASTER, dev);
+	ret = notifier_to_errno(ret);
 
 	if (ret < 0) {
 		netdev_err(dev,
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 5e5de4b0a433..62f0f7f7bcee 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3159,6 +3159,7 @@ enum netdev_cmd {
 	NETDEV_OFFLOAD_XSTATS_REPORT_USED,
 	NETDEV_OFFLOAD_XSTATS_REPORT_DELTA,
 	NETDEV_XDP_FEAT_CHANGE,
+	NETDEV_VRF_MASTER,
 };
 const char *netdev_cmd_to_name(enum netdev_cmd cmd);
 
diff --git a/net/core/dev.c b/net/core/dev.c
index b28ce68830b2..cd5c3ae08487 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1853,7 +1853,7 @@ const char *netdev_cmd_to_name(enum netdev_cmd cmd)
 	N(SVLAN_FILTER_PUSH_INFO) N(SVLAN_FILTER_DROP_INFO)
 	N(PRE_CHANGEADDR) N(OFFLOAD_XSTATS_ENABLE) N(OFFLOAD_XSTATS_DISABLE)
 	N(OFFLOAD_XSTATS_REPORT_USED) N(OFFLOAD_XSTATS_REPORT_DELTA)
-	N(XDP_FEAT_CHANGE)
+	N(XDP_FEAT_CHANGE) N(VRF_MASTER)
 	}
 #undef N
 	return "UNKNOWN_NETDEV_EVENT";
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 5cfc1c939673..67d7c4c949a2 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1328,6 +1328,7 @@ static int arp_netdev_event(struct notifier_block *this, unsigned long event,
 	bool evict_nocarrier;
 
 	switch (event) {
+	case NETDEV_VRF_MASTER:
 	case NETDEV_CHANGEADDR:
 		neigh_changeaddr(&arp_tbl, dev);
 		rt_cache_flush(dev_net(dev));
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 6e1b94796f67..53de7b11e731 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -1510,6 +1510,9 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
 		return NOTIFY_DONE;
 
 	switch (event) {
+	case NETDEV_VRF_MASTER:
+		fib_disable_ip(dev, event, false);
+		fallthrough;
 	case NETDEV_UP:
 		in_dev_for_each_ifa_rtnl(ifa, in_dev) {
 			fib_add_ifaddr(ifa);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f17a5dd4789f..c1f8c8a3e394 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3677,6 +3677,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
 
 		run_pending = 1;
 		fallthrough;
+	case NETDEV_VRF_MASTER:
 	case NETDEV_UP:
 	case NETDEV_CHANGE:
 		if (idev && idev->cnf.disable_ipv6)
@@ -3689,7 +3690,10 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
 			break;
 		}
 
-		if (event == NETDEV_UP) {
+		if (event == NETDEV_VRF_MASTER)
+			addrconf_ifdown(dev, false);
+
+		if (event == NETDEV_UP || event == NETDEV_VRF_MASTER) {
 			/* restore routes for permanent addresses */
 			addrconf_permanent_addr(net, dev);
 
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 7d5abb3158ec..8db8c34b9108 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1858,6 +1858,7 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event,
 	bool evict_nocarrier;
 
 	switch (event) {
+	case NETDEV_VRF_MASTER:
 	case NETDEV_CHANGEADDR:
 		neigh_changeaddr(&nd_tbl, dev);
 		fib6_run_gc(0, net, false);
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2025-08-11  1:14 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-07  5:56 [PATCH net-next v2] net: vrf: don't down the interface when add slave Menglong Dong
2025-08-07 17:32 ` kernel test robot
2025-08-10  7:41 ` Ido Schimmel
2025-08-11  0:03   ` David Ahern
2025-08-11  1:14     ` Menglong Dong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).