In data receive method when MAC address save is requested a false assumption is made that "curthread" is in same VNET as node, which of course is not always true. For example eiface is attached to a bridge and moved to different VNET: kldload ng_ether ngctl -f - << EOF mkpeer vtnet0: bridge lower uplink1 name vtnet0:lower switch0 mkpeer switch0: eiface link0 ether EOF jail -c path=/ vnet=new vnet.interface=ngeth0 persist host.hostname=test name=test exec.start="sh -c 'ifconfig ngeth0 inet 192.168.1.123/24; ifconfig ngeth0 up'" jexec test ping -c 1 192.168.1.254 ngctl msg switch0: gettable ngctl msg switch0: getstats 0 In this case failures are recorded as "memoryFailures". Fix: --- a/sys/netgraph/ng_bridge.c +++ b/sys/netgraph/ng_bridge.c @@ -911,8 +911,10 @@ ng_bridge_rcvdata(hook_p hook, item_p item) strncpy(mh->hook, NG_HOOK_NAME(ctx.incoming->hook), sizeof(mh->hook)); memcpy(mh->addr, eh->ether_shost, sizeof(mh->addr)); + CURVNET_SET(node->nd_vnet); NG_SEND_MSG_ID(error, node, msg, NG_NODE_ID(node), NG_NODE_ID(node)); + CURVNET_RESTORE(); if (error) counter_u64_add(ctx.incoming->stats.memoryFailures, 1); }
Created attachment 245156 [details] Switch VNETs when injecting mbufs into netgraph Good catch, thanks! However, the culprit here is not ng_bridge, but ng_eiface, whic may be on lease to another vnet, while it remains bonded to its origin vnet on the netgraph layer. In such circumstances, when injecting mbufs into netgraph, ng_eiface should switch curvnet to that of the netgraph layer, which it fails to. For the problem at hand, the attached patch would be a more accurate fix, since it cures the cause, not the symptom.
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=03ef737c544d3dd90a0000c18382db99ccf2ee9a commit 03ef737c544d3dd90a0000c18382db99ccf2ee9a Author: Marko Zec <zec@FreeBSD.org> AuthorDate: 2023-09-23 08:56:56 +0000 Commit: Marko Zec <zec@FreeBSD.org> CommitDate: 2023-09-23 08:56:56 +0000 ng_eiface: switch VNETs when injecting mbufs into netgraph A ng_eiface instance may be on lease to a different vnet while remaining tied to its parent vnet. In such circumstances, before injecting mbufs into netgraph, curvnet must be set to that of the ng_eiface's netgraph node. Mark the vnet transition as QUIET, since otherwise it would be recorded as a curvnet recursion when ng_eiface's ifnet resides in the same (parent) vnet as its netgraph node. PR: 274028 Reported by: Dancho Penev <dpslavov@hotmail.com> MFC after: 1 week sys/netgraph/ng_eiface.c | 2 ++ 1 file changed, 2 insertions(+)
Hi Marko, Thank you for your swift response. When I was thinking how to fix my problem I also considered your solution but went with more limited change instead of global one because: a) I'm not expert here and it's silly to make broad changes in such situation b) I would create hidden security catch: when someone moves interface into new VNET he/she expects outbound packets to be processed in this new VNET, instead behind the scene the VNET is replaced That's why I thought that it's better to leave the global solution to more knowledgeable person, which definitely you are.
^Triage: assign to the resolving committer.
^Triage: set flag for possible MFC to 13.