aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/rtnetlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r--net/core/rtnetlink.c14
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;