diff options
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r-- | net/core/rtnetlink.c | 28 |
1 files changed, 9 insertions, 19 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index ed27c8e1d..dad9ee252 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -50,22 +50,22 @@ #include <net/sock.h> #include <net/pkt_sched.h> -atomic_t rtnl_rlockct; -struct wait_queue *rtnl_wait; +DECLARE_MUTEX(rtnl_sem); - -void rtnl_lock() +void rtnl_lock(void) { rtnl_shlock(); rtnl_exlock(); } - -void rtnl_unlock() + +void rtnl_unlock(void) { rtnl_exunlock(); rtnl_shunlock(); } + + int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len) { memset(tb, 0, sizeof(struct rtattr*)*maxattr); @@ -82,8 +82,6 @@ int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len) #ifdef CONFIG_RTNETLINK struct sock *rtnl; -unsigned long rtnl_wlockct; - struct rtnetlink_link * rtnetlink_links[NPROTO]; #define _S 1 /* superuser privileges required */ @@ -189,12 +187,14 @@ int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) int s_idx = cb->args[0]; struct device *dev; + read_lock(&dev_base_lock); for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { if (idx < s_idx) continue; if (rtnetlink_fill_ifinfo(skb, dev, RTM_NEWLINK, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq) <= 0) break; } + read_unlock(&dev_base_lock); cb->args[0] = idx; return skb->len; @@ -216,9 +216,7 @@ int rtnetlink_dump_all(struct sk_buff *skb, struct netlink_callback *cb) continue; if (idx > s_idx) memset(&cb->args[0], 0, sizeof(cb->args)); - if (rtnetlink_links[idx][type].dumpit(skb, cb) == 0) - continue; - if (skb_tailroom(skb) < 256) + if (rtnetlink_links[idx][type].dumpit(skb, cb)) break; } cb->family = idx; @@ -245,8 +243,6 @@ void rtmsg_ifinfo(int type, struct device *dev) static int rtnetlink_done(struct netlink_callback *cb) { - if (cap_raised(NETLINK_CB(cb->skb).eff_cap, CAP_NET_ADMIN) && cb->nlh->nlmsg_flags&NLM_F_ATOMIC) - rtnl_shunlock(); return 0; } @@ -314,15 +310,9 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) if (link->dumpit == NULL) goto err_inval; - /* Super-user locks all the tables to get atomic snapshot */ - if (cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN) - && nlh->nlmsg_flags&NLM_F_ATOMIC) - atomic_inc(&rtnl_rlockct); if ((*errp = netlink_dump_start(rtnl, skb, nlh, link->dumpit, rtnetlink_done)) != 0) { - if (cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN) && nlh->nlmsg_flags&NLM_F_ATOMIC) - atomic_dec(&rtnl_rlockct); return -1; } rlen = NLMSG_ALIGN(nlh->nlmsg_len); |