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 ---