rtnetlink.c (db46edc6d3b66bf708a8f23a9aa89f63a49ebe33) | rtnetlink.c (2a0a6ebee1d68552152ae8d4aeda91d806995dec) |
---|---|
1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * Routing netlink socket interface: protocol independent part. 7 * 8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> --- 595 unchanged lines hidden (view full) --- 604 skb_pull(skb, rlen); 605 } 606 607 return 0; 608} 609 610/* 611 * rtnetlink input queue processing routine: | 1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * Routing netlink socket interface: protocol independent part. 7 * 8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> --- 595 unchanged lines hidden (view full) --- 604 skb_pull(skb, rlen); 605 } 606 607 return 0; 608} 609 610/* 611 * rtnetlink input queue processing routine: |
612 * - try to acquire shared lock. If it is failed, defer processing. | 612 * - process as much as there was in the queue upon entry. |
613 * - feed skbs to rtnetlink_rcv_skb, until it refuse a message, | 613 * - feed skbs to rtnetlink_rcv_skb, until it refuse a message, |
614 * that will occur, when a dump started and/or acquisition of 615 * exclusive lock failed. | 614 * that will occur, when a dump started. |
616 */ 617 618static void rtnetlink_rcv(struct sock *sk, int len) 619{ | 615 */ 616 617static void rtnetlink_rcv(struct sock *sk, int len) 618{ |
619 unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); 620 |
|
620 do { 621 struct sk_buff *skb; 622 | 621 do { 622 struct sk_buff *skb; 623 |
623 if (rtnl_shlock_nowait()) 624 return; | 624 rtnl_lock(); |
625 | 625 |
626 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 626 if (qlen > skb_queue_len(&sk->sk_receive_queue)) 627 qlen = skb_queue_len(&sk->sk_receive_queue); 628 629 while (qlen--) { 630 skb = skb_dequeue(&sk->sk_receive_queue); |
627 if (rtnetlink_rcv_skb(skb)) { | 631 if (rtnetlink_rcv_skb(skb)) { |
628 if (skb->len) | 632 if (skb->len) { |
629 skb_queue_head(&sk->sk_receive_queue, 630 skb); | 633 skb_queue_head(&sk->sk_receive_queue, 634 skb); |
631 else | 635 qlen++; 636 } else |
632 kfree_skb(skb); 633 break; 634 } 635 kfree_skb(skb); 636 } 637 638 up(&rtnl_sem); 639 640 netdev_run_todo(); | 637 kfree_skb(skb); 638 break; 639 } 640 kfree_skb(skb); 641 } 642 643 up(&rtnl_sem); 644 645 netdev_run_todo(); |
641 } while (rtnl && rtnl->sk_receive_queue.qlen); | 646 } while (qlen); |
642} 643 644static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] = 645{ 646 [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo }, 647 [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, 648 [RTM_GETADDR - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, 649 [RTM_GETROUTE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, --- 65 unchanged lines hidden --- | 647} 648 649static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] = 650{ 651 [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo }, 652 [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, 653 [RTM_GETADDR - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, 654 [RTM_GETROUTE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, --- 65 unchanged lines hidden --- |