X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fcore%2Frtnetlink.c;fp=net%2Fcore%2Frtnetlink.c;h=46f356344b0d7041c82dd8818a3c109398042d07;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=84ca035d82079a8f7d3eacbe8e5ca5b6c1c760e1;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 84ca035d8..46f356344 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -16,6 +16,7 @@ * Vitaly E. Lavrov RTA_OK arithmetics was wrong. */ +#include #include #include #include @@ -34,7 +35,6 @@ #include #include #include -#include #include #include @@ -50,34 +50,24 @@ #include #include #include -#ifdef CONFIG_NET_WIRELESS_RTNETLINK -#include -#include -#endif /* CONFIG_NET_WIRELESS_RTNETLINK */ -static DEFINE_MUTEX(rtnl_mutex); +DECLARE_MUTEX(rtnl_sem); void rtnl_lock(void) { - mutex_lock(&rtnl_mutex); + rtnl_shlock(); } -void __rtnl_unlock(void) +int rtnl_lock_interruptible(void) { - mutex_unlock(&rtnl_mutex); + return down_interruptible(&rtnl_sem); } - + void rtnl_unlock(void) { - mutex_unlock(&rtnl_mutex); - if (rtnl && rtnl->sk_receive_queue.qlen) - rtnl->sk_data_ready(rtnl, 0); - netdev_run_todo(); -} + rtnl_shunlock(); -int rtnl_trylock(void) -{ - return mutex_trylock(&rtnl_mutex); + netdev_run_todo(); } int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len) @@ -189,33 +179,6 @@ rtattr_failure: } -static void set_operstate(struct net_device *dev, unsigned char transition) -{ - unsigned char operstate = dev->operstate; - - switch(transition) { - case IF_OPER_UP: - if ((operstate == IF_OPER_DORMANT || - operstate == IF_OPER_UNKNOWN) && - !netif_dormant(dev)) - operstate = IF_OPER_UP; - break; - - case IF_OPER_DORMANT: - if (operstate == IF_OPER_UP || - operstate == IF_OPER_UNKNOWN) - operstate = IF_OPER_DORMANT; - break; - }; - - if (dev->operstate != operstate) { - write_lock_bh(&dev_base_lock); - dev->operstate = operstate; - write_unlock_bh(&dev_base_lock); - netdev_state_change(dev); - } -} - static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, int type, u32 pid, u32 seq, u32 change, unsigned int flags) @@ -245,13 +208,6 @@ static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, RTA_PUT(skb, IFLA_WEIGHT, sizeof(weight), &weight); } - if (1) { - u8 operstate = netif_running(dev)?dev->operstate:IF_OPER_DOWN; - u8 link_mode = dev->link_mode; - RTA_PUT(skb, IFLA_OPERSTATE, sizeof(operstate), &operstate); - RTA_PUT(skb, IFLA_LINKMODE, sizeof(link_mode), &link_mode); - } - if (1) { struct rtnl_link_ifmap map = { .mem_start = dev->mem_start, @@ -459,22 +415,6 @@ static int do_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) dev->weight = *((u32 *) RTA_DATA(ida[IFLA_WEIGHT - 1])); } - if (ida[IFLA_OPERSTATE - 1]) { - if (ida[IFLA_OPERSTATE - 1]->rta_len != RTA_LENGTH(sizeof(u8))) - goto out; - - set_operstate(dev, *((u8 *) RTA_DATA(ida[IFLA_OPERSTATE - 1]))); - } - - if (ida[IFLA_LINKMODE - 1]) { - if (ida[IFLA_LINKMODE - 1]->rta_len != RTA_LENGTH(sizeof(u8))) - goto out; - - write_lock_bh(&dev_base_lock); - dev->link_mode = *((u8 *) RTA_DATA(ida[IFLA_LINKMODE - 1])); - write_unlock_bh(&dev_base_lock); - } - if (ifm->ifi_index >= 0 && ida[IFLA_IFNAME - 1]) { char ifname[IFNAMSIZ]; @@ -486,17 +426,6 @@ static int do_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) goto out; } -#ifdef CONFIG_NET_WIRELESS_RTNETLINK - if (ida[IFLA_WIRELESS - 1]) { - - /* Call Wireless Extensions. - * Various stuff checked in there... */ - err = wireless_rtnetlink_set(dev, RTA_DATA(ida[IFLA_WIRELESS - 1]), ida[IFLA_WIRELESS - 1]->rta_len); - if (err) - goto out; - } -#endif /* CONFIG_NET_WIRELESS_RTNETLINK */ - err = 0; out: @@ -507,83 +436,6 @@ out: return err; } -#ifdef CONFIG_NET_WIRELESS_RTNETLINK -static int do_getlink(struct sk_buff *in_skb, struct nlmsghdr* in_nlh, void *arg) -{ - struct ifinfomsg *ifm = NLMSG_DATA(in_nlh); - struct rtattr **ida = arg; - struct net_device *dev; - struct ifinfomsg *r; - struct nlmsghdr *nlh; - int err = -ENOBUFS; - struct sk_buff *skb; - unsigned char *b; - char *iw_buf = NULL; - int iw_buf_len = 0; - - if (ifm->ifi_index >= 0) - dev = dev_get_by_index(ifm->ifi_index); - else - return -EINVAL; - if (!dev) - return -ENODEV; - -#ifdef CONFIG_NET_WIRELESS_RTNETLINK - if (ida[IFLA_WIRELESS - 1]) { - - /* Call Wireless Extensions. We need to know the size before - * we can alloc. Various stuff checked in there... */ - err = wireless_rtnetlink_get(dev, RTA_DATA(ida[IFLA_WIRELESS - 1]), ida[IFLA_WIRELESS - 1]->rta_len, &iw_buf, &iw_buf_len); - if (err) - goto out; - } -#endif /* CONFIG_NET_WIRELESS_RTNETLINK */ - - /* Create a skb big enough to include all the data. - * Some requests are way bigger than 4k... Jean II */ - skb = alloc_skb((NLMSG_LENGTH(sizeof(*r))) + (RTA_SPACE(iw_buf_len)), - GFP_KERNEL); - if (!skb) - goto out; - b = skb->tail; - - /* Put in the message the usual good stuff */ - nlh = NLMSG_PUT(skb, NETLINK_CB(in_skb).pid, in_nlh->nlmsg_seq, - RTM_NEWLINK, sizeof(*r)); - r = NLMSG_DATA(nlh); - r->ifi_family = AF_UNSPEC; - r->__ifi_pad = 0; - r->ifi_type = dev->type; - r->ifi_index = dev->ifindex; - r->ifi_flags = dev->flags; - r->ifi_change = 0; - - /* Put the wireless payload if it exist */ - if(iw_buf != NULL) - RTA_PUT(skb, IFLA_WIRELESS, iw_buf_len, - iw_buf + IW_EV_POINT_OFF); - - nlh->nlmsg_len = skb->tail - b; - - /* Needed ? */ - NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid; - - err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); - if (err > 0) - err = 0; -out: - if(iw_buf != NULL) - kfree(iw_buf); - dev_put(dev); - return err; - -rtattr_failure: -nlmsg_failure: - kfree_skb(skb); - goto out; -} -#endif /* CONFIG_NET_WIRELESS_RTNETLINK */ - static int rtnetlink_dump_all(struct sk_buff *skb, struct netlink_callback *cb) { int idx; @@ -681,7 +533,7 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) sz_idx = type>>2; kind = type&3; - if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN)) { + if (kind != 2 && security_netlink_recv(skb)) { *errp = -EPERM; return -1; } @@ -742,9 +594,9 @@ static void rtnetlink_rcv(struct sock *sk, int len) unsigned int qlen = 0; do { - mutex_lock(&rtnl_mutex); + rtnl_lock(); netlink_run_queue(sk, &qlen, &rtnetlink_rcv_msg); - mutex_unlock(&rtnl_mutex); + up(&rtnl_sem); netdev_run_todo(); } while (qlen); @@ -752,11 +604,7 @@ static void rtnetlink_rcv(struct sock *sk, int len) static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] = { - [RTM_GETLINK - RTM_BASE] = { -#ifdef CONFIG_NET_WIRELESS_RTNETLINK - .doit = do_getlink, -#endif /* CONFIG_NET_WIRELESS_RTNETLINK */ - .dumpit = rtnetlink_dump_ifinfo }, + [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo }, [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, [RTM_GETADDR - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, [RTM_GETROUTE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, @@ -825,5 +673,6 @@ EXPORT_SYMBOL(rtnetlink_links); EXPORT_SYMBOL(rtnetlink_put_metrics); EXPORT_SYMBOL(rtnl); EXPORT_SYMBOL(rtnl_lock); -EXPORT_SYMBOL(rtnl_trylock); +EXPORT_SYMBOL(rtnl_lock_interruptible); +EXPORT_SYMBOL(rtnl_sem); EXPORT_SYMBOL(rtnl_unlock);