X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=net%2Fcore%2Frtnetlink.c;h=a9a77216310e028c2dfe1d125d2706c21c51630d;hb=ee5c2ab09b79d3aba3515a3eae7c5cf1e2cbc569;hp=2bd9c5f7627dd84b450ec3f105263979adda77e3;hpb=4f02f8220562591322c118d07a32bebf705318b7;p=karo-tx-linux.git diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 2bd9c5f7627d..a9a77216310e 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -82,6 +82,11 @@ int rtnl_trylock(void) return mutex_trylock(&rtnl_mutex); } +int rtnl_is_locked(void) +{ + return mutex_is_locked(&rtnl_mutex); +} + static struct rtnl_link *rtnl_msg_handlers[NPROTO]; static inline int rtm_msgindex(int msgtype) @@ -269,6 +274,26 @@ int rtnl_link_register(struct rtnl_link_ops *ops) EXPORT_SYMBOL_GPL(rtnl_link_register); +static void __rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops) +{ + struct net_device *dev; +restart: + for_each_netdev(net, dev) { + if (dev->rtnl_link_ops == ops) { + ops->dellink(dev); + goto restart; + } + } +} + +void rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops) +{ + rtnl_lock(); + __rtnl_kill_links(net, ops); + rtnl_unlock(); +} +EXPORT_SYMBOL_GPL(rtnl_kill_links); + /** * __rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink. * @ops: struct rtnl_link_ops * to unregister @@ -277,17 +302,10 @@ EXPORT_SYMBOL_GPL(rtnl_link_register); */ void __rtnl_link_unregister(struct rtnl_link_ops *ops) { - struct net_device *dev, *n; struct net *net; for_each_net(net) { -restart: - for_each_netdev_safe(net, dev, n) { - if (dev->rtnl_link_ops == ops) { - ops->dellink(dev); - goto restart; - } - } + __rtnl_kill_links(net, ops); } list_del(&ops->list); } @@ -480,7 +498,8 @@ int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics) return nla_nest_end(skb, mx); nla_put_failure: - return nla_nest_cancel(skb, mx); + nla_nest_cancel(skb, mx); + return -EMSGSIZE; } int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst, u32 id, @@ -662,7 +681,7 @@ nla_put_failure: static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); int idx; int s_idx = cb->args[0]; struct net_device *dev; @@ -879,7 +898,7 @@ errout: static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct ifinfomsg *ifm; struct net_device *dev; int err; @@ -921,7 +940,7 @@ errout: static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); const struct rtnl_link_ops *ops; struct net_device *dev; struct ifinfomsg *ifm; @@ -972,7 +991,7 @@ struct net_device *rtnl_create_link(struct net *net, char *ifname, goto err_free; } - dev->nd_net = net; + dev_net_set(dev, net); dev->rtnl_link_ops = ops; if (tb[IFLA_MTU]) @@ -1000,7 +1019,7 @@ err: static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); const struct rtnl_link_ops *ops; struct net_device *dev; struct ifinfomsg *ifm; @@ -1132,7 +1151,7 @@ replay: static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); struct ifinfomsg *ifm; struct nlattr *tb[IFLA_MAX+1]; struct net_device *dev = NULL; @@ -1198,7 +1217,7 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) { - struct net *net = dev->nd_net; + struct net *net = dev_net(dev); struct sk_buff *skb; int err = -ENOBUFS; @@ -1227,7 +1246,7 @@ static int rtattr_max; static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { - struct net *net = skb->sk->sk_net; + struct net *net = sock_net(skb->sk); rtnl_doit_func doit; int sz_idx, kind; int min_len; @@ -1389,6 +1408,7 @@ EXPORT_SYMBOL(rtnetlink_put_metrics); EXPORT_SYMBOL(rtnl_lock); EXPORT_SYMBOL(rtnl_trylock); EXPORT_SYMBOL(rtnl_unlock); +EXPORT_SYMBOL(rtnl_is_locked); EXPORT_SYMBOL(rtnl_unicast); EXPORT_SYMBOL(rtnl_notify); EXPORT_SYMBOL(rtnl_set_sk_err);