)]}'
{
  "commit": "af3634d4ac652cd93cb97dd2ad2f01536c2cebc7",
  "tree": "b67310dfb1fa0d08ead953bbb8da42f301709f14",
  "parents": [
    "0fa296dd520eb388e18b97dc553926f82a09cc1d"
  ],
  "author": {
    "name": "Kuniyuki Iwashima",
    "email": "kuniyu@google.com",
    "time": "Fri Jul 03 00:09:17 2026 +0000"
  },
  "committer": {
    "name": "Paolo Abeni",
    "email": "pabeni@redhat.com",
    "time": "Sat Jul 11 12:57:49 2026 +0200"
  },
  "message": "net: Add per-netns netdev unregistration infra.\n\nWhen we need to unregister a netdev in a different netns, we will\ndelegate its unregistration to per-netns work.\n\nThere are three types of such cross-netns devices:\n\n  1. Paired devices (e.g., netkit, veth, vxcan)\n     -\u003e Unregistering one device also deletes its peer, which\n        may reside in another netns.\n\n  2. Tunnel devices (e.g., bareudp, geneve, etc)\n     -\u003e Destroying a netns removes devices in another netns if\n        their backend sockets reside in the dying netns\n\n  3. Stacked devices (e.g., ipvlan, macvlan, etc)\n     -\u003e Removing the lower device also removes multiple upper\n        devices, each of which may reside in different namespaces.\n\nIn these cases, we will use unregister_netdevice_queue_net() to\nqueue such potential cross-netns devices for destruction.\n\nEach driver must not call both unregister_netdevice_queue_net()\nand unregister_netdevice_queue() for the same device.  See the\nsubsequent veth/bareudp/ipvlan patches for how they avoid double\nqueueing.\n\nunregister_netdevice_queue_net() takes net and dev.  If dev resides\nin the net, it simply calls unregister_netdevice_queue().\n\nIf dev_net(dev) is different from the net, it enqueues the device\nto dev_net(dev)-\u003edev_unreg_head and schedules the per-netns work.\n\nWhen __rtnl_net_unlock() is called from the per-netns work (or another\nthread already holding the lock), unregister_netdevice_many_net()\ncollects the queued devices and calls unregister_netdevice_many()\nto perform the actual unregistration.\n\nDuring netns dismantle, rtnl_net_flush_workqueue() is called at the\nend of default_device_exit_batch() to ensure that cross-netns\ndevices in the other alive netns are unregistered.\n\nOnce RTNL is removed, a device could be moved to another netns while\nbeing queued to net-\u003edev_unreg_head.\n\n__dev_change_net_namespace() handles this race by acquiring\nnet-\u003edev_unreg_lock of both the old and new netns after dev_set_net()\nand moving the device between their dev_unreg_head lists.\n\nSince dev_set_net() and unregister_netdevice_queue_net() are\nsynchronised by netdev_lock(), the device is either queued to the\nold netns\u0027s dev_unreg_head and then moved, or queued directly to\nthe new netns.\n\nNote that unregister_netdevice_move_net() does not need to call\nrtnl_net_queue_work() because __dev_change_net_namespace() is\n(supposed to be) called with rtnl_net_lock().  (Not all callers\nhold it yet, but the race does not happen until all callers\nare converted and RTNL is removed.)\n\nSigned-off-by: Kuniyuki Iwashima \u003ckuniyu@google.com\u003e\nLink: https://patch.msgid.link/20260703001009.1572444-7-kuniyu@google.com\nSigned-off-by: Paolo Abeni \u003cpabeni@redhat.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "9981d637f8b546aad80e03f1bc0a653554a04d96",
      "old_mode": 33188,
      "old_path": "include/linux/netdevice.h",
      "new_id": "108d8d7ea75bc82d14ccc78a83c53efc01f9f39f",
      "new_mode": 33188,
      "new_path": "include/linux/netdevice.h"
    },
    {
      "type": "modify",
      "old_id": "a989019af5f7128eaa667d16ad6efc98ccfaac36",
      "old_mode": 33188,
      "old_path": "include/net/net_namespace.h",
      "new_id": "501af1999fe8393d7c282a87645d1c4ceabadddc",
      "new_mode": 33188,
      "new_path": "include/net/net_namespace.h"
    },
    {
      "type": "modify",
      "old_id": "cc77f41452ecac8c52130c47b37edae91332122d",
      "old_mode": 33188,
      "old_path": "net/core/dev.c",
      "new_id": "7ec9af75d14377ac5e3b00144739e536a7efac5e",
      "new_mode": 33188,
      "new_path": "net/core/dev.c"
    },
    {
      "type": "modify",
      "old_id": "d1aeff9de5800122e537df2f8536568a08507163",
      "old_mode": 33188,
      "old_path": "net/core/net_namespace.c",
      "new_id": "578b48cf5318cf24a3c9ef621185c075d91761f1",
      "new_mode": 33188,
      "new_path": "net/core/net_namespace.c"
    },
    {
      "type": "modify",
      "old_id": "608908b3feecbad7fc2e6a354054fc62b995059b",
      "old_mode": 33188,
      "old_path": "net/core/rtnetlink.c",
      "new_id": "cf2b7697a6e7eb22258d42d05b4f7e6dc801e053",
      "new_mode": 33188,
      "new_path": "net/core/rtnetlink.c"
    }
  ]
}
