PERFORCE change 40111 for review
Sam Leffler
sam at FreeBSD.org
Tue Oct 21 12:13:35 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=40111
Change 40111 by sam at 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(ðer_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(ðer_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(ðer_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(ðer_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, ðer_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, ðer_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:
More information about the p4-projects
mailing list