kern/63317: [patch] make ng_ether(4) support "lower" and "orphans"
simultaneously
Gleb Smirnoff
glebius at cell.sick.ru
Tue Feb 24 11:50:13 PST 2004
>Number: 63317
>Category: kern
>Synopsis: [patch] make ng_ether(4) support "lower" and "orphans" simultaneously
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Tue Feb 24 11:50:12 PST 2004
>Closed-Date:
>Last-Modified:
>Originator: Gleb Smirnoff
>Release: FreeBSD 4.9-PRERELEASE i386
>Organization:
Oilspace, Inc.
>Environment:
System: FreeBSD cell.sick.ru 4.9-PRERELEASE FreeBSD 4.9-PRERELEASE #0: Fri Sep 19 10:22:46 MSD 2003 root at fade.bestcom.ru:/usr/obj/usr/src/sys/NUCLEUS i386
>Description:
It is mentioned in manpage ng_ether.4, that ng_ether node has
a limitation:
The orphans hook is equivalent to 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 orphans and lower
may be connected at any time.
In some cases it is necessary to use both hooks. Examining code
haven't revealed any obstacles for me, so I still can't guess
what was the purpose of such a limitation. May be developers
will point me at some underwater stone.
>How-To-Repeat:
Try to connect both "lower" and "orphans" at one time.
>Fix:
A patch for CURRENT follows. A patch for STABLE
can be found here:
http://cell.sick.ru/~glebius/patches/netgraph/ng_ether_lowerorphan/ng_ether.c.diff.STABLE
The patch for STABLE was successfully used at production
router for ~ 2 weeks.
--- ng_ether.c.orig Mon Feb 23 15:18:14 2004
+++ ng_ether.c Mon Feb 23 15:26:20 2004
@@ -71,8 +71,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 */
@@ -95,7 +95,7 @@
static void ng_ether_detach(struct ifnet *ifp);
/* Other functions */
-static void ng_ether_input2(node_p node, struct mbuf **mp);
+static void ng_ether_input2(hook_p hook, 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);
@@ -204,9 +204,9 @@
const priv_p priv = NG_NODE_PRIVATE(node);
/* 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_ether_input2(priv->lower, mp);
}
/*
@@ -222,11 +222,11 @@
const priv_p priv = NG_NODE_PRIVATE(node);
/* If "orphan" hook not connected, let packet continue */
- if (priv->lower == NULL || !priv->lowerOrphan) {
+ if (priv->orphan == NULL ) {
m_freem(m);
return;
}
- ng_ether_input2(node, &m);
+ ng_ether_input2(priv->orphan, &m);
if (m != NULL)
m_freem(m);
}
@@ -239,13 +239,12 @@
* NOTE: this function will get called at splimp()
*/
static void
-ng_ether_input2(node_p node, struct mbuf **mp)
+ng_ether_input2(hook_p hook, 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);
+ NG_SEND_DATA_ONLY(error, hook, *mp);
*mp = NULL;
}
@@ -353,7 +352,6 @@
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 */
@@ -365,10 +363,8 @@
hookptr = &priv->upper;
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;
+ hookptr = &priv->orphan;
} else
return (EINVAL);
@@ -382,7 +378,6 @@
/* OK */
*hookptr = hook;
- priv->lowerOrphan = orphan;
return (0);
}
@@ -515,7 +510,7 @@
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);
@@ -632,7 +627,8 @@
priv->ifp->if_hwassist = priv->hwassist;
} else if (hook == priv->lower) {
priv->lower = NULL;
- priv->lowerOrphan = 0;
+ } else if (hook == priv->orphan) {
+ priv->orphan = NULL;
} else
panic("%s: weird hook", __func__);
if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list