Path: blob/main/emulators/virtualbox-ose/files/patch-src-VBox-HostDrivers-VBoxNetFlt-freebsd-VBoxNetFlt-freebsd.c
17359 views
--- src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c.orig 2021-01-07 15:41:28 UTC1+++ src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c2@@ -52,6 +52,7 @@3#include <net/if_dl.h>4#include <net/if_types.h>5#include <net/ethernet.h>6+#include <net/if_vlan_var.h>78#include <netgraph/ng_message.h>9#include <netgraph/netgraph.h>10@@ -73,6 +74,7 @@1112#define VBOXNETFLT_OS_SPECFIC 113#include "../VBoxNetFltInternal.h"14+#include "freebsd/the-freebsd-kernel.h"1516static int vboxnetflt_modevent(struct module *, int, void *);17static ng_constructor_t ng_vboxnetflt_constructor;18@@ -361,7 +363,14 @@ static int ng_vboxnetflt_rcvdata(hook_p hook, item_p i19{20if (mtag != NULL || !fActive)21{22+#if __FreeBSD_version >= 130004923+ struct epoch_tracker et;24+ NET_EPOCH_ENTER(et);25+#endif26ether_demux(ifp, m);27+#if __FreeBSD_version >= 130004928+ NET_EPOCH_EXIT(et);29+#endif30if (fActive)31vboxNetFltRelease(pThis, true /*fBusy*/);32VBOXCURVNET_RESTORE();33@@ -436,6 +445,8 @@ static void vboxNetFltFreeBSDinput(void *arg, int pend34struct ifnet *ifp = pThis->u.s.ifp;35unsigned int cSegs = 0;36bool fDropIt = false, fActive;37+ bool is_vl_tagged = false;38+ uint16_t vl_tag;39PINTNETSG pSG;4041VBOXCURVNET_SET(ifp->if_vnet);42@@ -448,6 +459,19 @@ static void vboxNetFltFreeBSDinput(void *arg, int pend43if (m == NULL)44break;4546+ /* Prepend a VLAN header for consumption by the virtual switch */47+ if (m->m_flags & M_VLANTAG) {48+ vl_tag = m->m_pkthdr.ether_vtag;49+ is_vl_tagged = true;50+51+ m = ether_vlanencap(m, m->m_pkthdr.ether_vtag);52+ if (m == NULL) {53+ printf("vboxflt: unable to prepend VLAN header\n");54+ break;55+ }56+ m->m_flags &= ~M_VLANTAG;57+ }58+59for (m0 = m; m0 != NULL; m0 = m0->m_next)60if (m0->m_len > 0)61cSegs++;62@@ -462,10 +486,39 @@ static void vboxNetFltFreeBSDinput(void *arg, int pend63vboxNetFltFreeBSDMBufToSG(pThis, m, pSG, cSegs, 0);64fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, NULL /* pvIf */, pSG, INTNETTRUNKDIR_WIRE);65RTMemTmpFree(pSG);66+67+ /* Restore the VLAN flags before re-injecting the packet */68+ if (is_vl_tagged && !fDropIt) {69+ struct ether_vlan_header *vl_hdr;70+71+ /* This shouldn't fail, as the header was just prepended */72+ if (m->m_len < sizeof(*vl_hdr) && (m = m_pullup(m, sizeof(*vl_hdr))) == NULL) {73+ printf("vboxflt: unable to pullup VLAN header\n");74+ m_freem(m);75+ break;76+ }77+78+ /* Copy the MAC dhost/shost over the 802.1q field */79+ vl_hdr = mtod(m, struct ether_vlan_header *);80+ bcopy((char *)vl_hdr, (char *)vl_hdr + ETHER_VLAN_ENCAP_LEN, ETHER_HDR_LEN - ETHER_TYPE_LEN);81+ m_adj(m, ETHER_VLAN_ENCAP_LEN);82+83+ m->m_pkthdr.ether_vtag = vl_tag;84+ m->m_flags |= M_VLANTAG;85+ }86+87if (fDropIt)88m_freem(m);89- else90+ else {91+#if __FreeBSD_version >= 130004992+ struct epoch_tracker et;93+ NET_EPOCH_ENTER(et);94+#endif95ether_demux(ifp, m);96+#if __FreeBSD_version >= 130004997+ NET_EPOCH_EXIT(et);98+#endif99+ }100}101vboxNetFltRelease(pThis, true /* fBusy */);102VBOXCURVNET_RESTORE();103@@ -521,6 +574,7 @@ static void vboxNetFltFreeBSDoutput(void *arg, int pen104*/105int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *pvIfData, PINTNETSG pSG, uint32_t fDst)106{107+ IPRT_FREEBSD_SAVE_EFL_AC();108NOREF(pvIfData);109110void (*input_f)(struct ifnet *, struct mbuf *);111@@ -537,10 +591,16 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *p112{113m = vboxNetFltFreeBSDSGMBufFromSG(pThis, pSG);114if (m == NULL)115+ {116+ IPRT_FREEBSD_RESTORE_EFL_AC();117return VERR_NO_MEMORY;118+ }119m = m_pullup(m, ETHER_HDR_LEN);120if (m == NULL)121+ {122+ IPRT_FREEBSD_RESTORE_EFL_AC();123return VERR_NO_MEMORY;124+ }125126m->m_flags |= M_PKTHDR;127ether_output_frame(ifp, m);128@@ -550,10 +610,16 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *p129{130m = vboxNetFltFreeBSDSGMBufFromSG(pThis, pSG);131if (m == NULL)132+ {133+ IPRT_FREEBSD_RESTORE_EFL_AC();134return VERR_NO_MEMORY;135+ }136m = m_pullup(m, ETHER_HDR_LEN);137if (m == NULL)138+ {139+ IPRT_FREEBSD_RESTORE_EFL_AC();140return VERR_NO_MEMORY;141+ }142/*143* Delivering packets to the host will be captured by the144* input hook. Tag the packet with a mbuf tag so that we145@@ -564,6 +630,7 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *p146if (mtag == NULL)147{148m_freem(m);149+ IPRT_FREEBSD_RESTORE_EFL_AC();150return VERR_NO_MEMORY;151}152153@@ -574,6 +641,7 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *p154ifp->if_input(ifp, m);155}156VBOXCURVNET_RESTORE();157+ IPRT_FREEBSD_RESTORE_EFL_AC();158return VINF_SUCCESS;159}160161@@ -586,6 +654,7 @@ static bool vboxNetFltFreeBsdIsPromiscuous(PVBOXNETFLT162163int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext)164{165+ IPRT_FREEBSD_SAVE_EFL_AC();166char nam[NG_NODESIZ];167struct ifnet *ifp;168node_p node;169@@ -594,7 +663,10 @@ int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, voi170NOREF(pvContext);171ifp = ifunit(pThis->szName);172if (ifp == NULL)173+ {174+ IPRT_FREEBSD_RESTORE_EFL_AC();175return VERR_INTNET_FLT_IF_NOT_FOUND;176+ }177178/* Create a new netgraph node for this instance */179if (ng_make_node_common(&ng_vboxnetflt_typestruct, &node) != 0)180@@ -638,12 +710,14 @@ int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, voi181vboxNetFltRelease(pThis, true /*fBusy*/);182}183VBOXCURVNET_RESTORE();184+ IPRT_FREEBSD_RESTORE_EFL_AC();185186return VINF_SUCCESS;187}188189bool vboxNetFltOsMaybeRediscovered(PVBOXNETFLTINS pThis)190{191+ IPRT_FREEBSD_SAVE_EFL_AC();192struct ifnet *ifp, *ifp0;193194ifp = ASMAtomicUoReadPtrT(&pThis->u.s.ifp, struct ifnet *);195@@ -660,6 +734,7 @@ bool vboxNetFltOsMaybeRediscovered(PVBOXNETFLTINS pThi196pThis->u.s.node = NULL;197}198VBOXCURVNET_RESTORE();199+ IPRT_FREEBSD_RESTORE_EFL_AC();200201if (ifp0 != NULL)202{203@@ -672,6 +747,7 @@ bool vboxNetFltOsMaybeRediscovered(PVBOXNETFLTINS pThi204205void vboxNetFltOsDeleteInstance(PVBOXNETFLTINS pThis)206{207+ IPRT_FREEBSD_SAVE_EFL_AC();208209taskqueue_drain(taskqueue_fast, &pThis->u.s.tskin);210taskqueue_drain(taskqueue_fast, &pThis->u.s.tskout);211@@ -684,6 +760,7 @@ void vboxNetFltOsDeleteInstance(PVBOXNETFLTINS pThis)212ng_rmnode_self(pThis->u.s.node);213VBOXCURVNET_RESTORE();214pThis->u.s.node = NULL;215+ IPRT_FREEBSD_RESTORE_EFL_AC();216}217218int vboxNetFltOsPreInitInstance(PVBOXNETFLTINS pThis)219@@ -697,6 +774,7 @@ int vboxNetFltOsPreInitInstance(PVBOXNETFLTINS pThis)220221void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)222{223+ IPRT_FREEBSD_SAVE_EFL_AC();224struct ifnet *ifp;225struct ifreq ifreq;226int error;227@@ -730,7 +808,10 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, b228NG_MKMESSAGE(msg, NGM_GENERIC_COOKIE, NGM_CONNECT,229sizeof(struct ngm_connect), M_NOWAIT);230if (msg == NULL)231+ {232+ IPRT_FREEBSD_RESTORE_EFL_AC();233return;234+ }235con = (struct ngm_connect *)msg->data;236snprintf(con->path, NG_PATHSIZ, "vboxnetflt_%s:", ifp->if_xname);237strlcpy(con->ourhook, "lower", NG_HOOKSIZ);238@@ -744,7 +825,10 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, b239NG_MKMESSAGE(msg, NGM_GENERIC_COOKIE, NGM_CONNECT,240sizeof(struct ngm_connect), M_NOWAIT);241if (msg == NULL)242+ {243+ IPRT_FREEBSD_RESTORE_EFL_AC();244return;245+ }246con = (struct ngm_connect *)msg->data;247snprintf(con->path, NG_PATHSIZ, "vboxnetflt_%s:",248ifp->if_xname);249@@ -767,7 +851,10 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, b250NG_MKMESSAGE(msg, NGM_GENERIC_COOKIE, NGM_RMHOOK,251sizeof(struct ngm_rmhook), M_NOWAIT);252if (msg == NULL)253+ {254+ IPRT_FREEBSD_RESTORE_EFL_AC();255return;256+ }257rm = (struct ngm_rmhook *)msg->data;258strlcpy(rm->ourhook, "input", NG_HOOKSIZ);259NG_SEND_MSG_PATH(error, node, msg, path, 0);260@@ -778,12 +865,16 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, b261NG_MKMESSAGE(msg, NGM_GENERIC_COOKIE, NGM_RMHOOK,262sizeof(struct ngm_rmhook), M_NOWAIT);263if (msg == NULL)264+ {265+ IPRT_FREEBSD_RESTORE_EFL_AC();266return;267+ }268rm = (struct ngm_rmhook *)msg->data;269strlcpy(rm->ourhook, "output", NG_HOOKSIZ);270NG_SEND_MSG_PATH(error, node, msg, path, 0);271}272VBOXCURVNET_RESTORE();273+ IPRT_FREEBSD_RESTORE_EFL_AC();274}275276int vboxNetFltOsDisconnectIt(PVBOXNETFLTINS pThis)277278279