diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-07-27 03:54:47 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-07-27 03:54:47 -0400 |
| commit | aa7eb8e78d8ecd6cd0475d86ea8385ff9cb47ece (patch) | |
| tree | 3f9e98fadd5124fb05e8f6f9b06aa23698d4f215 /net/core/rtnetlink.c | |
| parent | cca8edfd2ec2a34d9f50f593bc753bb11e1bc1f5 (diff) | |
| parent | 3c6b50141ef9f0a8844bf1357b80c0cdf518bf05 (diff) | |
Merge branch 'next' into for-linus
Diffstat (limited to 'net/core/rtnetlink.c')
| -rw-r--r-- | net/core/rtnetlink.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index d7c4bb4b1820..abd936d8a716 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -850,6 +850,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
| 850 | struct nlattr *attr, *af_spec; | 850 | struct nlattr *attr, *af_spec; |
| 851 | struct rtnl_af_ops *af_ops; | 851 | struct rtnl_af_ops *af_ops; |
| 852 | 852 | ||
| 853 | ASSERT_RTNL(); | ||
| 853 | nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags); | 854 | nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags); |
| 854 | if (nlh == NULL) | 855 | if (nlh == NULL) |
| 855 | return -EMSGSIZE; | 856 | return -EMSGSIZE; |
| @@ -1007,10 +1008,11 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1007 | s_h = cb->args[0]; | 1008 | s_h = cb->args[0]; |
| 1008 | s_idx = cb->args[1]; | 1009 | s_idx = cb->args[1]; |
| 1009 | 1010 | ||
| 1011 | rcu_read_lock(); | ||
| 1010 | for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { | 1012 | for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { |
| 1011 | idx = 0; | 1013 | idx = 0; |
| 1012 | head = &net->dev_index_head[h]; | 1014 | head = &net->dev_index_head[h]; |
| 1013 | hlist_for_each_entry(dev, node, head, index_hlist) { | 1015 | hlist_for_each_entry_rcu(dev, node, head, index_hlist) { |
| 1014 | if (idx < s_idx) | 1016 | if (idx < s_idx) |
| 1015 | goto cont; | 1017 | goto cont; |
| 1016 | if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, | 1018 | if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, |
| @@ -1023,6 +1025,7 @@ cont: | |||
| 1023 | } | 1025 | } |
| 1024 | } | 1026 | } |
| 1025 | out: | 1027 | out: |
| 1028 | rcu_read_unlock(); | ||
| 1026 | cb->args[1] = idx; | 1029 | cb->args[1] = idx; |
| 1027 | cb->args[0] = h; | 1030 | cb->args[0] = h; |
| 1028 | 1031 | ||
| @@ -1043,6 +1046,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = { | |||
| 1043 | [IFLA_LINKMODE] = { .type = NLA_U8 }, | 1046 | [IFLA_LINKMODE] = { .type = NLA_U8 }, |
| 1044 | [IFLA_LINKINFO] = { .type = NLA_NESTED }, | 1047 | [IFLA_LINKINFO] = { .type = NLA_NESTED }, |
| 1045 | [IFLA_NET_NS_PID] = { .type = NLA_U32 }, | 1048 | [IFLA_NET_NS_PID] = { .type = NLA_U32 }, |
| 1049 | [IFLA_NET_NS_FD] = { .type = NLA_U32 }, | ||
| 1046 | [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 }, | 1050 | [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 }, |
| 1047 | [IFLA_VFINFO_LIST] = {. type = NLA_NESTED }, | 1051 | [IFLA_VFINFO_LIST] = {. type = NLA_NESTED }, |
| 1048 | [IFLA_VF_PORTS] = { .type = NLA_NESTED }, | 1052 | [IFLA_VF_PORTS] = { .type = NLA_NESTED }, |
| @@ -1091,6 +1095,8 @@ struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]) | |||
| 1091 | */ | 1095 | */ |
| 1092 | if (tb[IFLA_NET_NS_PID]) | 1096 | if (tb[IFLA_NET_NS_PID]) |
| 1093 | net = get_net_ns_by_pid(nla_get_u32(tb[IFLA_NET_NS_PID])); | 1097 | net = get_net_ns_by_pid(nla_get_u32(tb[IFLA_NET_NS_PID])); |
| 1098 | else if (tb[IFLA_NET_NS_FD]) | ||
| 1099 | net = get_net_ns_by_fd(nla_get_u32(tb[IFLA_NET_NS_FD])); | ||
| 1094 | else | 1100 | else |
| 1095 | net = get_net(src_net); | 1101 | net = get_net(src_net); |
| 1096 | return net; | 1102 | return net; |
| @@ -1221,7 +1227,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | |||
| 1221 | int send_addr_notify = 0; | 1227 | int send_addr_notify = 0; |
| 1222 | int err; | 1228 | int err; |
| 1223 | 1229 | ||
| 1224 | if (tb[IFLA_NET_NS_PID]) { | 1230 | if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD]) { |
| 1225 | struct net *net = rtnl_link_get_net(dev_net(dev), tb); | 1231 | struct net *net = rtnl_link_get_net(dev_net(dev), tb); |
| 1226 | if (IS_ERR(net)) { | 1232 | if (IS_ERR(net)) { |
| 1227 | err = PTR_ERR(net); | 1233 | err = PTR_ERR(net); |
| @@ -1499,6 +1505,7 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
| 1499 | char ifname[IFNAMSIZ]; | 1505 | char ifname[IFNAMSIZ]; |
| 1500 | struct nlattr *tb[IFLA_MAX+1]; | 1506 | struct nlattr *tb[IFLA_MAX+1]; |
| 1501 | int err; | 1507 | int err; |
| 1508 | LIST_HEAD(list_kill); | ||
| 1502 | 1509 | ||
| 1503 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); | 1510 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); |
| 1504 | if (err < 0) | 1511 | if (err < 0) |
| @@ -1522,7 +1529,9 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
| 1522 | if (!ops) | 1529 | if (!ops) |
| 1523 | return -EOPNOTSUPP; | 1530 | return -EOPNOTSUPP; |
| 1524 | 1531 | ||
| 1525 | ops->dellink(dev, NULL); | 1532 | ops->dellink(dev, &list_kill); |
| 1533 | unregister_netdevice_many(&list_kill); | ||
| 1534 | list_del(&list_kill); | ||
| 1526 | return 0; | 1535 | return 0; |
| 1527 | } | 1536 | } |
| 1528 | 1537 | ||
| @@ -1570,12 +1579,6 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net, | |||
| 1570 | dev->rtnl_link_state = RTNL_LINK_INITIALIZING; | 1579 | dev->rtnl_link_state = RTNL_LINK_INITIALIZING; |
| 1571 | dev->real_num_tx_queues = real_num_queues; | 1580 | dev->real_num_tx_queues = real_num_queues; |
| 1572 | 1581 | ||
| 1573 | if (strchr(dev->name, '%')) { | ||
| 1574 | err = dev_alloc_name(dev, dev->name); | ||
| 1575 | if (err < 0) | ||
| 1576 | goto err_free; | ||
| 1577 | } | ||
| 1578 | |||
| 1579 | if (tb[IFLA_MTU]) | 1582 | if (tb[IFLA_MTU]) |
| 1580 | dev->mtu = nla_get_u32(tb[IFLA_MTU]); | 1583 | dev->mtu = nla_get_u32(tb[IFLA_MTU]); |
| 1581 | if (tb[IFLA_ADDRESS]) | 1584 | if (tb[IFLA_ADDRESS]) |
| @@ -1595,8 +1598,6 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net, | |||
| 1595 | 1598 | ||
| 1596 | return dev; | 1599 | return dev; |
| 1597 | 1600 | ||
| 1598 | err_free: | ||
| 1599 | free_netdev(dev); | ||
| 1600 | err: | 1601 | err: |
| 1601 | return ERR_PTR(err); | 1602 | return ERR_PTR(err); |
| 1602 | } | 1603 | } |
| @@ -1963,6 +1964,8 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi | |||
| 1963 | case NETDEV_GOING_DOWN: | 1964 | case NETDEV_GOING_DOWN: |
| 1964 | case NETDEV_UNREGISTER: | 1965 | case NETDEV_UNREGISTER: |
| 1965 | case NETDEV_UNREGISTER_BATCH: | 1966 | case NETDEV_UNREGISTER_BATCH: |
| 1967 | case NETDEV_RELEASE: | ||
| 1968 | case NETDEV_JOIN: | ||
| 1966 | break; | 1969 | break; |
| 1967 | default: | 1970 | default: |
| 1968 | rtmsg_ifinfo(RTM_NEWLINK, dev, 0); | 1971 | rtmsg_ifinfo(RTM_NEWLINK, dev, 0); |
