aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/rtnetlink.c
diff options
context:
space:
mode:
authorTony Luck <tony.luck@intel.com>2005-05-17 18:53:14 -0400
committerTony Luck <tony.luck@intel.com>2005-05-17 18:53:14 -0400
commit325a479c4c110db278ef3361460a48c4093252cc (patch)
treebcfbf4d0647d9442045639a5c19da59d55190e81 /net/core/rtnetlink.c
parentebcc80c1b6629a445f7471cc1ddb48faf8a84e70 (diff)
parent7f9eaedf894dbaa08c157832e9a6c9c03ffed1ed (diff)
Merge with temp tree to get David's gdb inferior calls patch
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r--net/core/rtnetlink.c67
1 files changed, 38 insertions, 29 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index d8c198e42f90..00caf4b318b2 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -86,30 +86,33 @@ struct sock *rtnl;
86 86
87struct rtnetlink_link * rtnetlink_links[NPROTO]; 87struct rtnetlink_link * rtnetlink_links[NPROTO];
88 88
89static const int rtm_min[(RTM_MAX+1-RTM_BASE)/4] = 89static const int rtm_min[RTM_NR_FAMILIES] =
90{ 90{
91 NLMSG_LENGTH(sizeof(struct ifinfomsg)), 91 [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
92 NLMSG_LENGTH(sizeof(struct ifaddrmsg)), 92 [RTM_FAM(RTM_NEWADDR)] = NLMSG_LENGTH(sizeof(struct ifaddrmsg)),
93 NLMSG_LENGTH(sizeof(struct rtmsg)), 93 [RTM_FAM(RTM_NEWROUTE)] = NLMSG_LENGTH(sizeof(struct rtmsg)),
94 NLMSG_LENGTH(sizeof(struct ndmsg)), 94 [RTM_FAM(RTM_NEWNEIGH)] = NLMSG_LENGTH(sizeof(struct ndmsg)),
95 NLMSG_LENGTH(sizeof(struct rtmsg)), 95 [RTM_FAM(RTM_NEWRULE)] = NLMSG_LENGTH(sizeof(struct rtmsg)),
96 NLMSG_LENGTH(sizeof(struct tcmsg)), 96 [RTM_FAM(RTM_NEWQDISC)] = NLMSG_LENGTH(sizeof(struct tcmsg)),
97 NLMSG_LENGTH(sizeof(struct tcmsg)), 97 [RTM_FAM(RTM_NEWTCLASS)] = NLMSG_LENGTH(sizeof(struct tcmsg)),
98 NLMSG_LENGTH(sizeof(struct tcmsg)), 98 [RTM_FAM(RTM_NEWTFILTER)] = NLMSG_LENGTH(sizeof(struct tcmsg)),
99 NLMSG_LENGTH(sizeof(struct tcamsg)) 99 [RTM_FAM(RTM_NEWACTION)] = NLMSG_LENGTH(sizeof(struct tcamsg)),
100 [RTM_FAM(RTM_NEWPREFIX)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
101 [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
102 [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
100}; 103};
101 104
102static const int rta_max[(RTM_MAX+1-RTM_BASE)/4] = 105static const int rta_max[RTM_NR_FAMILIES] =
103{ 106{
104 IFLA_MAX, 107 [RTM_FAM(RTM_NEWLINK)] = IFLA_MAX,
105 IFA_MAX, 108 [RTM_FAM(RTM_NEWADDR)] = IFA_MAX,
106 RTA_MAX, 109 [RTM_FAM(RTM_NEWROUTE)] = RTA_MAX,
107 NDA_MAX, 110 [RTM_FAM(RTM_NEWNEIGH)] = NDA_MAX,
108 RTA_MAX, 111 [RTM_FAM(RTM_NEWRULE)] = RTA_MAX,
109 TCA_MAX, 112 [RTM_FAM(RTM_NEWQDISC)] = TCA_MAX,
110 TCA_MAX, 113 [RTM_FAM(RTM_NEWTCLASS)] = TCA_MAX,
111 TCA_MAX, 114 [RTM_FAM(RTM_NEWTFILTER)] = TCA_MAX,
112 TCAA_MAX 115 [RTM_FAM(RTM_NEWACTION)] = TCAA_MAX,
113}; 116};
114 117
115void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data) 118void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data)
@@ -606,27 +609,33 @@ static inline int rtnetlink_rcv_skb(struct sk_buff *skb)
606 609
607/* 610/*
608 * rtnetlink input queue processing routine: 611 * rtnetlink input queue processing routine:
609 * - try to acquire shared lock. If it is failed, defer processing. 612 * - process as much as there was in the queue upon entry.
610 * - feed skbs to rtnetlink_rcv_skb, until it refuse a message, 613 * - feed skbs to rtnetlink_rcv_skb, until it refuse a message,
611 * that will occur, when a dump started and/or acquisition of 614 * that will occur, when a dump started.
612 * exclusive lock failed.
613 */ 615 */
614 616
615static void rtnetlink_rcv(struct sock *sk, int len) 617static void rtnetlink_rcv(struct sock *sk, int len)
616{ 618{
619 unsigned int qlen = skb_queue_len(&sk->sk_receive_queue);
620
617 do { 621 do {
618 struct sk_buff *skb; 622 struct sk_buff *skb;
619 623
620 if (rtnl_shlock_nowait()) 624 rtnl_lock();
621 return; 625
626 if (qlen > skb_queue_len(&sk->sk_receive_queue))
627 qlen = skb_queue_len(&sk->sk_receive_queue);
622 628
623 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { 629 for (; qlen; qlen--) {
630 skb = skb_dequeue(&sk->sk_receive_queue);
624 if (rtnetlink_rcv_skb(skb)) { 631 if (rtnetlink_rcv_skb(skb)) {
625 if (skb->len) 632 if (skb->len)
626 skb_queue_head(&sk->sk_receive_queue, 633 skb_queue_head(&sk->sk_receive_queue,
627 skb); 634 skb);
628 else 635 else {
629 kfree_skb(skb); 636 kfree_skb(skb);
637 qlen--;
638 }
630 break; 639 break;
631 } 640 }
632 kfree_skb(skb); 641 kfree_skb(skb);
@@ -635,10 +644,10 @@ static void rtnetlink_rcv(struct sock *sk, int len)
635 up(&rtnl_sem); 644 up(&rtnl_sem);
636 645
637 netdev_run_todo(); 646 netdev_run_todo();
638 } while (rtnl && rtnl->sk_receive_queue.qlen); 647 } while (qlen);
639} 648}
640 649
641static struct rtnetlink_link link_rtnetlink_table[RTM_MAX-RTM_BASE+1] = 650static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] =
642{ 651{
643 [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo }, 652 [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo },
644 [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, 653 [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink },