ALSA: hda - Add support for Thinkpad Edge conexant chip
[safe/jmp/linux-2.6] / net / decnet / dn_fib.c
index 3cbfddc..4ab96c1 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/string.h>
 #include <linux/net.h>
 #include <linux/socket.h>
+#include <linux/slab.h>
 #include <linux/sockios.h>
 #include <linux/init.h>
 #include <linux/skbuff.h>
@@ -63,7 +64,7 @@ static struct
 {
        int error;
        u8 scope;
-} dn_fib_props[RTA_MAX+1] = {
+} dn_fib_props[RTN_MAX+1] = {
        [RTN_UNSPEC] =      { .error = 0,       .scope = RT_SCOPE_NOWHERE },
        [RTN_UNICAST] =     { .error = 0,       .scope = RT_SCOPE_UNIVERSE },
        [RTN_LOCAL] =       { .error = 0,       .scope = RT_SCOPE_HOST },
@@ -203,8 +204,6 @@ static int dn_fib_check_nh(const struct rtmsg *r, struct dn_fib_info *fi, struct
                struct flowi fl;
                struct dn_fib_res res;
 
-               memset(&fl, 0, sizeof(fl));
-
                if (nh->nh_flags&RTNH_F_ONLINK) {
                        struct net_device *dev;
 
@@ -212,7 +211,7 @@ static int dn_fib_check_nh(const struct rtmsg *r, struct dn_fib_info *fi, struct
                                return -EINVAL;
                        if (dnet_addr_type(nh->nh_gw) != RTN_UNICAST)
                                return -EINVAL;
-                       if ((dev = __dev_get_by_index(nh->nh_oif)) == NULL)
+                       if ((dev = __dev_get_by_index(&init_net, nh->nh_oif)) == NULL)
                                return -ENODEV;
                        if (!(dev->flags&IFF_UP))
                                return -ENETDOWN;
@@ -255,7 +254,7 @@ out:
                if (nh->nh_flags&(RTNH_F_PERVASIVE|RTNH_F_ONLINK))
                        return -EINVAL;
 
-               dev = __dev_get_by_index(nh->nh_oif);
+               dev = __dev_get_by_index(&init_net, nh->nh_oif);
                if (dev == NULL || dev->dn_ptr == NULL)
                        return -ENODEV;
                if (!(dev->flags&IFF_UP))
@@ -276,6 +275,9 @@ struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r, struct dn_kern_rta
        struct dn_fib_info *ofi;
        int nhs = 1;
 
+       if (r->rtm_type > RTN_MAX)
+               goto err_inval;
+
        if (dn_fib_props[r->rtm_type].scope > r->rtm_scope)
                goto err_inval;
 
@@ -352,7 +354,7 @@ struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r, struct dn_kern_rta
                if (nhs != 1 || nh->nh_gw)
                        goto err_inval;
                nh->nh_scope = RT_SCOPE_NOWHERE;
-               nh->nh_dev = dev_get_by_index(fi->fib_nh->nh_oif);
+               nh->nh_dev = dev_get_by_index(&init_net, fi->fib_nh->nh_oif);
                err = -ENODEV;
                if (nh->nh_dev == NULL)
                        goto failure;
@@ -501,12 +503,16 @@ static int dn_fib_check_attr(struct rtmsg *r, struct rtattr **rta)
        return 0;
 }
 
-int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
+       struct net *net = sock_net(skb->sk);
        struct dn_fib_table *tb;
        struct rtattr **rta = arg;
        struct rtmsg *r = NLMSG_DATA(nlh);
 
+       if (!net_eq(net, &init_net))
+               return -EINVAL;
+
        if (dn_fib_check_attr(r, rta))
                return -EINVAL;
 
@@ -517,12 +523,16 @@ int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
        return -ESRCH;
 }
 
-int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+static int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
+       struct net *net = sock_net(skb->sk);
        struct dn_fib_table *tb;
        struct rtattr **rta = arg;
        struct rtmsg *r = NLMSG_DATA(nlh);
 
+       if (!net_eq(net, &init_net))
+               return -EINVAL;
+
        if (dn_fib_check_attr(r, rta))
                return -EINVAL;
 
@@ -598,8 +608,8 @@ static void dn_fib_del_ifaddr(struct dn_ifaddr *ifa)
        ASSERT_RTNL();
 
        /* Scan device list */
-       read_lock(&dev_base_lock);
-       for(dev = dev_base; dev; dev = dev->next) {
+       rcu_read_lock();
+       for_each_netdev_rcu(&init_net, dev) {
                dn_db = dev->dn_ptr;
                if (dn_db == NULL)
                        continue;
@@ -610,7 +620,7 @@ static void dn_fib_del_ifaddr(struct dn_ifaddr *ifa)
                        }
                }
        }
-       read_unlock(&dev_base_lock);
+       rcu_read_unlock();
 
        if (found_it == 0) {
                fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 16, ifa);
@@ -745,11 +755,13 @@ void __exit dn_fib_cleanup(void)
 
 void __init dn_fib_init(void)
 {
-
        dn_fib_table_init();
        dn_fib_rules_init();
 
        register_dnaddr_notifier(&dn_fib_dnaddr_notifier);
+
+       rtnl_register(PF_DECnet, RTM_NEWROUTE, dn_fib_rtm_newroute, NULL);
+       rtnl_register(PF_DECnet, RTM_DELROUTE, dn_fib_rtm_delroute, NULL);
 }