mirror of
https://github.com/torvalds/linux.git
synced 2026-09-14 16:10:02 +02:00
When we need to unregister a netdev in a different netns, we will
delegate its unregistration to per-netns work.
There are three types of such cross-netns devices:
1. Paired devices (e.g., netkit, veth, vxcan)
-> Unregistering one device also deletes its peer, which
may reside in another netns.
2. Tunnel devices (e.g., bareudp, geneve, etc)
-> Destroying a netns removes devices in another netns if
their backend sockets reside in the dying netns
3. Stacked devices (e.g., ipvlan, macvlan, etc)
-> Removing the lower device also removes multiple upper
devices, each of which may reside in different namespaces.
In these cases, we will use unregister_netdevice_queue_net() to
queue such potential cross-netns devices for destruction.
Each driver must not call both unregister_netdevice_queue_net()
and unregister_netdevice_queue() for the same device. See the
subsequent veth/bareudp/ipvlan patches for how they avoid double
queueing.
unregister_netdevice_queue_net() takes net and dev. If dev resides
in the net, it simply calls unregister_netdevice_queue().
If dev_net(dev) is different from the net, it enqueues the device
to dev_net(dev)->dev_unreg_head and schedules the per-netns work.
When __rtnl_net_unlock() is called from the per-netns work (or another
thread already holding the lock), unregister_netdevice_many_net()
collects the queued devices and calls unregister_netdevice_many()
to perform the actual unregistration.
During netns dismantle, rtnl_net_flush_workqueue() is called at the
end of default_device_exit_batch() to ensure that cross-netns
devices in the other alive netns are unregistered.
Once RTNL is removed, a device could be moved to another netns while
being queued to net->dev_unreg_head.
__dev_change_net_namespace() handles this race by acquiring
net->dev_unreg_lock of both the old and new netns after dev_set_net()
and moving the device between their dev_unreg_head lists.
Since dev_set_net() and unregister_netdevice_queue_net() are
synchronised by netdev_lock(), the device is either queued to the
old netns's dev_unreg_head and then moved, or queued directly to
the new netns.
Note that unregister_netdevice_move_net() does not need to call
rtnl_net_queue_work() because __dev_change_net_namespace() is
(supposed to be) called with rtnl_net_lock(). (Not all callers
hold it yet, but the race does not happen until all callers
are converted and RTNL is removed.)
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260703001009.1572444-7-kuniyu@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||
|---|---|---|
| .. | ||
| 6lowpan | ||
| 9p | ||
| 802 | ||
| 8021q | ||
| atm | ||
| batman-adv | ||
| bluetooth | ||
| bpf | ||
| bridge | ||
| can | ||
| ceph | ||
| core | ||
| dcb | ||
| devlink | ||
| dns_resolver | ||
| dsa | ||
| ethernet | ||
| ethtool | ||
| handshake | ||
| hsr | ||
| ieee802154 | ||
| ife | ||
| ipv4 | ||
| ipv6 | ||
| iucv | ||
| kcm | ||
| key | ||
| l2tp | ||
| l3mdev | ||
| lapb | ||
| llc | ||
| mac80211 | ||
| mac802154 | ||
| mctp | ||
| mpls | ||
| mptcp | ||
| ncsi | ||
| netfilter | ||
| netlabel | ||
| netlink | ||
| nfc | ||
| nsh | ||
| openvswitch | ||
| packet | ||
| phonet | ||
| psample | ||
| psp | ||
| qrtr | ||
| rds | ||
| rfkill | ||
| rxrpc | ||
| sched | ||
| sctp | ||
| shaper | ||
| smc | ||
| strparser | ||
| sunrpc | ||
| switchdev | ||
| tipc | ||
| tls | ||
| unix | ||
| vmw_vsock | ||
| wireless | ||
| x25 | ||
| xdp | ||
| xfrm | ||
| compat.c | ||
| devres.c | ||
| Kconfig | ||
| Kconfig.debug | ||
| Makefile | ||
| socket.c | ||
| sysctl_net.c | ||