linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] PF_PACKET filtering hooks for netfilter
@ 2002-09-07 16:45 Marc Zyngier
  2002-09-20 11:35 ` Marc Zyngier
  0 siblings, 1 reply; 2+ messages in thread
From: Marc Zyngier @ 2002-09-07 16:45 UTC (permalink / raw)
  To: netfilter-devel; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 607 bytes --]

Hi all,

The included patch adds two new hooks to the netfilter framework, at
the packet level.

With this patch, it is now possible to write filtering modules for non
IP/ARP protocols (or even filtering access to user-mode services bound
to a packet socket (DHCP, for example...).

It also add the necessary logic to control such modules via
setsockopt/getsockopt.

I made two version of this patch : one for 2.4.20-pre5, the other for
2.5.33. I'd be very glad to have some feedback from people trying it,
as well as any comment about what is ok and what isn't with this patch.

Thanks a lot,

        M.


[-- Attachment #2: PF_PACKET hooks 2.4.20-pre5 (BK) --]
[-- Type: text/plain, Size: 6450 bytes --]

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.612   -> 1.613  
#	net/packet/af_packet.c	1.10    -> 1.11   
#	      net/core/dev.c	1.28    -> 1.29   
#	               (new)	        -> 1.1     include/linux/netfilter_packet.h
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/07	maz@hina.wild-wind.fr.eu.org	1.613
# Implements PF_PACKET netfilter hooks, as well as PF_PACKET
# {get,set}sockopt operations to control modules.
# --------------------------------------------
#
diff -Nru a/include/linux/netfilter_packet.h b/include/linux/netfilter_packet.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_packet.h	Sat Sep  7 18:25:04 2002
@@ -0,0 +1,17 @@
+#ifndef __LINUX_NETFILTER_PACKET_H
+#define __LINUX_NETFILTER_PACKET_H
+
+/* PF_PACKET-specific defines for netfilter.
+ * Written by Marc Zyngier <Marc.Zyngier@evidian.com>
+ * (C)2002 Evidian -- This code is GPL.
+ */
+
+#include <linux/config.h>
+#include <linux/netfilter.h>
+
+/* PF_PACKET filter hooks */
+
+#define NF_PACKET_INPUT		0
+#define NF_PACKET_OUTPUT	1
+
+#endif /* __LINUX_NETFILTER_PACKET_H */
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c	Sat Sep  7 18:25:04 2002
+++ b/net/core/dev.c	Sat Sep  7 18:25:04 2002
@@ -100,6 +100,7 @@
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/module.h>
+#include <linux/netfilter_packet.h>
 #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
 #include <linux/wireless.h>		/* Note : will define WIRELESS_EXT */
 #include <net/iw_handler.h>
@@ -986,40 +987,11 @@
  *	to congestion or traffic shaping.
  */
 
-int dev_queue_xmit(struct sk_buff *skb)
+static inline int dev_queue_xmit_finish(struct sk_buff *skb)
 {
 	struct net_device *dev = skb->dev;
 	struct Qdisc  *q;
 
-	if (skb_shinfo(skb)->frag_list &&
-	    !(dev->features&NETIF_F_FRAGLIST) &&
-	    skb_linearize(skb, GFP_ATOMIC) != 0) {
-		kfree_skb(skb);
-		return -ENOMEM;
-	}
-
-	/* Fragmented skb is linearized if device does not support SG,
-	 * or if at least one of fragments is in highmem and device
-	 * does not support DMA from it.
-	 */
-	if (skb_shinfo(skb)->nr_frags &&
-	    (!(dev->features&NETIF_F_SG) || illegal_highdma(dev, skb)) &&
-	    skb_linearize(skb, GFP_ATOMIC) != 0) {
-		kfree_skb(skb);
-		return -ENOMEM;
-	}
-
-	/* If packet is not checksummed and device does not support
-	 * checksumming for this protocol, complete checksumming here.
-	 */
-	if (skb->ip_summed == CHECKSUM_HW &&
-	    (!(dev->features&(NETIF_F_HW_CSUM|NETIF_F_NO_CSUM)) &&
-	     (!(dev->features&NETIF_F_IP_CSUM) ||
-	      skb->protocol != htons(ETH_P_IP)))) {
-		if ((skb = skb_checksum_help(skb)) == NULL)
-			return -ENOMEM;
-	}
-
 	/* Grab device queue */
 	spin_lock_bh(&dev->queue_lock);
 	q = dev->qdisc;
@@ -1079,6 +1051,43 @@
 	return -ENETDOWN;
 }
 
+int dev_queue_xmit(struct sk_buff *skb)
+{
+	struct net_device *dev = skb->dev;
+
+	if (skb_shinfo(skb)->frag_list &&
+	    !(dev->features&NETIF_F_FRAGLIST) &&
+	    skb_linearize(skb, GFP_ATOMIC) != 0) {
+		kfree_skb(skb);
+		return -ENOMEM;
+	}
+
+	/* Fragmented skb is linearized if device does not support SG,
+	 * or if at least one of fragments is in highmem and device
+	 * does not support DMA from it.
+	 */
+	if (skb_shinfo(skb)->nr_frags &&
+	    (!(dev->features&NETIF_F_SG) || illegal_highdma(dev, skb)) &&
+	    skb_linearize(skb, GFP_ATOMIC) != 0) {
+		kfree_skb(skb);
+		return -ENOMEM;
+	}
+
+	/* If packet is not checksummed and device does not support
+	 * checksumming for this protocol, complete checksumming here.
+	 */
+	if (skb->ip_summed == CHECKSUM_HW &&
+	    (!(dev->features&(NETIF_F_HW_CSUM|NETIF_F_NO_CSUM)) &&
+	     (!(dev->features&NETIF_F_IP_CSUM) ||
+	      skb->protocol != htons(ETH_P_IP)))) {
+		if ((skb = skb_checksum_help(skb)) == NULL)
+			return -ENOMEM;
+	}
+
+	return NF_HOOK(PF_PACKET, NF_PACKET_OUTPUT, skb, NULL, dev,
+		       dev_queue_xmit_finish);
+}
+
 
 /*=======================================================================
 			Receiver routines
@@ -1424,28 +1433,12 @@
 }
 #endif   /* CONFIG_NET_DIVERT */
 
-int netif_receive_skb(struct sk_buff *skb)
+static inline int netif_receive_skb_finish(struct sk_buff *skb)
 {
 	struct packet_type *ptype, *pt_prev;
 	int ret = NET_RX_DROP;
 	unsigned short type = skb->protocol;
 
-	if (skb->stamp.tv_sec == 0)
-		do_gettimeofday(&skb->stamp);
-
-	skb_bond(skb);
-
-	netdev_rx_stat[smp_processor_id()].total++;
-
-#ifdef CONFIG_NET_FASTROUTE
-	if (skb->pkt_type == PACKET_FASTROUTE) {
-		netdev_rx_stat[smp_processor_id()].fastroute_deferred_out++;
-		return dev_queue_xmit(skb);
-	}
-#endif
-
-	skb->h.raw = skb->nh.raw = skb->data;
-
 	pt_prev = NULL;
 	for (ptype = ptype_all; ptype; ptype = ptype->next) {
 		if (!ptype->dev || ptype->dev == skb->dev) {
@@ -1503,6 +1496,28 @@
 	}
 
 	return ret;
+}
+
+int netif_receive_skb(struct sk_buff *skb)
+{
+	if (skb->stamp.tv_sec == 0)
+		do_gettimeofday(&skb->stamp);
+
+	skb_bond(skb);
+
+	netdev_rx_stat[smp_processor_id()].total++;
+
+#ifdef CONFIG_NET_FASTROUTE
+	if (skb->pkt_type == PACKET_FASTROUTE) {
+		netdev_rx_stat[smp_processor_id()].fastroute_deferred_out++;
+		return dev_queue_xmit(skb);
+	}
+#endif
+
+	skb->h.raw = skb->nh.raw = skb->data;
+
+	return NF_HOOK(PF_PACKET, NF_PACKET_INPUT, skb, skb->dev, NULL,
+		       netif_receive_skb_finish);
 }
 
 static int process_backlog(struct net_device *blog_dev, int *budget)
diff -Nru a/net/packet/af_packet.c b/net/packet/af_packet.c
--- a/net/packet/af_packet.c	Sat Sep  7 18:25:04 2002
+++ b/net/packet/af_packet.c	Sat Sep  7 18:25:04 2002
@@ -77,6 +77,10 @@
 #include <net/inet_common.h>
 #endif
 
+#ifdef CONFIG_NETFILTER
+#include <linux/netfilter.h>
+#endif
+
 #ifdef CONFIG_DLCI
 extern int dlci_ioctl(unsigned int, void*);
 #endif
@@ -1321,7 +1325,12 @@
 	}
 #endif
 	default:
+#ifdef CONFIG_NETFILTER
+	        return nf_setsockopt(sock->sk, PF_PACKET, optname, optval,
+				     optlen);
+#else
 		return -ENOPROTOOPT;
+#endif
 	}
 }
 
@@ -1358,7 +1367,12 @@
 		break;
 	}
 	default:
+#ifdef CONFIG_NETFILTER
+	  	return nf_getsockopt(sock->sk, PF_PACKET, optname, optval,
+				     optlen);
+#else
 		return -ENOPROTOOPT;
+#endif
 	}
 
   	if (put_user(len, optlen))

[-- Attachment #3: PF_PACKET hooks 2.5.33 (BK) --]
[-- Type: text/plain, Size: 6544 bytes --]

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.582   -> 1.583  
#	net/packet/af_packet.c	1.14    -> 1.15   
#	      net/core/dev.c	1.36    -> 1.37   
#	               (new)	        -> 1.1     include/linux/netfilter_packet.h
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/07	maz@hina.wild-wind.fr.eu.org	1.583
# Implements PF_PACKET netfilter hooks, as well as PF_PACKET
# {get,set}sockopt operations to control modules.
# --------------------------------------------
#
diff -Nru a/include/linux/netfilter_packet.h b/include/linux/netfilter_packet.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_packet.h	Sat Sep  7 15:35:07 2002
@@ -0,0 +1,17 @@
+#ifndef __LINUX_NETFILTER_PACKET_H
+#define __LINUX_NETFILTER_PACKET_H
+
+/* PF_PACKET-specific defines for netfilter.
+ * Written by Marc Zyngier <Marc.Zyngier@evidian.com>
+ * (C)2002 Evidian -- This code is GPL.
+ */
+
+#include <linux/config.h>
+#include <linux/netfilter.h>
+
+/* PF_PACKET filter hooks */
+
+#define NF_PACKET_INPUT		0
+#define NF_PACKET_OUTPUT	1
+
+#endif /* __LINUX_NETFILTER_PACKET_H */
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c	Sat Sep  7 15:35:07 2002
+++ b/net/core/dev.c	Sat Sep  7 15:35:07 2002
@@ -105,6 +105,7 @@
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/module.h>
+#include <linux/netfilter_packet.h>
 #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
 #include <linux/wireless.h>		/* Note : will define WIRELESS_EXT */
 #include <net/iw_handler.h>
@@ -976,37 +977,12 @@
  *	to congestion or traffic shaping.
  */
 
-int dev_queue_xmit(struct sk_buff *skb)
+static inline int dev_queue_xmit_finish(struct sk_buff *skb)
 {
 	struct net_device *dev = skb->dev;
 	struct Qdisc *q;
 	int rc = -ENOMEM;
 
-	if (skb_shinfo(skb)->frag_list &&
-	    !(dev->features & NETIF_F_FRAGLIST) &&
-	    skb_linearize(skb, GFP_ATOMIC))
-		goto out_kfree_skb;
-
-	/* Fragmented skb is linearized if device does not support SG,
-	 * or if at least one of fragments is in highmem and device
-	 * does not support DMA from it.
-	 */
-	if (skb_shinfo(skb)->nr_frags &&
-	    (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
-	    skb_linearize(skb, GFP_ATOMIC))
-		goto out_kfree_skb;
-
-	/* If packet is not checksummed and device does not support
-	 * checksumming for this protocol, complete checksumming here.
-	 */
-	if (skb->ip_summed == CHECKSUM_HW &&
-	    (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
-	     (!(dev->features & NETIF_F_IP_CSUM) ||
-	      skb->protocol != htons(ETH_P_IP)))) {
-		if ((skb = skb_checksum_help(skb)) == NULL)
-			goto out;
-	}
-
 	/* Grab device queue */
 	spin_lock_bh(&dev->queue_lock);
 	q = dev->qdisc;
@@ -1074,12 +1050,49 @@
 	spin_unlock_bh(&dev->queue_lock);
 out_enetdown:
 	rc = -ENETDOWN;
-out_kfree_skb:
 	kfree_skb(skb);
 out:
 	return rc;
 }
 
+int dev_queue_xmit(struct sk_buff *skb)
+{
+	struct net_device *dev = skb->dev;
+	int rc = -ENOMEM;
+
+	if (skb_shinfo(skb)->frag_list &&
+	    !(dev->features & NETIF_F_FRAGLIST) &&
+	    skb_linearize(skb, GFP_ATOMIC))
+		goto out_kfree_skb;
+
+	/* Fragmented skb is linearized if device does not support SG,
+	 * or if at least one of fragments is in highmem and device
+	 * does not support DMA from it.
+	 */
+	if (skb_shinfo(skb)->nr_frags &&
+	    (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
+	    skb_linearize(skb, GFP_ATOMIC))
+		goto out_kfree_skb;
+
+	/* If packet is not checksummed and device does not support
+	 * checksumming for this protocol, complete checksumming here.
+	 */
+	if (skb->ip_summed == CHECKSUM_HW &&
+	    (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
+	     (!(dev->features & NETIF_F_IP_CSUM) ||
+	      skb->protocol != htons(ETH_P_IP)))) {
+		if ((skb = skb_checksum_help(skb)) == NULL)
+			goto out;
+	}
+
+	return NF_HOOK(PF_PACKET, NF_PACKET_OUTPUT, skb, NULL, dev,
+		       dev_queue_xmit_finish);
+
+out_kfree_skb:
+	kfree_skb(skb);
+out:
+	return rc;
+}
 
 /*=======================================================================
 			Receiver routines
@@ -1427,28 +1440,12 @@
 }
 #endif   /* CONFIG_NET_DIVERT */
 
-int netif_receive_skb(struct sk_buff *skb)
+static inline int netif_receive_skb_finish(struct sk_buff *skb)
 {
 	struct packet_type *ptype, *pt_prev;
 	int ret = NET_RX_DROP;
 	unsigned short type = skb->protocol;
 
-	if (!skb->stamp.tv_sec)
-		do_gettimeofday(&skb->stamp);
-
-	skb_bond(skb);
-
-	netdev_rx_stat[smp_processor_id()].total++;
-
-#ifdef CONFIG_NET_FASTROUTE
-	if (skb->pkt_type == PACKET_FASTROUTE) {
-		netdev_rx_stat[smp_processor_id()].fastroute_deferred_out++;
-		return dev_queue_xmit(skb);
-	}
-#endif
-
-	skb->h.raw = skb->nh.raw = skb->data;
-
 	pt_prev = NULL;
 	for (ptype = ptype_all; ptype; ptype = ptype->next) {
 		if (!ptype->dev || ptype->dev == skb->dev) {
@@ -1509,6 +1506,28 @@
 	}
 
 	return ret;
+}
+
+int netif_receive_skb(struct sk_buff *skb)
+{
+	if (!skb->stamp.tv_sec)
+		do_gettimeofday(&skb->stamp);
+
+	skb_bond(skb);
+
+	netdev_rx_stat[smp_processor_id()].total++;
+
+#ifdef CONFIG_NET_FASTROUTE
+	if (skb->pkt_type == PACKET_FASTROUTE) {
+		netdev_rx_stat[smp_processor_id()].fastroute_deferred_out++;
+		return dev_queue_xmit(skb);
+	}
+#endif
+
+	skb->h.raw = skb->nh.raw = skb->data;
+
+	return NF_HOOK(PF_PACKET, NF_PACKET_INPUT, skb, skb->dev, NULL,
+		       netif_receive_skb_finish);
 }
 
 static int process_backlog(struct net_device *backlog_dev, int *budget)
diff -Nru a/net/packet/af_packet.c b/net/packet/af_packet.c
--- a/net/packet/af_packet.c	Sat Sep  7 15:35:07 2002
+++ b/net/packet/af_packet.c	Sat Sep  7 15:35:07 2002
@@ -77,6 +77,10 @@
 #include <net/inet_common.h>
 #endif
 
+#ifdef CONFIG_NETFILTER
+#include <linux/netfilter.h>
+#endif
+
 #ifdef CONFIG_DLCI
 extern int dlci_ioctl(unsigned int, void*);
 #endif
@@ -1333,7 +1337,12 @@
 	}
 #endif
 	default:
+#ifdef CONFIG_NETFILTER
+	        return nf_setsockopt(sock->sk, PF_PACKET, optname, optval,
+				     optlen);
+#else
 		return -ENOPROTOOPT;
+#endif
 	}
 }
 
@@ -1371,7 +1380,12 @@
 		break;
 	}
 	default:
+#ifdef CONFIG_NETFILTER
+	  	return nf_getsockopt(sock->sk, PF_PACKET, optname, optval,
+				     optlen);
+#else
 		return -ENOPROTOOPT;
+#endif
 	}
 
   	if (put_user(len, optlen))

[-- Attachment #4: Type: text/plain, Size: 58 bytes --]

-- 
Places change, faces change. Life is so very strange.

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH] PF_PACKET filtering hooks for netfilter
  2002-09-07 16:45 [PATCH] PF_PACKET filtering hooks for netfilter Marc Zyngier
@ 2002-09-20 11:35 ` Marc Zyngier
  0 siblings, 0 replies; 2+ messages in thread
From: Marc Zyngier @ 2002-09-20 11:35 UTC (permalink / raw)
  To: linux-kernel; +Cc: davem

[-- Attachment #1: Type: text/plain, Size: 625 bytes --]

David, Lkml,

The included patch adds two new hooks to the netfilter framework, at
the packet level.

With this patch, it is now possible to write filtering modules for non
IP/ARP protocols (or even filtering access to user-mode services bound
to a packet socket, encription at the device level...).

It also add the necessary logic to control such modules via
setsockopt/getsockopt.

I made two version of this patch : one for 2.4.20-pre5, the other for
2.5.33. I'd be very glad to have some feedback from people trying it,
as well as any comment about what is ok and what isn't with this patch.

Thanks a lot,

        M.


[-- Attachment #2: pf_packet-2.4.20-pre5.diff --]
[-- Type: text/plain, Size: 6450 bytes --]

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.612   -> 1.613  
#	net/packet/af_packet.c	1.10    -> 1.11   
#	      net/core/dev.c	1.28    -> 1.29   
#	               (new)	        -> 1.1     include/linux/netfilter_packet.h
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/07	maz@hina.wild-wind.fr.eu.org	1.613
# Implements PF_PACKET netfilter hooks, as well as PF_PACKET
# {get,set}sockopt operations to control modules.
# --------------------------------------------
#
diff -Nru a/include/linux/netfilter_packet.h b/include/linux/netfilter_packet.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_packet.h	Sat Sep  7 18:25:04 2002
@@ -0,0 +1,17 @@
+#ifndef __LINUX_NETFILTER_PACKET_H
+#define __LINUX_NETFILTER_PACKET_H
+
+/* PF_PACKET-specific defines for netfilter.
+ * Written by Marc Zyngier <Marc.Zyngier@evidian.com>
+ * (C)2002 Evidian -- This code is GPL.
+ */
+
+#include <linux/config.h>
+#include <linux/netfilter.h>
+
+/* PF_PACKET filter hooks */
+
+#define NF_PACKET_INPUT		0
+#define NF_PACKET_OUTPUT	1
+
+#endif /* __LINUX_NETFILTER_PACKET_H */
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c	Sat Sep  7 18:25:04 2002
+++ b/net/core/dev.c	Sat Sep  7 18:25:04 2002
@@ -100,6 +100,7 @@
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/module.h>
+#include <linux/netfilter_packet.h>
 #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
 #include <linux/wireless.h>		/* Note : will define WIRELESS_EXT */
 #include <net/iw_handler.h>
@@ -986,40 +987,11 @@
  *	to congestion or traffic shaping.
  */
 
-int dev_queue_xmit(struct sk_buff *skb)
+static inline int dev_queue_xmit_finish(struct sk_buff *skb)
 {
 	struct net_device *dev = skb->dev;
 	struct Qdisc  *q;
 
-	if (skb_shinfo(skb)->frag_list &&
-	    !(dev->features&NETIF_F_FRAGLIST) &&
-	    skb_linearize(skb, GFP_ATOMIC) != 0) {
-		kfree_skb(skb);
-		return -ENOMEM;
-	}
-
-	/* Fragmented skb is linearized if device does not support SG,
-	 * or if at least one of fragments is in highmem and device
-	 * does not support DMA from it.
-	 */
-	if (skb_shinfo(skb)->nr_frags &&
-	    (!(dev->features&NETIF_F_SG) || illegal_highdma(dev, skb)) &&
-	    skb_linearize(skb, GFP_ATOMIC) != 0) {
-		kfree_skb(skb);
-		return -ENOMEM;
-	}
-
-	/* If packet is not checksummed and device does not support
-	 * checksumming for this protocol, complete checksumming here.
-	 */
-	if (skb->ip_summed == CHECKSUM_HW &&
-	    (!(dev->features&(NETIF_F_HW_CSUM|NETIF_F_NO_CSUM)) &&
-	     (!(dev->features&NETIF_F_IP_CSUM) ||
-	      skb->protocol != htons(ETH_P_IP)))) {
-		if ((skb = skb_checksum_help(skb)) == NULL)
-			return -ENOMEM;
-	}
-
 	/* Grab device queue */
 	spin_lock_bh(&dev->queue_lock);
 	q = dev->qdisc;
@@ -1079,6 +1051,43 @@
 	return -ENETDOWN;
 }
 
+int dev_queue_xmit(struct sk_buff *skb)
+{
+	struct net_device *dev = skb->dev;
+
+	if (skb_shinfo(skb)->frag_list &&
+	    !(dev->features&NETIF_F_FRAGLIST) &&
+	    skb_linearize(skb, GFP_ATOMIC) != 0) {
+		kfree_skb(skb);
+		return -ENOMEM;
+	}
+
+	/* Fragmented skb is linearized if device does not support SG,
+	 * or if at least one of fragments is in highmem and device
+	 * does not support DMA from it.
+	 */
+	if (skb_shinfo(skb)->nr_frags &&
+	    (!(dev->features&NETIF_F_SG) || illegal_highdma(dev, skb)) &&
+	    skb_linearize(skb, GFP_ATOMIC) != 0) {
+		kfree_skb(skb);
+		return -ENOMEM;
+	}
+
+	/* If packet is not checksummed and device does not support
+	 * checksumming for this protocol, complete checksumming here.
+	 */
+	if (skb->ip_summed == CHECKSUM_HW &&
+	    (!(dev->features&(NETIF_F_HW_CSUM|NETIF_F_NO_CSUM)) &&
+	     (!(dev->features&NETIF_F_IP_CSUM) ||
+	      skb->protocol != htons(ETH_P_IP)))) {
+		if ((skb = skb_checksum_help(skb)) == NULL)
+			return -ENOMEM;
+	}
+
+	return NF_HOOK(PF_PACKET, NF_PACKET_OUTPUT, skb, NULL, dev,
+		       dev_queue_xmit_finish);
+}
+
 
 /*=======================================================================
 			Receiver routines
@@ -1424,28 +1433,12 @@
 }
 #endif   /* CONFIG_NET_DIVERT */
 
-int netif_receive_skb(struct sk_buff *skb)
+static inline int netif_receive_skb_finish(struct sk_buff *skb)
 {
 	struct packet_type *ptype, *pt_prev;
 	int ret = NET_RX_DROP;
 	unsigned short type = skb->protocol;
 
-	if (skb->stamp.tv_sec == 0)
-		do_gettimeofday(&skb->stamp);
-
-	skb_bond(skb);
-
-	netdev_rx_stat[smp_processor_id()].total++;
-
-#ifdef CONFIG_NET_FASTROUTE
-	if (skb->pkt_type == PACKET_FASTROUTE) {
-		netdev_rx_stat[smp_processor_id()].fastroute_deferred_out++;
-		return dev_queue_xmit(skb);
-	}
-#endif
-
-	skb->h.raw = skb->nh.raw = skb->data;
-
 	pt_prev = NULL;
 	for (ptype = ptype_all; ptype; ptype = ptype->next) {
 		if (!ptype->dev || ptype->dev == skb->dev) {
@@ -1503,6 +1496,28 @@
 	}
 
 	return ret;
+}
+
+int netif_receive_skb(struct sk_buff *skb)
+{
+	if (skb->stamp.tv_sec == 0)
+		do_gettimeofday(&skb->stamp);
+
+	skb_bond(skb);
+
+	netdev_rx_stat[smp_processor_id()].total++;
+
+#ifdef CONFIG_NET_FASTROUTE
+	if (skb->pkt_type == PACKET_FASTROUTE) {
+		netdev_rx_stat[smp_processor_id()].fastroute_deferred_out++;
+		return dev_queue_xmit(skb);
+	}
+#endif
+
+	skb->h.raw = skb->nh.raw = skb->data;
+
+	return NF_HOOK(PF_PACKET, NF_PACKET_INPUT, skb, skb->dev, NULL,
+		       netif_receive_skb_finish);
 }
 
 static int process_backlog(struct net_device *blog_dev, int *budget)
diff -Nru a/net/packet/af_packet.c b/net/packet/af_packet.c
--- a/net/packet/af_packet.c	Sat Sep  7 18:25:04 2002
+++ b/net/packet/af_packet.c	Sat Sep  7 18:25:04 2002
@@ -77,6 +77,10 @@
 #include <net/inet_common.h>
 #endif
 
+#ifdef CONFIG_NETFILTER
+#include <linux/netfilter.h>
+#endif
+
 #ifdef CONFIG_DLCI
 extern int dlci_ioctl(unsigned int, void*);
 #endif
@@ -1321,7 +1325,12 @@
 	}
 #endif
 	default:
+#ifdef CONFIG_NETFILTER
+	        return nf_setsockopt(sock->sk, PF_PACKET, optname, optval,
+				     optlen);
+#else
 		return -ENOPROTOOPT;
+#endif
 	}
 }
 
@@ -1358,7 +1367,12 @@
 		break;
 	}
 	default:
+#ifdef CONFIG_NETFILTER
+	  	return nf_getsockopt(sock->sk, PF_PACKET, optname, optval,
+				     optlen);
+#else
 		return -ENOPROTOOPT;
+#endif
 	}
 
   	if (put_user(len, optlen))

[-- Attachment #3: pf_packet-2.5.33.diff --]
[-- Type: text/plain, Size: 6544 bytes --]

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.582   -> 1.583  
#	net/packet/af_packet.c	1.14    -> 1.15   
#	      net/core/dev.c	1.36    -> 1.37   
#	               (new)	        -> 1.1     include/linux/netfilter_packet.h
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/07	maz@hina.wild-wind.fr.eu.org	1.583
# Implements PF_PACKET netfilter hooks, as well as PF_PACKET
# {get,set}sockopt operations to control modules.
# --------------------------------------------
#
diff -Nru a/include/linux/netfilter_packet.h b/include/linux/netfilter_packet.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_packet.h	Sat Sep  7 15:35:07 2002
@@ -0,0 +1,17 @@
+#ifndef __LINUX_NETFILTER_PACKET_H
+#define __LINUX_NETFILTER_PACKET_H
+
+/* PF_PACKET-specific defines for netfilter.
+ * Written by Marc Zyngier <Marc.Zyngier@evidian.com>
+ * (C)2002 Evidian -- This code is GPL.
+ */
+
+#include <linux/config.h>
+#include <linux/netfilter.h>
+
+/* PF_PACKET filter hooks */
+
+#define NF_PACKET_INPUT		0
+#define NF_PACKET_OUTPUT	1
+
+#endif /* __LINUX_NETFILTER_PACKET_H */
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c	Sat Sep  7 15:35:07 2002
+++ b/net/core/dev.c	Sat Sep  7 15:35:07 2002
@@ -105,6 +105,7 @@
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/module.h>
+#include <linux/netfilter_packet.h>
 #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
 #include <linux/wireless.h>		/* Note : will define WIRELESS_EXT */
 #include <net/iw_handler.h>
@@ -976,37 +977,12 @@
  *	to congestion or traffic shaping.
  */
 
-int dev_queue_xmit(struct sk_buff *skb)
+static inline int dev_queue_xmit_finish(struct sk_buff *skb)
 {
 	struct net_device *dev = skb->dev;
 	struct Qdisc *q;
 	int rc = -ENOMEM;
 
-	if (skb_shinfo(skb)->frag_list &&
-	    !(dev->features & NETIF_F_FRAGLIST) &&
-	    skb_linearize(skb, GFP_ATOMIC))
-		goto out_kfree_skb;
-
-	/* Fragmented skb is linearized if device does not support SG,
-	 * or if at least one of fragments is in highmem and device
-	 * does not support DMA from it.
-	 */
-	if (skb_shinfo(skb)->nr_frags &&
-	    (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
-	    skb_linearize(skb, GFP_ATOMIC))
-		goto out_kfree_skb;
-
-	/* If packet is not checksummed and device does not support
-	 * checksumming for this protocol, complete checksumming here.
-	 */
-	if (skb->ip_summed == CHECKSUM_HW &&
-	    (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
-	     (!(dev->features & NETIF_F_IP_CSUM) ||
-	      skb->protocol != htons(ETH_P_IP)))) {
-		if ((skb = skb_checksum_help(skb)) == NULL)
-			goto out;
-	}
-
 	/* Grab device queue */
 	spin_lock_bh(&dev->queue_lock);
 	q = dev->qdisc;
@@ -1074,12 +1050,49 @@
 	spin_unlock_bh(&dev->queue_lock);
 out_enetdown:
 	rc = -ENETDOWN;
-out_kfree_skb:
 	kfree_skb(skb);
 out:
 	return rc;
 }
 
+int dev_queue_xmit(struct sk_buff *skb)
+{
+	struct net_device *dev = skb->dev;
+	int rc = -ENOMEM;
+
+	if (skb_shinfo(skb)->frag_list &&
+	    !(dev->features & NETIF_F_FRAGLIST) &&
+	    skb_linearize(skb, GFP_ATOMIC))
+		goto out_kfree_skb;
+
+	/* Fragmented skb is linearized if device does not support SG,
+	 * or if at least one of fragments is in highmem and device
+	 * does not support DMA from it.
+	 */
+	if (skb_shinfo(skb)->nr_frags &&
+	    (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
+	    skb_linearize(skb, GFP_ATOMIC))
+		goto out_kfree_skb;
+
+	/* If packet is not checksummed and device does not support
+	 * checksumming for this protocol, complete checksumming here.
+	 */
+	if (skb->ip_summed == CHECKSUM_HW &&
+	    (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
+	     (!(dev->features & NETIF_F_IP_CSUM) ||
+	      skb->protocol != htons(ETH_P_IP)))) {
+		if ((skb = skb_checksum_help(skb)) == NULL)
+			goto out;
+	}
+
+	return NF_HOOK(PF_PACKET, NF_PACKET_OUTPUT, skb, NULL, dev,
+		       dev_queue_xmit_finish);
+
+out_kfree_skb:
+	kfree_skb(skb);
+out:
+	return rc;
+}
 
 /*=======================================================================
 			Receiver routines
@@ -1427,28 +1440,12 @@
 }
 #endif   /* CONFIG_NET_DIVERT */
 
-int netif_receive_skb(struct sk_buff *skb)
+static inline int netif_receive_skb_finish(struct sk_buff *skb)
 {
 	struct packet_type *ptype, *pt_prev;
 	int ret = NET_RX_DROP;
 	unsigned short type = skb->protocol;
 
-	if (!skb->stamp.tv_sec)
-		do_gettimeofday(&skb->stamp);
-
-	skb_bond(skb);
-
-	netdev_rx_stat[smp_processor_id()].total++;
-
-#ifdef CONFIG_NET_FASTROUTE
-	if (skb->pkt_type == PACKET_FASTROUTE) {
-		netdev_rx_stat[smp_processor_id()].fastroute_deferred_out++;
-		return dev_queue_xmit(skb);
-	}
-#endif
-
-	skb->h.raw = skb->nh.raw = skb->data;
-
 	pt_prev = NULL;
 	for (ptype = ptype_all; ptype; ptype = ptype->next) {
 		if (!ptype->dev || ptype->dev == skb->dev) {
@@ -1509,6 +1506,28 @@
 	}
 
 	return ret;
+}
+
+int netif_receive_skb(struct sk_buff *skb)
+{
+	if (!skb->stamp.tv_sec)
+		do_gettimeofday(&skb->stamp);
+
+	skb_bond(skb);
+
+	netdev_rx_stat[smp_processor_id()].total++;
+
+#ifdef CONFIG_NET_FASTROUTE
+	if (skb->pkt_type == PACKET_FASTROUTE) {
+		netdev_rx_stat[smp_processor_id()].fastroute_deferred_out++;
+		return dev_queue_xmit(skb);
+	}
+#endif
+
+	skb->h.raw = skb->nh.raw = skb->data;
+
+	return NF_HOOK(PF_PACKET, NF_PACKET_INPUT, skb, skb->dev, NULL,
+		       netif_receive_skb_finish);
 }
 
 static int process_backlog(struct net_device *backlog_dev, int *budget)
diff -Nru a/net/packet/af_packet.c b/net/packet/af_packet.c
--- a/net/packet/af_packet.c	Sat Sep  7 15:35:07 2002
+++ b/net/packet/af_packet.c	Sat Sep  7 15:35:07 2002
@@ -77,6 +77,10 @@
 #include <net/inet_common.h>
 #endif
 
+#ifdef CONFIG_NETFILTER
+#include <linux/netfilter.h>
+#endif
+
 #ifdef CONFIG_DLCI
 extern int dlci_ioctl(unsigned int, void*);
 #endif
@@ -1333,7 +1337,12 @@
 	}
 #endif
 	default:
+#ifdef CONFIG_NETFILTER
+	        return nf_setsockopt(sock->sk, PF_PACKET, optname, optval,
+				     optlen);
+#else
 		return -ENOPROTOOPT;
+#endif
 	}
 }
 
@@ -1371,7 +1380,12 @@
 		break;
 	}
 	default:
+#ifdef CONFIG_NETFILTER
+	  	return nf_getsockopt(sock->sk, PF_PACKET, optname, optval,
+				     optlen);
+#else
 		return -ENOPROTOOPT;
+#endif
 	}
 
   	if (put_user(len, optlen))

[-- Attachment #4: Type: text/plain, Size: 59 bytes --]


-- 
Places change, faces change. Life is so very strange.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2002-09-20 11:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-09-07 16:45 [PATCH] PF_PACKET filtering hooks for netfilter Marc Zyngier
2002-09-20 11:35 ` Marc Zyngier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).