diff --git a/share/man/man4/ng_ether.4 b/share/man/man4/ng_ether.4 index f1b5731600d7..3dceb9a1c19a 100644 --- a/share/man/man4/ng_ether.4 +++ b/share/man/man4/ng_ether.4 @@ -97,12 +97,12 @@ The hook is equivalent to .Va lower , except that only unrecognized packets (that would otherwise be discarded) -are written to the hook, and normal incoming traffic is unaffected. -At most one of +are written to the hook, while other normal incoming traffic is unaffected. +Unrecognized packets written to +.Va upper +will be forwarded back out to .Va orphans -and -.Va lower -may be connected at any time. +if connected. .Pp In all cases, frames are raw Ethernet frames with the standard 14 byte Ethernet header (but no checksum). diff --git a/sys/netgraph/ng_ether.c b/sys/netgraph/ng_ether.c index 52fdee5d0252..ca63f5ec2be1 100644 --- a/sys/netgraph/ng_ether.c +++ b/sys/netgraph/ng_ether.c @@ -70,8 +70,8 @@ struct private { struct ifnet *ifp; /* associated interface */ hook_p upper; /* upper hook connection */ - hook_p lower; /* lower OR orphan hook connection */ - u_char lowerOrphan; /* whether lower is lower or orphan */ + hook_p lower; /* lower hook connection */ + hook_p orphan; /* orphan hook connection */ u_char autoSrcAddr; /* always overwrite source address */ u_char promisc; /* promiscuous mode enabled */ u_long hwassist; /* hardware checksum capabilities */ @@ -94,7 +94,6 @@ static void ng_ether_attach(struct ifnet *ifp); static void ng_ether_detach(struct ifnet *ifp); /* Other functions */ -static void ng_ether_input2(node_p node, struct mbuf **mp); static int ng_ether_rcv_lower(node_p node, struct mbuf *m, meta_p meta); static int ng_ether_rcv_upper(node_p node, struct mbuf *m, meta_p meta); @@ -201,11 +200,12 @@ ng_ether_input(struct ifnet *ifp, struct mbuf **mp) { const node_p node = IFP2NG(ifp); const priv_p priv = NG_NODE_PRIVATE(node); + int error; /* If "lower" hook not connected, let packet continue */ - if (priv->lower == NULL || priv->lowerOrphan) + if (priv->lower == NULL) return; - ng_ether_input2(node, mp); + NG_SEND_DATA_ONLY(error, priv->lower, *mp); /* sets *mp = NULL */ } /* @@ -219,33 +219,14 @@ ng_ether_input_orphan(struct ifnet *ifp, struct mbuf *m) { const node_p node = IFP2NG(ifp); const priv_p priv = NG_NODE_PRIVATE(node); + int error; - /* If "orphan" hook not connected, let packet continue */ - if (priv->lower == NULL || !priv->lowerOrphan) { + /* If "orphan" hook not connected, discard packet */ + if (priv->orphan == NULL) { m_freem(m); return; } - ng_ether_input2(node, &m); - if (m != NULL) - m_freem(m); -} - -/* - * Handle a packet that has come in on an ethernet interface. - * The Ethernet header has already been detached from the mbuf, - * so we have to put it back. - * - * NOTE: this function will get called at splimp() - */ -static void -ng_ether_input2(node_p node, struct mbuf **mp) -{ - const priv_p priv = NG_NODE_PRIVATE(node); - int error; - - /* Send out lower/orphan hook */ - NG_SEND_DATA_ONLY(error, priv->lower, *mp); - *mp = NULL; + NG_SEND_DATA_ONLY(error, priv->orphan, m); } /* @@ -352,7 +333,6 @@ static int ng_ether_newhook(node_p node, hook_p hook, const char *name) { const priv_p priv = NG_NODE_PRIVATE(node); - u_char orphan = priv->lowerOrphan; hook_p *hookptr; /* Divert hook is an alias for lower */ @@ -362,13 +342,11 @@ ng_ether_newhook(node_p node, hook_p hook, const char *name) /* Which hook? */ if (strcmp(name, NG_ETHER_HOOK_UPPER) == 0) hookptr = &priv->upper; - else if (strcmp(name, NG_ETHER_HOOK_LOWER) == 0) { + else if (strcmp(name, NG_ETHER_HOOK_LOWER) == 0) hookptr = &priv->lower; - orphan = 0; - } else if (strcmp(name, NG_ETHER_HOOK_ORPHAN) == 0) { - hookptr = &priv->lower; - orphan = 1; - } else + else if (strcmp(name, NG_ETHER_HOOK_ORPHAN) == 0) + hookptr = &priv->orphan; + else return (EINVAL); /* Check if already connected (shouldn't be, but doesn't hurt) */ @@ -381,7 +359,6 @@ ng_ether_newhook(node_p node, hook_p hook, const char *name) /* OK */ *hookptr = hook; - priv->lowerOrphan = orphan; return (0); } @@ -514,18 +491,18 @@ ng_ether_rcvdata(hook_p hook, item_p item) NGI_GET_M(item, m); NGI_GET_META(item, meta); NG_FREE_ITEM(item); - if (hook == priv->lower) + if (hook == priv->lower || hook == priv->orphan) return ng_ether_rcv_lower(node, m, meta); if (hook == priv->upper) return ng_ether_rcv_upper(node, m, meta); panic("%s: weird hook", __func__); -#ifdef RESTARTABLE_PANICS /* so we don;t get an error msg in LINT */ +#ifdef RESTARTABLE_PANICS /* so we don't get an error msg in LINT */ return NULL; #endif } /* - * Handle an mbuf received on the "lower" hook. + * Handle an mbuf received on the "lower" or "orphan" hook. */ static int ng_ether_rcv_lower(node_p node, struct mbuf *m, meta_p meta) @@ -629,10 +606,11 @@ ng_ether_disconnect(hook_p hook) priv->upper = NULL; if (priv->ifp != NULL) /* restore h/w csum */ priv->ifp->if_hwassist = priv->hwassist; - } else if (hook == priv->lower) { + } else if (hook == priv->lower) priv->lower = NULL; - priv->lowerOrphan = 0; - } else + else if (hook == priv->orphan) + priv->orphan = NULL; + else panic("%s: weird hook", __func__); if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook))))