Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1153f29 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by David S. Miller
Browse files

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: default avatarStephen Hemminger <shemminger@vyatta.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6f8b13bc
Loading
Loading
Loading
Loading
+23 −4
Original line number Diff line number Diff line
@@ -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);

		if (sk_filter(sk, skb))
			kfree_skb(skb);
		else {
			skb_queue_tail(&sk->sk_receive_queue, skb);
		sk->sk_data_ready(sk, len);
			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));

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