diff options
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r-- | net/core/rtnetlink.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index d1644e317e7..abd936d8a71 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; |
@@ -1045,6 +1046,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = { | |||
1045 | [IFLA_LINKMODE] = { .type = NLA_U8 }, | 1046 | [IFLA_LINKMODE] = { .type = NLA_U8 }, |
1046 | [IFLA_LINKINFO] = { .type = NLA_NESTED }, | 1047 | [IFLA_LINKINFO] = { .type = NLA_NESTED }, |
1047 | [IFLA_NET_NS_PID] = { .type = NLA_U32 }, | 1048 | [IFLA_NET_NS_PID] = { .type = NLA_U32 }, |
1049 | [IFLA_NET_NS_FD] = { .type = NLA_U32 }, | ||
1048 | [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 }, | 1050 | [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 }, |
1049 | [IFLA_VFINFO_LIST] = {. type = NLA_NESTED }, | 1051 | [IFLA_VFINFO_LIST] = {. type = NLA_NESTED }, |
1050 | [IFLA_VF_PORTS] = { .type = NLA_NESTED }, | 1052 | [IFLA_VF_PORTS] = { .type = NLA_NESTED }, |
@@ -1093,6 +1095,8 @@ struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]) | |||
1093 | */ | 1095 | */ |
1094 | if (tb[IFLA_NET_NS_PID]) | 1096 | if (tb[IFLA_NET_NS_PID]) |
1095 | 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])); | ||
1096 | else | 1100 | else |
1097 | net = get_net(src_net); | 1101 | net = get_net(src_net); |
1098 | return net; | 1102 | return net; |
@@ -1223,7 +1227,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | |||
1223 | int send_addr_notify = 0; | 1227 | int send_addr_notify = 0; |
1224 | int err; | 1228 | int err; |
1225 | 1229 | ||
1226 | if (tb[IFLA_NET_NS_PID]) { | 1230 | if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD]) { |
1227 | struct net *net = rtnl_link_get_net(dev_net(dev), tb); | 1231 | struct net *net = rtnl_link_get_net(dev_net(dev), tb); |
1228 | if (IS_ERR(net)) { | 1232 | if (IS_ERR(net)) { |
1229 | err = PTR_ERR(net); | 1233 | err = PTR_ERR(net); |
@@ -1876,6 +1880,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1876 | int min_len; | 1880 | int min_len; |
1877 | int family; | 1881 | int family; |
1878 | int type; | 1882 | int type; |
1883 | int err; | ||
1879 | 1884 | ||
1880 | type = nlh->nlmsg_type; | 1885 | type = nlh->nlmsg_type; |
1881 | if (type > RTM_MAX) | 1886 | if (type > RTM_MAX) |
@@ -1902,8 +1907,11 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1902 | if (dumpit == NULL) | 1907 | if (dumpit == NULL) |
1903 | return -EOPNOTSUPP; | 1908 | return -EOPNOTSUPP; |
1904 | 1909 | ||
1910 | __rtnl_unlock(); | ||
1905 | rtnl = net->rtnl; | 1911 | rtnl = net->rtnl; |
1906 | return netlink_dump_start(rtnl, skb, nlh, dumpit, NULL); | 1912 | err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL); |
1913 | rtnl_lock(); | ||
1914 | return err; | ||
1907 | } | 1915 | } |
1908 | 1916 | ||
1909 | memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *))); | 1917 | memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *))); |
@@ -1975,7 +1983,7 @@ static int __net_init rtnetlink_net_init(struct net *net) | |||
1975 | { | 1983 | { |
1976 | struct sock *sk; | 1984 | struct sock *sk; |
1977 | sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX, | 1985 | sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX, |
1978 | rtnetlink_rcv, NULL, THIS_MODULE); | 1986 | rtnetlink_rcv, &rtnl_mutex, THIS_MODULE); |
1979 | if (!sk) | 1987 | if (!sk) |
1980 | return -ENOMEM; | 1988 | return -ENOMEM; |
1981 | net->rtnl = sk; | 1989 | net->rtnl = sk; |