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
This commit is contained in:
parent
2ed07f34d6
commit
a3e232d65b
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user