diff options
-rw-r--r-- | drivers/net/can/dev.c | 1 | ||||
-rw-r--r-- | include/net/rtnetlink.h | 2 | ||||
-rw-r--r-- | net/core/dev.c | 2 |
3 files changed, 4 insertions, 1 deletions
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 2ae9feb99a07..1e0c1a05df82 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -1226,6 +1226,7 @@ static void can_dellink(struct net_device *dev, struct list_head *head) static struct rtnl_link_ops can_link_ops __read_mostly = { .kind = "can", + .netns_refund = true, .maxtype = IFLA_CAN_MAX, .policy = can_policy, .setup = can_setup, diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h index e2091bb2b3a8..4da61c950e93 100644 --- a/include/net/rtnetlink.h +++ b/include/net/rtnetlink.h @@ -33,6 +33,7 @@ static inline int rtnl_msg_family(const struct nlmsghdr *nlh) * * @list: Used internally * @kind: Identifier + * @netns_refund: Physical device, move to init_net on netns exit * @maxtype: Highest device specific netlink attribute number * @policy: Netlink policy for device specific attribute validation * @validate: Optional validation function for netlink/changelink parameters @@ -64,6 +65,7 @@ struct rtnl_link_ops { size_t priv_size; void (*setup)(struct net_device *dev); + bool netns_refund; unsigned int maxtype; const struct nla_policy *policy; int (*validate)(struct nlattr *tb[], diff --git a/net/core/dev.c b/net/core/dev.c index e732faade5dc..2ec21380f86d 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -10121,7 +10121,7 @@ static void __net_exit default_device_exit(struct net *net) continue; /* Leave virtual devices for the generic cleanup */ - if (dev->rtnl_link_ops) + if (dev->rtnl_link_ops && !dev->rtnl_link_ops->netns_refund) continue; /* Push remaining network devices to init_net */ |