Loading net/core/rtnetlink.c +5 −70 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ #include <net/udp.h> #include <net/sock.h> #include <net/pkt_sched.h> #include <net/netlink.h> DECLARE_MUTEX(rtnl_sem); Loading Loading @@ -519,8 +520,6 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) } if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { u32 rlen; if (link->dumpit == NULL) link = &(rtnetlink_links[PF_UNSPEC][type]); Loading @@ -531,10 +530,8 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) link->dumpit, NULL)) != 0) { return -1; } rlen = NLMSG_ALIGN(nlh->nlmsg_len); if (rlen > skb->len) rlen = skb->len; skb_pull(skb, rlen); netlink_queue_skip(nlh, skb); return -1; } Loading Loading @@ -573,75 +570,13 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) return -1; } /* * Process one packet of messages. * Malformed skbs with wrong lengths of messages are discarded silently. */ static inline int rtnetlink_rcv_skb(struct sk_buff *skb) { int err; struct nlmsghdr * nlh; while (skb->len >= NLMSG_SPACE(0)) { u32 rlen; nlh = (struct nlmsghdr *)skb->data; if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) return 0; rlen = NLMSG_ALIGN(nlh->nlmsg_len); if (rlen > skb->len) rlen = skb->len; if (rtnetlink_rcv_msg(skb, nlh, &err)) { /* Not error, but we must interrupt processing here: * Note, that in this case we do not pull message * from skb, it will be processed later. */ if (err == 0) return -1; netlink_ack(skb, nlh, err); } else if (nlh->nlmsg_flags&NLM_F_ACK) netlink_ack(skb, nlh, 0); skb_pull(skb, rlen); } return 0; } /* * rtnetlink input queue processing routine: * - process as much as there was in the queue upon entry. * - feed skbs to rtnetlink_rcv_skb, until it refuse a message, * that will occur, when a dump started. */ static void rtnetlink_rcv(struct sock *sk, int len) { unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); unsigned int qlen = 0; do { struct sk_buff *skb; rtnl_lock(); if (qlen > skb_queue_len(&sk->sk_receive_queue)) qlen = skb_queue_len(&sk->sk_receive_queue); for (; qlen; qlen--) { skb = skb_dequeue(&sk->sk_receive_queue); if (rtnetlink_rcv_skb(skb)) { if (skb->len) skb_queue_head(&sk->sk_receive_queue, skb); else { kfree_skb(skb); qlen--; } break; } kfree_skb(skb); } netlink_run_queue(sk, &qlen, &rtnetlink_rcv_msg); up(&rtnl_sem); netdev_run_todo(); Loading Loading
net/core/rtnetlink.c +5 −70 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ #include <net/udp.h> #include <net/sock.h> #include <net/pkt_sched.h> #include <net/netlink.h> DECLARE_MUTEX(rtnl_sem); Loading Loading @@ -519,8 +520,6 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) } if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { u32 rlen; if (link->dumpit == NULL) link = &(rtnetlink_links[PF_UNSPEC][type]); Loading @@ -531,10 +530,8 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) link->dumpit, NULL)) != 0) { return -1; } rlen = NLMSG_ALIGN(nlh->nlmsg_len); if (rlen > skb->len) rlen = skb->len; skb_pull(skb, rlen); netlink_queue_skip(nlh, skb); return -1; } Loading Loading @@ -573,75 +570,13 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) return -1; } /* * Process one packet of messages. * Malformed skbs with wrong lengths of messages are discarded silently. */ static inline int rtnetlink_rcv_skb(struct sk_buff *skb) { int err; struct nlmsghdr * nlh; while (skb->len >= NLMSG_SPACE(0)) { u32 rlen; nlh = (struct nlmsghdr *)skb->data; if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) return 0; rlen = NLMSG_ALIGN(nlh->nlmsg_len); if (rlen > skb->len) rlen = skb->len; if (rtnetlink_rcv_msg(skb, nlh, &err)) { /* Not error, but we must interrupt processing here: * Note, that in this case we do not pull message * from skb, it will be processed later. */ if (err == 0) return -1; netlink_ack(skb, nlh, err); } else if (nlh->nlmsg_flags&NLM_F_ACK) netlink_ack(skb, nlh, 0); skb_pull(skb, rlen); } return 0; } /* * rtnetlink input queue processing routine: * - process as much as there was in the queue upon entry. * - feed skbs to rtnetlink_rcv_skb, until it refuse a message, * that will occur, when a dump started. */ static void rtnetlink_rcv(struct sock *sk, int len) { unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); unsigned int qlen = 0; do { struct sk_buff *skb; rtnl_lock(); if (qlen > skb_queue_len(&sk->sk_receive_queue)) qlen = skb_queue_len(&sk->sk_receive_queue); for (; qlen; qlen--) { skb = skb_dequeue(&sk->sk_receive_queue); if (rtnetlink_rcv_skb(skb)) { if (skb->len) skb_queue_head(&sk->sk_receive_queue, skb); else { kfree_skb(skb); qlen--; } break; } kfree_skb(skb); } netlink_run_queue(sk, &qlen, &rtnetlink_rcv_msg); up(&rtnl_sem); netdev_run_todo(); Loading