[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <2f2b193761ed53f8a529a146e544179864076ce2.camel@mellanox.com>
Date: Fri, 20 Dec 2019 19:29:31 +0000
From: Saeed Mahameed <saeedm@...lanox.com>
To: "jiri@...nulli.us" <jiri@...nulli.us>,
"netdev@...r.kernel.org" <netdev@...r.kernel.org>
CC: Aya Levin <ayal@...lanox.com>,
"davem@...emloft.net" <davem@...emloft.net>,
Moshe Shemesh <moshe@...lanox.com>,
Vlad Buslov <vladbu@...lanox.com>,
Tariq Toukan <tariqt@...lanox.com>,
"jakub.kicinski@...ronome.com" <jakub.kicinski@...ronome.com>,
Michael Guralnik <michaelgur@...lanox.com>,
mlxsw <mlxsw@...lanox.com>, "leon@...nel.org" <leon@...nel.org>
Subject: Re: [patch net-next 3/4] net: introduce dev_net notifier
register/unregister variants
On Fri, 2019-12-20 at 13:35 +0100, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@...lanox.com>
>
> Introduce dev_net variants of netdev notifier register/unregister
> functions
> and allow per-net notifier to follow the netdevice into the namespace
> it is
> moved to.
>
> Signed-off-by: Jiri Pirko <jiri@...lanox.com>
> ---
> include/linux/netdevice.h | 17 +++++++++++++++
> net/core/dev.c | 46
> +++++++++++++++++++++++++++++++++++++++
> 2 files changed, 63 insertions(+)
>
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 7a8ed11f5d45..89ccd4c8d9ea 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -937,6 +937,11 @@ struct netdev_name_node {
> int netdev_name_node_alt_create(struct net_device *dev, const char
> *name);
> int netdev_name_node_alt_destroy(struct net_device *dev, const char
> *name);
>
> +struct netdev_net_notifier {
> + struct list_head list;
> + struct notifier_block *nb;
> +};
> +
> /*
> * This structure defines the management hooks for network devices.
> * The following hooks can be defined; unless noted otherwise, they
> are
> @@ -1790,6 +1795,10 @@ enum netdev_priv_flags {
> *
> * @wol_enabled: Wake-on-LAN is enabled
> *
> + * @net_notifier_list: List of per-net netdev notifier block
> + * that follow this device when it is
> moved
> + * to another network namespace.
> + *
> * FIXME: cleanup struct net_device such that network protocol
> info
> * moves out.
> */
> @@ -2080,6 +2089,8 @@ struct net_device {
> struct lock_class_key addr_list_lock_key;
> bool proto_down;
> unsigned wol_enabled:1;
> +
> + struct list_head net_notifier_list;
> };
> #define to_net_dev(d) container_of(d, struct net_device, dev)
>
> @@ -2523,6 +2534,12 @@ int unregister_netdevice_notifier(struct
> notifier_block *nb);
> int register_netdevice_notifier_net(struct net *net, struct
> notifier_block *nb);
> int unregister_netdevice_notifier_net(struct net *net,
> struct notifier_block *nb);
> +int register_netdevice_notifier_dev_net(struct net_device *dev,
> + struct notifier_block *nb,
> + struct netdev_net_notifier
> *nn);
> +int unregister_netdevice_notifier_dev_net(struct net_device *dev,
> + struct notifier_block *nb,
> + struct netdev_net_notifier
> *nn);
>
> struct netdev_notifier_info {
> struct net_device *dev;
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 932ee131c8c9..f59d2116db8d 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -1874,6 +1874,48 @@ int unregister_netdevice_notifier_net(struct
> net *net,
> }
> EXPORT_SYMBOL(unregister_netdevice_notifier_net);
>
> +int register_netdevice_notifier_dev_net(struct net_device *dev,
> + struct notifier_block *nb,
> + struct netdev_net_notifier *nn)
> +{
> + int err;
> +
> + rtnl_lock();
> + err = __register_netdevice_notifier_net(dev_net(dev), nb,
> false);
> + if (!err) {
> + nn->nb = nb;
looks like there is 1 to 1 mapping between nn and nb,
to save the driver developers the headache of dealing with two objects
just embed the nb object into the nn object and let the driver deal
with nn objects only.
> + list_add(&nn->list, &dev->net_notifier_list);
> + }
> + rtnl_unlock();
> + return err;
> +}
> +EXPORT_SYMBOL(register_netdevice_notifier_dev_net);
> +
> +int unregister_netdevice_notifier_dev_net(struct net_device *dev,
> + struct notifier_block *nb,
> + struct netdev_net_notifier
> *nn)
> +{
> + int err;
> +
> + rtnl_lock();
> + list_del(&nn->list);
> + err = __unregister_netdevice_notifier_net(dev_net(dev), nb);
> + rtnl_unlock();
> + return err;
> +}
> +EXPORT_SYMBOL(unregister_netdevice_notifier_dev_net);
> +
> +static void move_netdevice_notifiers_dev_net(struct net_device *dev,
> + struct net *net)
> +{
> + struct netdev_net_notifier *nn;
> +
> + list_for_each_entry(nn, &dev->net_notifier_list, list) {
> + __unregister_netdevice_notifier_net(dev_net(dev), nn-
> >nb);
> + __register_netdevice_notifier_net(net, nn->nb, true);
> + }
> +}
> +
> /**
> * call_netdevice_notifiers_info - call all network notifier
> blocks
> * @val: value passed unmodified to notifier function
> @@ -9770,6 +9812,7 @@ struct net_device *alloc_netdev_mqs(int
> sizeof_priv, const char *name,
> INIT_LIST_HEAD(&dev->adj_list.lower);
> INIT_LIST_HEAD(&dev->ptype_all);
> INIT_LIST_HEAD(&dev->ptype_specific);
> + INIT_LIST_HEAD(&dev->net_notifier_list);
> #ifdef CONFIG_NET_SCHED
> hash_init(dev->qdisc_hash);
> #endif
> @@ -10031,6 +10074,9 @@ int dev_change_net_namespace(struct
> net_device *dev, struct net *net, const char
> kobject_uevent(&dev->dev.kobj, KOBJ_REMOVE);
> netdev_adjacent_del_links(dev);
>
> + /* Move per-net netdevice notifiers that are following the
> netdevice */
> + move_netdevice_notifiers_dev_net(dev, net);
> +
> /* Actually switch the network namespace */
> dev_net_set(dev, net);
> dev->ifindex = new_ifindex;
Powered by blists - more mailing lists