[NET]: Revert sk_buff walker cleanups.
[safe/jmp/linux-2.6] / net / core / rtnetlink.c
index 3044702..cec1111 100644 (file)
 #include <net/pkt_sched.h>
 #include <net/fib_rules.h>
 #include <net/rtnetlink.h>
-#ifdef CONFIG_NET_WIRELESS_RTNETLINK
-#include <linux/wireless.h>
-#include <net/iw_handler.h>
-#endif /* CONFIG_NET_WIRELESS_RTNETLINK */
 
 struct rtnl_link
 {
@@ -101,7 +97,7 @@ int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len)
        return 0;
 }
 
-struct rtnl_link *rtnl_msg_handlers[NPROTO];
+static struct rtnl_link *rtnl_msg_handlers[NPROTO];
 
 static inline int rtm_msgindex(int msgtype)
 {
@@ -122,10 +118,10 @@ static rtnl_doit_func rtnl_get_doit(int protocol, int msgindex)
        struct rtnl_link *tab;
 
        tab = rtnl_msg_handlers[protocol];
-       if (tab == NULL || tab->doit == NULL)
+       if (tab == NULL || tab[msgindex].doit == NULL)
                tab = rtnl_msg_handlers[PF_UNSPEC];
 
-       return tab ? tab->doit : NULL;
+       return tab ? tab[msgindex].doit : NULL;
 }
 
 static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex)
@@ -133,10 +129,10 @@ static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex)
        struct rtnl_link *tab;
 
        tab = rtnl_msg_handlers[protocol];
-       if (tab == NULL || tab->dumpit == NULL)
+       if (tab == NULL || tab[msgindex].dumpit == NULL)
                tab = rtnl_msg_handlers[PF_UNSPEC];
 
-       return tab ? tab->dumpit : NULL;
+       return tab ? tab[msgindex].dumpit : NULL;
 }
 
 /**
@@ -399,7 +395,7 @@ static void set_operstate(struct net_device *dev, unsigned char transition)
                    operstate == IF_OPER_UNKNOWN)
                        operstate = IF_OPER_DORMANT;
                break;
-       };
+       }
 
        if (dev->operstate != operstate) {
                write_lock_bh(&dev_base_lock);
@@ -543,7 +539,6 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
        int s_idx = cb->args[0];
        struct net_device *dev;
 
-       read_lock(&dev_base_lock);
        for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
                if (idx < s_idx)
                        continue;
@@ -552,7 +547,6 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
                                     cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0)
                        break;
        }
-       read_unlock(&dev_base_lock);
        cb->args[0] = idx;
 
        return skb->len;
@@ -686,17 +680,6 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
                modified = 1;
        }
 
-#ifdef CONFIG_NET_WIRELESS_RTNETLINK
-       if (tb[IFLA_WIRELESS]) {
-               /* Call Wireless Extensions.
-                * Various stuff checked in there... */
-               err = wireless_rtnetlink_set(dev, nla_data(tb[IFLA_WIRELESS]),
-                                            nla_len(tb[IFLA_WIRELESS]));
-               if (err < 0)
-                       goto errout_dev;
-       }
-#endif /* CONFIG_NET_WIRELESS_RTNETLINK */
-
        if (tb[IFLA_BROADCAST]) {
                nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len);
                send_addr_notify = 1;
@@ -760,22 +743,6 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
        } else
                return -EINVAL;
 
-
-#ifdef CONFIG_NET_WIRELESS_RTNETLINK
-       if (tb[IFLA_WIRELESS]) {
-               /* Call Wireless Extensions. We need to know the size before
-                * we can alloc. Various stuff checked in there... */
-               err = wireless_rtnetlink_get(dev, nla_data(tb[IFLA_WIRELESS]),
-                                            nla_len(tb[IFLA_WIRELESS]),
-                                            &iw_buf, &iw_buf_len);
-               if (err < 0)
-                       goto errout;
-
-               /* Payload is at an offset in buffer */
-               iw = iw_buf + IW_EV_POINT_OFF;
-       }
-#endif /* CONFIG_NET_WIRELESS_RTNETLINK */
-
        nskb = nlmsg_new(if_nlmsg_size(iw_buf_len), GFP_KERNEL);
        if (nskb == NULL) {
                err = -ENOBUFS;
@@ -798,7 +765,7 @@ errout:
        return err;
 }
 
-int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
+static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
 {
        int idx;
        int s_idx = cb->family;
@@ -822,8 +789,6 @@ int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
        return skb->len;
 }
 
-EXPORT_SYMBOL_GPL(rtnl_dump_all);
-
 void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
 {
        struct sk_buff *skb;
@@ -852,8 +817,7 @@ static int rtattr_max;
 
 /* Process one rtnetlink message. */
 
-static __inline__ int
-rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
+static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
        rtnl_doit_func doit;
        int sz_idx, kind;
@@ -862,19 +826,9 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
        int type;
        int err;
 
-       /* Only requests are handled by kernel now */
-       if (!(nlh->nlmsg_flags&NLM_F_REQUEST))
-               return 0;
-
        type = nlh->nlmsg_type;
-
-       /* A control message: ignore them */
-       if (type < RTM_BASE)
-               return 0;
-
-       /* Unknown message: reply with EINVAL */
        if (type > RTM_MAX)
-               goto err_inval;
+               return -EOPNOTSUPP;
 
        type -= RTM_BASE;
 
@@ -883,40 +837,33 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
                return 0;
 
        family = ((struct rtgenmsg*)NLMSG_DATA(nlh))->rtgen_family;
-       if (family >= NPROTO) {
-               *errp = -EAFNOSUPPORT;
-               return -1;
-       }
+       if (family >= NPROTO)
+               return -EAFNOSUPPORT;
 
        sz_idx = type>>2;
        kind = type&3;
 
-       if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN)) {
-               *errp = -EPERM;
-               return -1;
-       }
+       if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN))
+               return -EPERM;
 
        if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
                rtnl_dumpit_func dumpit;
 
                dumpit = rtnl_get_dumpit(family, type);
                if (dumpit == NULL)
-                       goto err_inval;
+                       return -EOPNOTSUPP;
 
-               if ((*errp = netlink_dump_start(rtnl, skb, nlh,
-                                               dumpit, NULL)) != 0) {
-                       return -1;
-               }
-
-               netlink_queue_skip(nlh, skb);
-               return -1;
+               __rtnl_unlock();
+               err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
+               rtnl_lock();
+               return err;
        }
 
        memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *)));
 
        min_len = rtm_min[sz_idx];
        if (nlh->nlmsg_len < min_len)
-               goto err_inval;
+               return -EINVAL;
 
        if (nlh->nlmsg_len > min_len) {
                int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len);
@@ -926,7 +873,7 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
                        unsigned flavor = attr->rta_type;
                        if (flavor) {
                                if (flavor > rta_max[sz_idx])
-                                       goto err_inval;
+                                       return -EINVAL;
                                rta_buf[flavor-1] = attr;
                        }
                        attr = RTA_NEXT(attr, attrlen);
@@ -935,15 +882,9 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
 
        doit = rtnl_get_doit(family, type);
        if (doit == NULL)
-               goto err_inval;
-       err = doit(skb, nlh, (void *)&rta_buf[0]);
-
-       *errp = err;
-       return err;
+               return -EOPNOTSUPP;
 
-err_inval:
-       *errp = -EINVAL;
-       return -1;
+       return doit(skb, nlh, (void *)&rta_buf[0]);
 }
 
 static void rtnetlink_rcv(struct sock *sk, int len)
@@ -959,17 +900,6 @@ static void rtnetlink_rcv(struct sock *sk, int len)
        } while (qlen);
 }
 
-static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] =
-{
-       [RTM_GETADDR     - RTM_BASE] = { .dumpit = rtnl_dump_all         },
-       [RTM_GETROUTE    - RTM_BASE] = { .dumpit = rtnl_dump_all         },
-#ifdef CONFIG_FIB_RULES
-       [RTM_NEWRULE     - RTM_BASE] = { .doit   = fib_nl_newrule        },
-       [RTM_DELRULE     - RTM_BASE] = { .doit   = fib_nl_delrule        },
-#endif
-       [RTM_GETRULE     - RTM_BASE] = { .dumpit = rtnl_dump_all         },
-};
-
 static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
        struct net_device *dev = ptr;
@@ -1011,7 +941,7 @@ void __init rtnetlink_init(void)
                panic("rtnetlink_init: cannot allocate rta_buf\n");
 
        rtnl = netlink_kernel_create(NETLINK_ROUTE, RTNLGRP_MAX, rtnetlink_rcv,
-                                    THIS_MODULE);
+                                    &rtnl_mutex, THIS_MODULE);
        if (rtnl == NULL)
                panic("rtnetlink_init: cannot initialize rtnetlink\n");
        netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV);
@@ -1019,6 +949,9 @@ void __init rtnetlink_init(void)
 
        rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, rtnl_dump_ifinfo);
        rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL);
+
+       rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all);
+       rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all);
 }
 
 EXPORT_SYMBOL(__rta_fill);