[NET]: Make rtnetlink infrastructure network namespace aware (v3)
[cascardo/linux.git] / net / ipv4 / devinet.c
index 721b89b..6e75c88 100644 (file)
@@ -203,8 +203,6 @@ static void inetdev_destroy(struct in_device *in_dev)
        ASSERT_RTNL();
 
        dev = in_dev->dev;
-       if (dev == &loopback_dev)
-               return;
 
        in_dev->dead = 1;
 
@@ -443,6 +441,7 @@ struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
 
 static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct nlattr *tb[IFA_MAX+1];
        struct in_device *in_dev;
        struct ifaddrmsg *ifm;
@@ -451,6 +450,9 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg
 
        ASSERT_RTNL();
 
+       if (net != &init_net)
+               return -EINVAL;
+
        err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy);
        if (err < 0)
                goto errout;
@@ -518,8 +520,6 @@ static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh)
                goto errout;
        }
 
-       ipv4_devconf_setall(in_dev);
-
        ifa = inet_alloc_ifa();
        if (ifa == NULL) {
                /*
@@ -530,6 +530,7 @@ static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh)
                goto errout;
        }
 
+       ipv4_devconf_setall(in_dev);
        in_dev_hold(in_dev);
 
        if (tb[IFA_ADDRESS] == NULL)
@@ -563,10 +564,14 @@ errout:
 
 static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct in_ifaddr *ifa;
 
        ASSERT_RTNL();
 
+       if (net != &init_net)
+               return -EINVAL;
+
        ifa = rtm_to_ifaddr(nlh);
        if (IS_ERR(ifa))
                return PTR_ERR(ifa);
@@ -1030,7 +1035,7 @@ static void inetdev_changename(struct net_device *dev, struct in_device *in_dev)
                memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
                if (named++ == 0)
                        continue;
-               dot = strchr(ifa->ifa_label, ':');
+               dot = strchr(old, ':');
                if (dot == NULL) {
                        sprintf(old, ":%d", named);
                        dot = old;
@@ -1061,7 +1066,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
                        in_dev = inetdev_init(dev);
                        if (!in_dev)
                                return notifier_from_errno(-ENOMEM);
-                       if (dev == &loopback_dev) {
+                       if (dev->flags & IFF_LOOPBACK) {
                                IN_DEV_CONF_SET(in_dev, NOXFRM, 1);
                                IN_DEV_CONF_SET(in_dev, NOPOLICY, 1);
                        }
@@ -1077,7 +1082,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
        case NETDEV_UP:
                if (dev->mtu < 68)
                        break;
-               if (dev == &loopback_dev) {
+               if (dev->flags & IFF_LOOPBACK) {
                        struct in_ifaddr *ifa;
                        if ((ifa = inet_alloc_ifa()) != NULL) {
                                ifa->ifa_local =
@@ -1177,12 +1182,16 @@ nla_put_failure:
 
 static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        int idx, ip_idx;
        struct net_device *dev;
        struct in_device *in_dev;
        struct in_ifaddr *ifa;
        int s_ip_idx, s_idx = cb->args[0];
 
+       if (net != &init_net)
+               return 0;
+
        s_ip_idx = ip_idx = cb->args[1];
        idx = 0;
        for_each_netdev(&init_net, dev) {
@@ -1231,10 +1240,10 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa, struct nlmsghdr *nlh,
                kfree_skb(skb);
                goto errout;
        }
-       err = rtnl_notify(skb, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
+       err = rtnl_notify(skb, &init_net, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
 errout:
        if (err < 0)
-               rtnl_set_sk_err(RTNLGRP_IPV4_IFADDR, err);
+               rtnl_set_sk_err(&init_net, RTNLGRP_IPV4_IFADDR, err);
 }
 
 #ifdef CONFIG_SYSCTL