From: Pablo Neira Ayuso <pa...@netfilter.org>

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.

Signed-off-by: Pablo Neira Ayuso <pa...@netfilter.org>
[lukas: acquire rcu_read_lock, fix typos, rebase]
Signed-off-by: Lukas Wunner <lu...@wunner.de>
---
 net/packet/af_packet.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 6bbc7a448593..6dca6ead1162 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -89,6 +89,7 @@
 #endif
 #include <linux/bpf.h>
 #include <net/compat.h>
+#include <linux/netfilter_netdev.h>
 
 #include "internal.h"
 
@@ -239,8 +240,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));
 }
 
-- 
2.29.2

Reply via email to