From 0f874737d40a5552526605bb98c57a1b0787ab4d Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 21 Mar 2008 15:46:12 -0700 Subject: [PATCH] --- yaml --- r: 90195 b: refs/heads/master c: b1153f29ee07dc1a788964409255a4b4fae50b98 h: refs/heads/master i: 90193: fa42f6376d8c5da9bb199792d2773bbf6829300f 90191: 769d1e3d300dbb91a8ee682025ea534751ca5f88 v: v3 --- [refs] | 2 +- trunk/net/netlink/af_netlink.c | 27 +++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index 9b82b1092b9a..e366c5cecd51 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6f8b13bcb3369a5df2e63acc422bed6098f5b8c4 +refs/heads/master: b1153f29ee07dc1a788964409255a4b4fae50b98 diff --git a/trunk/net/netlink/af_netlink.c b/trunk/net/netlink/af_netlink.c index 524e826bb976..86bd8660a8f2 100644 --- a/trunk/net/netlink/af_netlink.c +++ b/trunk/net/netlink/af_netlink.c @@ -886,6 +886,13 @@ int netlink_unicast(struct sock *ssk, struct sk_buff *skb, if (netlink_is_kernel(sk)) return netlink_unicast_kernel(sk, skb); + if (sk_filter(sk, skb)) { + int err = skb->len; + kfree_skb(skb); + sock_put(sk); + return err; + } + err = netlink_attachskb(sk, skb, nonblock, &timeo, ssk); if (err == 1) goto retry; @@ -980,6 +987,9 @@ static inline int do_one_broadcast(struct sock *sk, netlink_overrun(sk); /* Clone failed. Notify ALL listeners. */ p->failure = 1; + } else if (sk_filter(sk, p->skb2)) { + kfree_skb(p->skb2); + p->skb2 = NULL; } else if ((val = netlink_broadcast_deliver(sk, p->skb2)) < 0) { netlink_overrun(sk); } else { @@ -1533,8 +1543,13 @@ static int netlink_dump(struct sock *sk) if (len > 0) { mutex_unlock(nlk->cb_mutex); - skb_queue_tail(&sk->sk_receive_queue, skb); - sk->sk_data_ready(sk, len); + + if (sk_filter(sk, skb)) + kfree_skb(skb); + else { + skb_queue_tail(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk, skb->len); + } return 0; } @@ -1544,8 +1559,12 @@ static int netlink_dump(struct sock *sk) memcpy(nlmsg_data(nlh), &len, sizeof(len)); - skb_queue_tail(&sk->sk_receive_queue, skb); - sk->sk_data_ready(sk, skb->len); + if (sk_filter(sk, skb)) + kfree_skb(skb); + else { + skb_queue_tail(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk, skb->len); + } if (cb->done) cb->done(cb);