[MTD] Always initialise mutex in new mtd_blktrans_dev.
[safe/jmp/linux-2.6] / net / ipv6 / route.c
index f4f0c34..95f8e4a 100644 (file)
@@ -138,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, },
@@ -164,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, },
@@ -184,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, },
@@ -224,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);
@@ -666,7 +663,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *d
        return rt;
 }
 
-static struct rt6_info *ip6_pol_route_input(struct fib6_table *table,
+static struct rt6_info *ip6_pol_route(struct fib6_table *table, int oif,
                                            struct flowi *fl, int flags)
 {
        struct fib6_node *fn;
@@ -685,7 +682,7 @@ restart_2:
        fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
 
 restart:
-       rt = rt6_select(fn, fl->iif, strict | reachable);
+       rt = rt6_select(fn, oif, strict | reachable);
        BACKTRACK(&fl->fl6_src);
        if (rt == &ip6_null_entry ||
            rt->rt6i_flags & RTF_CACHE)
@@ -738,6 +735,12 @@ out2:
        return rt;
 }
 
+static struct rt6_info *ip6_pol_route_input(struct fib6_table *table,
+                                           struct flowi *fl, int flags)
+{
+       return ip6_pol_route(table, fl->iif, fl, flags);
+}
+
 void ip6_route_input(struct sk_buff *skb)
 {
        struct ipv6hdr *iph = ipv6_hdr(skb);
@@ -764,72 +767,7 @@ void ip6_route_input(struct sk_buff *skb)
 static struct rt6_info *ip6_pol_route_output(struct fib6_table *table,
                                             struct flowi *fl, int flags)
 {
-       struct fib6_node *fn;
-       struct rt6_info *rt, *nrt;
-       int strict = 0;
-       int attempts = 3;
-       int err;
-       int reachable = ipv6_devconf.forwarding ? 0 : RT6_LOOKUP_F_REACHABLE;
-
-       strict |= flags & RT6_LOOKUP_F_IFACE;
-
-relookup:
-       read_lock_bh(&table->tb6_lock);
-
-restart_2:
-       fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
-
-restart:
-       rt = rt6_select(fn, fl->oif, strict | reachable);
-       BACKTRACK(&fl->fl6_src);
-       if (rt == &ip6_null_entry ||
-           rt->rt6i_flags & RTF_CACHE)
-               goto out;
-
-       dst_hold(&rt->u.dst);
-       read_unlock_bh(&table->tb6_lock);
-
-       if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP))
-               nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src);
-       else {
-#if CLONE_OFFLINK_ROUTE
-               nrt = rt6_alloc_clone(rt, &fl->fl6_dst);
-#else
-               goto out2;
-#endif
-       }
-
-       dst_release(&rt->u.dst);
-       rt = nrt ? : &ip6_null_entry;
-
-       dst_hold(&rt->u.dst);
-       if (nrt) {
-               err = ip6_ins_rt(nrt);
-               if (!err)
-                       goto out2;
-       }
-
-       if (--attempts <= 0)
-               goto out2;
-
-       /*
-        * Race condition! In the gap, when table->tb6_lock was
-        * released someone could insert this route.  Relookup.
-        */
-       dst_release(&rt->u.dst);
-       goto relookup;
-
-out:
-       if (reachable) {
-               reachable = 0;
-               goto restart_2;
-       }
-       dst_hold(&rt->u.dst);
-       read_unlock_bh(&table->tb6_lock);
-out2:
-       rt->u.dst.lastuse = jiffies;
-       rt->u.dst.__use++;
-       return rt;
+       return ip6_pol_route(table, fl->oif, fl, flags);
 }
 
 struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl)
@@ -1130,7 +1068,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);
@@ -1188,12 +1126,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) {
@@ -1279,7 +1217,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) {
@@ -1897,13 +1835,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));
@@ -2265,7 +2203,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;
@@ -2459,7 +2397,6 @@ int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp,
 
 ctl_table ipv6_route_table[] = {
        {
-               .ctl_name       =       NET_IPV6_ROUTE_FLUSH,
                .procname       =       "flush",
                .data           =       &flush_delay,
                .maxlen         =       sizeof(int),