diff options
author | Jiri Pirko <jiri@resnulli.us> | 2014-06-26 09:58:25 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-07-01 14:40:17 -0700 |
commit | b0ab2fabb5b91da99c189db02e91ae10bc8355c5 (patch) | |
tree | d3d9aa5bb93078b5fcf027c38a18fba652e5007b /net/core | |
parent | 9bf2b8c280b5c02ca8a9e75263bf3ca998fed144 (diff) | |
download | op-kernel-dev-b0ab2fabb5b91da99c189db02e91ae10bc8355c5.zip op-kernel-dev-b0ab2fabb5b91da99c189db02e91ae10bc8355c5.tar.gz |
rtnetlink: allow to register ops without ops->setup set
So far, it is assumed that ops->setup is filled up. But there might be
case that ops might make sense even without ->setup. In that case,
forbid to newlink and dellink.
This allows to register simple rtnl link ops containing only ->kind.
That allows consistent way of passing device kind (either device-kind or
slave-kind) to userspace.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 2 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 12 |
2 files changed, 11 insertions, 3 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index de97741..6e2a2cd 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -7091,7 +7091,7 @@ static void __net_exit default_device_exit_batch(struct list_head *net_list) rtnl_lock_unregistering(net_list); list_for_each_entry(net, net_list, exit_list) { for_each_netdev_reverse(net, dev) { - if (dev->rtnl_link_ops) + if (dev->rtnl_link_ops && dev->rtnl_link_ops->dellink) dev->rtnl_link_ops->dellink(dev, &dev_kill_list); else unregister_netdevice_queue(dev, &dev_kill_list); diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 1063996..27acaf7 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -299,7 +299,12 @@ int __rtnl_link_register(struct rtnl_link_ops *ops) if (rtnl_link_ops_get(ops->kind)) return -EEXIST; - if (!ops->dellink) + /* The check for setup is here because if ops + * does not have that filled up, it is not possible + * to use the ops for creating device. So do not + * fill up dellink as well. That disables rtnl_dellink. + */ + if (ops->setup && !ops->dellink) ops->dellink = unregister_netdevice_queue; list_add_tail(&ops->list, &link_ops); @@ -1777,7 +1782,7 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh) return -ENODEV; ops = dev->rtnl_link_ops; - if (!ops) + if (!ops || !ops->dellink) return -EOPNOTSUPP; ops->dellink(dev, &list_kill); @@ -2038,6 +2043,9 @@ replay: return -EOPNOTSUPP; } + if (!ops->setup) + return -EOPNOTSUPP; + if (!ifname[0]) snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind); |