Commit 0d7308c0 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

af_packet: Introduce egress hook

Add egress hook for AF_PACKET sockets that have the PACKET_QDISC_BYPASS
socket option set to on, which allows packets to escape without being
filtered in the egress path.

This patch only updates the AF_PACKET path, it does not update
dev_direct_xmit() so the XDP infrastructure has a chance to bypass
Netfilter.

[lukas: acquire rcu_read_lock, fix typos, rebase]
Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 42df6e1d
......@@ -91,6 +91,7 @@
#endif
#include <linux/bpf.h>
#include <net/compat.h>
#include <linux/netfilter_netdev.h>
#include "internal.h"
......@@ -241,8 +242,42 @@ struct packet_skb_cb {
static void __fanout_unlink(struct sock *sk, struct packet_sock *po);
static void __fanout_link(struct sock *sk, struct packet_sock *po);
#ifdef CONFIG_NETFILTER_EGRESS
static noinline struct sk_buff *nf_hook_direct_egress(struct sk_buff *skb)
{
struct sk_buff *next, *head = NULL, *tail;
int rc;
rcu_read_lock();
for (; skb != NULL; skb = next) {
next = skb->next;
skb_mark_not_on_list(skb);
if (!nf_hook_egress(skb, &rc, skb->dev))
continue;
if (!head)
head = skb;
else
tail->next = skb;
tail = skb;
}
rcu_read_unlock();
return head;
}
#endif
static int packet_direct_xmit(struct sk_buff *skb)
{
#ifdef CONFIG_NETFILTER_EGRESS
if (nf_hook_egress_active()) {
skb = nf_hook_direct_egress(skb);
if (!skb)
return NET_XMIT_DROP;
}
#endif
return dev_direct_xmit(skb, packet_pick_tx_queue(skb));
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment