[NET]: Make the loopback device per network namespace.
[cascardo/linux.git] / net / ipv6 / route.c
index 919de68..6ff19f9 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/seq_file.h>
 #endif
 
+#include <net/net_namespace.h>
 #include <net/snmp.h>
 #include <net/ipv6.h>
 #include <net/ip6_fib.h>
@@ -137,7 +138,6 @@ struct rt6_info ip6_null_entry = {
                .dst = {
                        .__refcnt       = ATOMIC_INIT(1),
                        .__use          = 1,
-                       .dev            = &loopback_dev,
                        .obsolete       = -1,
                        .error          = -ENETUNREACH,
                        .metrics        = { [RTAX_HOPLIMIT - 1] = 255, },
@@ -163,7 +163,6 @@ struct rt6_info ip6_prohibit_entry = {
                .dst = {
                        .__refcnt       = ATOMIC_INIT(1),
                        .__use          = 1,
-                       .dev            = &loopback_dev,
                        .obsolete       = -1,
                        .error          = -EACCES,
                        .metrics        = { [RTAX_HOPLIMIT - 1] = 255, },
@@ -183,7 +182,6 @@ struct rt6_info ip6_blk_hole_entry = {
                .dst = {
                        .__refcnt       = ATOMIC_INIT(1),
                        .__use          = 1,
-                       .dev            = &loopback_dev,
                        .obsolete       = -1,
                        .error          = -EINVAL,
                        .metrics        = { [RTAX_HOPLIMIT - 1] = 255, },
@@ -223,8 +221,8 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
        struct rt6_info *rt = (struct rt6_info *)dst;
        struct inet6_dev *idev = rt->rt6i_idev;
 
-       if (dev != &loopback_dev && idev != NULL && idev->dev == dev) {
-               struct inet6_dev *loopback_idev = in6_dev_get(&loopback_dev);
+       if (dev != init_net.loopback_dev && idev != NULL && idev->dev == dev) {
+               struct inet6_dev *loopback_idev = in6_dev_get(init_net.loopback_dev);
                if (loopback_idev != NULL) {
                        rt->rt6i_idev = loopback_idev;
                        in6_dev_put(idev);
@@ -1129,7 +1127,7 @@ int ip6_route_add(struct fib6_config *cfg)
 #endif
        if (cfg->fc_ifindex) {
                err = -ENODEV;
-               dev = dev_get_by_index(cfg->fc_ifindex);
+               dev = dev_get_by_index(&init_net, cfg->fc_ifindex);
                if (!dev)
                        goto out;
                idev = in6_dev_get(dev);
@@ -1187,12 +1185,12 @@ int ip6_route_add(struct fib6_config *cfg)
        if ((cfg->fc_flags & RTF_REJECT) ||
            (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) {
                /* hold loopback dev/idev if we haven't done so. */
-               if (dev != &loopback_dev) {
+               if (dev != init_net.loopback_dev) {
                        if (dev) {
                                dev_put(dev);
                                in6_dev_put(idev);
                        }
-                       dev = &loopback_dev;
+                       dev = init_net.loopback_dev;
                        dev_hold(dev);
                        idev = in6_dev_get(dev);
                        if (!idev) {
@@ -1278,7 +1276,7 @@ install_route:
                int remaining;
 
                nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) {
-                       int type = nla->nla_type;
+                       int type = nla_type(nla);
 
                        if (type) {
                                if (type > RTAX_MAX) {
@@ -1896,13 +1894,13 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
        if (rt == NULL)
                return ERR_PTR(-ENOMEM);
 
-       dev_hold(&loopback_dev);
+       dev_hold(init_net.loopback_dev);
        in6_dev_hold(idev);
 
        rt->u.dst.flags = DST_HOST;
        rt->u.dst.input = ip6_input;
        rt->u.dst.output = ip6_output;
-       rt->rt6i_dev = &loopback_dev;
+       rt->rt6i_dev = init_net.loopback_dev;
        rt->rt6i_idev = idev;
        rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev);
        rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst));
@@ -1983,9 +1981,10 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
            !dst_metric_locked(&rt->u.dst, RTAX_MTU) &&
            (dst_mtu(&rt->u.dst) > arg->mtu ||
             (dst_mtu(&rt->u.dst) < arg->mtu &&
-             dst_mtu(&rt->u.dst) == idev->cnf.mtu6)))
+             dst_mtu(&rt->u.dst) == idev->cnf.mtu6))) {
                rt->u.dst.metrics[RTAX_MTU-1] = arg->mtu;
-       rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(arg->mtu);
+               rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(arg->mtu);
+       }
        return 0;
 }
 
@@ -2263,7 +2262,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
 
        if (iif) {
                struct net_device *dev;
-               dev = __dev_get_by_index(iif);
+               dev = __dev_get_by_index(&init_net, iif);
                if (!dev) {
                        err = -ENODEV;
                        goto errout;
@@ -2560,11 +2559,11 @@ void __init ip6_route_init(void)
 
        fib6_init();
 #ifdef         CONFIG_PROC_FS
-       p = proc_net_create("ipv6_route", 0, rt6_proc_info);
+       p = proc_net_create(&init_net, "ipv6_route", 0, rt6_proc_info);
        if (p)
                p->owner = THIS_MODULE;
 
-       proc_net_fops_create("rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
+       proc_net_fops_create(&init_net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
 #endif
 #ifdef CONFIG_XFRM
        xfrm6_init();
@@ -2584,8 +2583,8 @@ void ip6_route_cleanup(void)
        fib6_rules_cleanup();
 #endif
 #ifdef CONFIG_PROC_FS
-       proc_net_remove("ipv6_route");
-       proc_net_remove("rt6_stats");
+       proc_net_remove(&init_net, "ipv6_route");
+       proc_net_remove(&init_net, "rt6_stats");
 #endif
 #ifdef CONFIG_XFRM
        xfrm6_fini();