Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Oct 2003 12:13:33 -0700 (PDT)
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 40111 for review
Message-ID:  <200310211913.h9LJDXAJ096619@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=40111

Change 40111 by sam@sam_ebb on 2003/10/21 12:12:41

	replace 3/5's of the netgraph hook functions with pfil hooks;
	this is the first step to removing all the global pointer crap
	from the ethernet processing paths
	
	for now keep things under PFIL_HOOKS but if this stuff gets
	committed then we'll need PFIL_HOOKS in the base system or
	at least GENERIC

Affected files ...

.. //depot/projects/netperf/sys/net/ethernet.h#2 edit
.. //depot/projects/netperf/sys/net/if_ethersubr.c#6 edit
.. //depot/projects/netperf/sys/net/pfil.h#5 edit
.. //depot/projects/netperf/sys/netgraph/ng_ether.c#2 edit

Differences ...

==== //depot/projects/netperf/sys/net/ethernet.h#2 (text+ko) ====

@@ -359,6 +359,10 @@
 extern	int  ether_output_frame(struct ifnet *, struct mbuf *);
 extern	char *ether_sprintf(const u_int8_t *);
 
+#ifdef PFIL_HOOKS
+extern	pfil_head ether_pfil_hook;
+#endif
+
 #else /* _KERNEL */
 
 #include <sys/cdefs.h>

==== //depot/projects/netperf/sys/net/if_ethersubr.c#6 (text+ko) ====

@@ -96,9 +96,6 @@
 #endif /* NETATALK */
 
 /* netgraph node hooks for ng_ether(4) */
-void	(*ng_ether_input_p)(struct ifnet *ifp, struct mbuf **mp);
-void	(*ng_ether_input_orphan_p)(struct ifnet *ifp, struct mbuf *m);
-int	(*ng_ether_output_p)(struct ifnet *ifp, struct mbuf **mp);
 void	(*ng_ether_attach_p)(struct ifnet *ifp);
 void	(*ng_ether_detach_p)(struct ifnet *ifp);
 
@@ -111,6 +108,10 @@
 bdgtakeifaces_t *bdgtakeifaces_ptr;
 struct bdg_softc *ifp2sc;
 
+#ifdef PFIL_HOOKS
+struct	pfil_head ether_pfil_hook;
+#endif
+
 static u_char etherbroadcastaddr[ETHER_ADDR_LEN] =
 			{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
@@ -300,20 +301,20 @@
 			return (0);	/* XXX */
 		}
 	}
-
-	/* Handle ng_ether(4) processing, if any */
-	if (ng_ether_output_p != NULL) {
-		if ((error = (*ng_ether_output_p)(ifp, &m)) != 0) {
-bad:			if (m != NULL)
-				m_freem(m);
-			return (error);
-		}
-		if (m == NULL)
-			return (0);
-	}
-
+#ifdef PFIL_HOOKS
+	/*
+	 * Run through list of hooks for output packets.
+	 */
+	error = pfil_run_hooks(&ether_pfil_hook, &m, ifp, PFIL_OUT);
+	if (error != 0 || m == NULL)
+		goto bad;
+#endif
 	/* Continue with link-layer output */
 	return ether_output_frame(ifp, m);
+bad:
+	if (m != NULL)
+		m_freem(m);
+	return (error);
 }
 
 /*
@@ -540,14 +541,15 @@
 	}
 
 	ifp->if_ibytes += m->m_pkthdr.len;
-
-	/* Handle ng_ether(4) processing, if any */
-	if (ng_ether_input_p != NULL) {
-		(*ng_ether_input_p)(ifp, &m);
-		if (m == NULL)
-			return;
-	}
-
+#ifdef PFIL_HOOKS
+	/*
+	 * Run through list of hooks for input packets.
+	 */
+	if (pfil_run_hooks(&inet_pfil_hook, &m, ifp, PFIL_IN) != 0)
+		return;
+	if (m == NULL)			/* consumed by filter */
+		return;
+#endif
 	/* Check for bridging mode */
 	if (BDG_ACTIVE(ifp) ) {
 		struct ifnet *bif;
@@ -787,20 +789,20 @@
 
 discard:
 	/*
-	 * Packet is to be discarded.  If netgraph is present,
-	 * hand the packet to it for last chance processing;
-	 * otherwise dispose of it.
+	 * Packet is to be discarded.  If let hooks have a
+	 * last go at it before we reclaim storage.
+	 */
+#ifdef PFIL_HOOKS
+	/*
+	 * Put back the ethernet header so hooks have a
+	 * consistent view of inbound packets.
 	 */
-	if (ng_ether_input_orphan_p != NULL) {
-		/*
-		 * Put back the ethernet header so netgraph has a
-		 * consistent view of inbound packets.
-		 */
-		M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT);
-		(*ng_ether_input_orphan_p)(ifp, m);
-		return;
-	}
-	m_freem(m);
+	M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT);
+	if (pfil_run_hooks(&ether_pfil_hook, &m, ifp, PFIL_IN_DISCARD) != 0)
+		m = NULL;		/* hook consumed packet, don't free */
+#endif
+	if (m != NULL)
+		m_freem(m);
 }
 
 /*
@@ -1038,11 +1040,53 @@
 	}
 }
 
+static int
+ether_modinit(void)
+{
+#ifdef PFIL_HOOKS
+	int error;
+
+	ether_pfil_hook.ph_type = PFIL_TYPE_AF;
+	ether_pfil_hook.ph_af = AF_LINK;		/* XXX */
+	error = pfil_head_register(&ether_pfil_hook);
+	if (error != 0)
+		printf("%s: Unable to register hook, error %d\n",
+			__func__, error);
+	return error;
+#else
+	return 0;
+#endif
+}
+
+static int
+ether_moddestroy(void)
+{
+#ifdef PFIL_HOOKS
+	(void) pfil_head_unregister(&ether_pfil_hook);
+#endif
+	return 0;
+}
+
+/*
+ * Module glue.
+ */
+static int
+ether_modevent(module_t mod, int type, void *unused)
+{
+	switch (type) {
+	case MOD_LOAD:
+		return ether_modinit();
+	case MOD_UNLOAD:
+		return ether_moddestroy();
+	}
+	return EINVAL;
+}
+
 static moduledata_t ether_mod = {
         "ether",
-        NULL,
+        ether_modevent,
         0
 };
                 
-DECLARE_MODULE(ether, ether_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
+DECLARE_MODULE(ether, ether_mod, SI_SUB_PSEUDO, SI_ORDER_FIRST);
 MODULE_VERSION(ether, 1);

==== //depot/projects/netperf/sys/net/pfil.h#5 (text+ko) ====

@@ -54,7 +54,8 @@
 
 #define PFIL_IN		0x00000001
 #define PFIL_OUT	0x00000002
-#define PFIL_WAITOK	0x00000004
+#define	PFIL_IN_DISCARD	0x00000004
+#define PFIL_WAITOK	0x00000008
 #define PFIL_ALL	(PFIL_IN|PFIL_OUT)
 
 typedef	TAILQ_HEAD(pfil_list, packet_filter_hook) pfil_list_t;

==== //depot/projects/netperf/sys/netgraph/ng_ether.c#2 (text+ko) ====

@@ -57,6 +57,7 @@
 #include <net/if_types.h>
 #include <net/if_arp.h>
 #include <net/if_var.h>
+#include <net/pfil.h>
 #include <net/ethernet.h>
 
 #include <netgraph/ng_message.h>
@@ -81,16 +82,11 @@
 typedef struct private *priv_p;
 
 /* Hook pointers used by if_ethersubr.c to callback to netgraph */
-extern	void	(*ng_ether_input_p)(struct ifnet *ifp, struct mbuf **mp);
-extern	void	(*ng_ether_input_orphan_p)(struct ifnet *ifp, struct mbuf *m);
-extern	int	(*ng_ether_output_p)(struct ifnet *ifp, struct mbuf **mp);
 extern	void	(*ng_ether_attach_p)(struct ifnet *ifp);
 extern	void	(*ng_ether_detach_p)(struct ifnet *ifp);
 
 /* Functional hooks called from if_ethersubr.c */
-static void	ng_ether_input(struct ifnet *ifp, struct mbuf **mp);
-static void	ng_ether_input_orphan(struct ifnet *ifp, struct mbuf *m);
-static int	ng_ether_output(struct ifnet *ifp, struct mbuf **mp);
+static int	ng_ether_pfil(void *, struct mbuf **, struct ifnet *, int);
 static void	ng_ether_attach(struct ifnet *ifp);
 static void	ng_ether_detach(struct ifnet *ifp); 
 
@@ -205,43 +201,34 @@
 ******************************************************************/
 
 /*
- * Handle a packet that has come in on an interface. We get to
+ * Handle a packet through an interface. We get to
  * look at it here before any upper layer protocols do.
- *
- * NOTE: this function will get called at splimp()
  */
 static void
-ng_ether_input(struct ifnet *ifp, struct mbuf **mp)
+ng_ether_pfil(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
 {
 	const node_p node = IFP2NG(ifp);
 	const priv_p priv = NG_NODE_PRIVATE(node);
+	int error = 0;
 
-	/* If "lower" hook not connected, let packet continue */
-	if (priv->lower == NULL || priv->lowerOrphan)
-		return;
-	ng_ether_input2(node, mp);
-}
-
-/*
- * Handle a packet that has come in on an interface, and which
- * does not match any of our known protocols (an ``orphan'').
- *
- * NOTE: this function will get called at splimp()
- */
-static void
-ng_ether_input_orphan(struct ifnet *ifp, struct mbuf *m)
-{
-	const node_p node = IFP2NG(ifp);
-	const priv_p priv = NG_NODE_PRIVATE(node);
-
-	/* If "orphan" hook not connected, let packet continue */
-	if (priv->lower == NULL || !priv->lowerOrphan) {
-		m_freem(m);
-		return;
+	switch (dir) {
+	case PFIL_IN:		/* inbound packet */
+		/* If "lower" hook not connected, let packet continue */
+		if (priv->lower != NULL && !priv->lowerOrphan)
+			ng_ether_input2(node, mp);
+		break;
+	case PFIL_OUT:		/* outbound packet */
+		/* If "upper" hook not connected, let packet continue */
+		if (priv->upper != NULL)
+			NG_SEND_DATA_ONLY(error, priv->upper, *mp);
+		break;
+	case PFIL_IN_DISCARD:	/* inbound discard */
+		/* If "orphan" hook not connected, let packet continue */
+		if (priv->lower != NULL && priv->lowerOrphan) {
+			ng_ether_input2(node, &m);
+		break;
 	}
-	ng_ether_input2(node, &m);
-	if (m != NULL)
-		m_freem(m);
+	return (error);
 }
 
 /*
@@ -263,26 +250,6 @@
 }
 
 /*
- * Handle a packet that is going out on an interface.
- * The Ethernet header is already attached to the mbuf.
- */
-static int
-ng_ether_output(struct ifnet *ifp, struct mbuf **mp)
-{
-	const node_p node = IFP2NG(ifp);
-	const priv_p priv = NG_NODE_PRIVATE(node);
-	int error = 0;
-
-	/* If "upper" hook not connected, let packet continue */
-	if (priv->upper == NULL)
-		return (0);
-
-	/* Send it out "upper" hook */
-	NG_SEND_DATA_ONLY(error, priv->upper, *mp);
-	return (error);
-}
-
-/*
  * A new Ethernet interface has been attached.
  * Create a new node for it, etc.
  */
@@ -721,11 +688,12 @@
 			error = EEXIST;
 			break;
 		}
+		error = pfil_add_hook(ng_ether_pfil, 0,
+			PFIL_ALL | PFIL_IN_DISCARD, &ether_pfil_head);
+		if (error)
+			break;
 		ng_ether_attach_p = ng_ether_attach;
 		ng_ether_detach_p = ng_ether_detach;
-		ng_ether_output_p = ng_ether_output;
-		ng_ether_input_p = ng_ether_input;
-		ng_ether_input_orphan_p = ng_ether_input_orphan;
 
 		/* Create nodes for any already-existing Ethernet interfaces */
 		IFNET_RLOCK();
@@ -748,11 +716,10 @@
 		 */
 
 		/* Unregister function hooks */
+		(void) pfil_remove_hook(ng_ether_pfil, 0,
+			PFIL_ALL | PFIL_IN_DISCARD, &ether_pfil_head);
 		ng_ether_attach_p = NULL;
 		ng_ether_detach_p = NULL;
-		ng_ether_output_p = NULL;
-		ng_ether_input_p = NULL;
-		ng_ether_input_orphan_p = NULL;
 		break;
 
 	default:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200310211913.h9LJDXAJ096619>