From a3e232d65bcee69050712273e241533d8ade54cb Mon Sep 17 00:00:00 2001 From: Archie Cobbs Date: Tue, 5 Feb 2002 18:27:30 +0000 Subject: [PATCH] The hardware checksum code makes the assumption that a packet routed out a particular Ethernet interface will actually be delivered by (only) that device driver. This is not necessarily true when ng_ether(4) is used. To word around this, while a ng_ether(4)'s "upper" hook is connected, turn off all hardware checksum, fragmentation, etc., features for that interface. PR: kern/31586 MFC after: 1 week --- sys/netgraph/ng_ether.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sys/netgraph/ng_ether.c b/sys/netgraph/ng_ether.c index a3c14e97ace5..0050bdd8b960 100644 --- a/sys/netgraph/ng_ether.c +++ b/sys/netgraph/ng_ether.c @@ -75,6 +75,7 @@ struct private { u_char lowerOrphan; /* whether lower is lower or orphan */ u_char autoSrcAddr; /* always overwrite source address */ u_char promisc; /* promiscuous mode enabled */ + u_long hwassist; /* hardware checksum capabilities */ u_int flags; /* flags e.g. really die */ }; typedef struct private *priv_p; @@ -317,6 +318,7 @@ ng_ether_attach(struct ifnet *ifp) priv->ifp = ifp; IFP2NG(ifp) = node; priv->autoSrcAddr = 1; + priv->hwassist = ifp->if_hwassist; /* Try to give the node the same name as the interface */ if (ng_name_node(node, name) != 0) { @@ -468,6 +470,10 @@ ng_ether_newhook(node_p node, hook_p hook, const char *name) if (*hookptr != NULL) return (EISCONN); + /* Disable hardware checksums while 'upper' hook is connected */ + if (hookptr == &priv->upper) + priv->ifp->if_hwassist = 0; + /* OK */ *hookptr = hook; priv->lowerOrphan = orphan; @@ -715,9 +721,10 @@ ng_ether_disconnect(hook_p hook) { const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); - if (hook == priv->upper) + if (hook == priv->upper) { priv->upper = NULL; - else if (hook == priv->lower) { + priv->ifp->if_hwassist = priv->hwassist; /* restore h/w csum */ + } else if (hook == priv->lower) { priv->lower = NULL; priv->lowerOrphan = 0; } else