Skip to content

Commit

Permalink
[RTNETLINK]: Use generic netlink receive queue processor
Browse files Browse the repository at this point in the history
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Thomas Graf authored and Thomas Graf committed Nov 10, 2005
1 parent 88fc2c8 commit 9ac4a16
Showing 1 changed file with 5 additions and 70 deletions.
75 changes: 5 additions & 70 deletions net/core/rtnetlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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]);

Expand All @@ -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;
}

Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 9ac4a16

Please sign in to comment.