提交 b1153f29 编写于 作者: S Stephen Hemminger 提交者: David S. Miller

netlink: make socket filters work on netlink

Make socket filters work for netlink unicast and notifications.
This is useful for applications like Zebra that get overrun with
messages that are then ignored.

Note: netlink messages are in host byte order, but packet filter
state machine operations are done as network byte order.
Signed-off-by: NStephen Hemminger <shemminger@vyatta.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 6f8b13bc
...@@ -886,6 +886,13 @@ int netlink_unicast(struct sock *ssk, struct sk_buff *skb, ...@@ -886,6 +886,13 @@ int netlink_unicast(struct sock *ssk, struct sk_buff *skb,
if (netlink_is_kernel(sk)) if (netlink_is_kernel(sk))
return netlink_unicast_kernel(sk, skb); 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); err = netlink_attachskb(sk, skb, nonblock, &timeo, ssk);
if (err == 1) if (err == 1)
goto retry; goto retry;
...@@ -980,6 +987,9 @@ static inline int do_one_broadcast(struct sock *sk, ...@@ -980,6 +987,9 @@ static inline int do_one_broadcast(struct sock *sk,
netlink_overrun(sk); netlink_overrun(sk);
/* Clone failed. Notify ALL listeners. */ /* Clone failed. Notify ALL listeners. */
p->failure = 1; 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) { } else if ((val = netlink_broadcast_deliver(sk, p->skb2)) < 0) {
netlink_overrun(sk); netlink_overrun(sk);
} else { } else {
...@@ -1533,8 +1543,13 @@ static int netlink_dump(struct sock *sk) ...@@ -1533,8 +1543,13 @@ static int netlink_dump(struct sock *sk)
if (len > 0) { if (len > 0) {
mutex_unlock(nlk->cb_mutex); 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; return 0;
} }
...@@ -1544,8 +1559,12 @@ static int netlink_dump(struct sock *sk) ...@@ -1544,8 +1559,12 @@ static int netlink_dump(struct sock *sk)
memcpy(nlmsg_data(nlh), &len, sizeof(len)); memcpy(nlmsg_data(nlh), &len, sizeof(len));
skb_queue_tail(&sk->sk_receive_queue, skb); if (sk_filter(sk, skb))
sk->sk_data_ready(sk, skb->len); kfree_skb(skb);
else {
skb_queue_tail(&sk->sk_receive_queue, skb);
sk->sk_data_ready(sk, skb->len);
}
if (cb->done) if (cb->done)
cb->done(cb); cb->done(cb);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册