From owner-freebsd-emulation@FreeBSD.ORG Sun May 26 16:24:01 2013 Return-Path: Delivered-To: freebsd-emulation@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 781F81F3 for ; Sun, 26 May 2013 16:24:01 +0000 (UTC) (envelope-from landonf@plausible.coop) Received: from web1.plausible.coop (web1.plausible.coop [173.45.236.101]) by mx1.freebsd.org (Postfix) with ESMTP id 4D5851AA for ; Sun, 26 May 2013 16:23:59 +0000 (UTC) Received: from smtp.office.plausible.coop (rrcs-50-74-162-238.nyc.biz.rr.com [50.74.162.238]) by web1.plausible.coop (Postfix) with ESMTP id C31F61E43A7 for ; Sun, 26 May 2013 09:18:11 -0700 (PDT) Received: by smtp.office.plausible.coop (Postfix, from userid 65534) id A1D0E3815C24; Sun, 26 May 2013 09:18:04 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail1.office.plausiblelabs.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED autolearn=ham version=3.3.1 Received: from [192.168.10.125] (unknown [184.152.74.159]) by smtp.office.plausible.coop (Postfix) with ESMTPSA id A661B3815C1C for ; Sun, 26 May 2013 09:17:58 -0700 (PDT) From: Landon Fuller Content-Type: multipart/mixed; boundary="Apple-Mail=_A25C6A19-0F06-4FEE-B1C0-CD2A395AF4BA" Message-Id: <2E7892C4-F9BD-41A3-9269-D9A24D0DB695@plausible.coop> Mime-Version: 1.0 (Mac OS X Mail 6.3 \(1503\)) Subject: Re: [PATCH] VLAN trunking support in VirtualBox vboxnetflt Date: Sun, 26 May 2013 12:17:56 -0400 References: <6BCC0BDE-C9FD-47F0-96AE-88F797EFB074@plausible.coop> To: freebsd-emulation@freebsd.org In-Reply-To: <6BCC0BDE-C9FD-47F0-96AE-88F797EFB074@plausible.coop> X-Mailer: Apple Mail (2.1503) X-BeenThere: freebsd-emulation@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Development of Emulators of other operating systems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 26 May 2013 16:24:01 -0000 --Apple-Mail=_A25C6A19-0F06-4FEE-B1C0-CD2A395AF4BA Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii Hello, This patch has been in the vbox kmod port for some time now, and I've = been running it without incident; however, I recently ran into a = configuration that the patch does not correctly handle: - A single host interface (eg, em0) bridged to a VM - VLANs also configured on the host interface (em0.vlan0, = em0.vlan1) The packet flow in this situation should be: - The ng filter is handed a packet from em0 - The filter re-adds the VLAN header to the top of the packet = and strips the M_VLANTAG flag - After passing to the virtual switch, the packet is re-injected = into the host via ether_demux(). - ether_demux() extracts the embedded VLAN tag and hands the = packet off to vlan_input_p(). As it turns out, ether_demux() does not handle frames with embedded VLAN = tags, and at this point, the packet is dropped, rather than being routed = to the host's VLAN handling: = http://lists.freebsd.org/pipermail/freebsd-net/2011-October/030201.html The result is as follows: - Packets received via the host interface are handled correctly. - Packets (including VLAN tagged packets) are passed to sub-VMs = correctly. - Packets that *should* be handled by vlan* sub-interfaces on = the host are never received by those interfaces as they're dropped in = ether_demux(). This worked in my existing configuration because the host and the VMs = actually use two different VLAN trunks (em0 and em1), and so em0 packets = being dropped after injection into the virtual switch does not affect = the host's handling of packets on em1. I've attached an updated patch that should resolve this issue; I'm = currently testing it locally on my home deployment and so far it is = working fine. The patch simply restores the VLAN flags and stripped = ethernet header after injecting the packet into the virtual ethernet = switch. With this change in place, ether_demux() correctly hands the = packet off to vlan_input_p(). Cheers, Landon --Apple-Mail=_A25C6A19-0F06-4FEE-B1C0-CD2A395AF4BA Content-Disposition: attachment; filename*0=patch-src-VBox-HostDrivers-VBoxNetFlt-freebsd-VBoxNetFlt-freebsd; filename*1=.c Content-Type: application/octet-stream; name="patch-src-VBox-HostDrivers-VBoxNetFlt-freebsd-VBoxNetFlt-freebsd.c" Content-Transfer-Encoding: 7bit --- ./src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c.orig 2013-04-12 06:38:11.000000000 -0400 +++ ./src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c 2013-05-25 20:14:52.152180452 -0400 @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -427,6 +428,8 @@ struct ifnet *ifp = pThis->u.s.ifp; unsigned int cSegs = 0; bool fDropIt = false, fActive; + bool is_vl_tagged = false; + uint16_t vl_tag; PINTNETSG pSG; VBOXCURVNET_SET(ifp->if_vnet); @@ -439,6 +442,19 @@ if (m == NULL) break; + /* Prepend a VLAN header for consumption by the virtual switch */ + if (m->m_flags & M_VLANTAG) { + vl_tag = m->m_pkthdr.ether_vtag; + is_vl_tagged = true; + + m = ether_vlanencap(m, m->m_pkthdr.ether_vtag); + if (m == NULL) { + printf("vboxflt: unable to prepend VLAN header\n"); + break; + } + m->m_flags &= ~M_VLANTAG; + } + for (m0 = m; m0 != NULL; m0 = m0->m_next) if (m0->m_len > 0) cSegs++; @@ -453,6 +469,27 @@ vboxNetFltFreeBSDMBufToSG(pThis, m, pSG, cSegs, 0); fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, NULL /* pvIf */, pSG, INTNETTRUNKDIR_WIRE); RTMemTmpFree(pSG); + + /* Restore the VLAN flags before re-injecting the packet */ + if (is_vl_tagged && !fDropIt) { + struct ether_vlan_header *vl_hdr; + + /* This shouldn't fail, as the header was just prepended */ + if (m->m_len < sizeof(*vl_hdr) && (m = m_pullup(m, sizeof(*vl_hdr))) == NULL) { + printf("vboxflt: unable to pullup VLAN header\n"); + m_freem(m); + break; + } + + /* Copy the MAC dhost/shost over the 802.1q field */ + vl_hdr = mtod(m, struct ether_vlan_header *); + bcopy((char *)vl_hdr, (char *)vl_hdr + ETHER_VLAN_ENCAP_LEN, ETHER_HDR_LEN - ETHER_TYPE_LEN); + m_adj(m, ETHER_VLAN_ENCAP_LEN); + + m->m_pkthdr.ether_vtag = vl_tag; + m->m_flags |= M_VLANTAG; + } + if (fDropIt) m_freem(m); else --Apple-Mail=_A25C6A19-0F06-4FEE-B1C0-CD2A395AF4BA Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii On Apr 13, 2012, at 2:51 PM, Landon J Fuller = wrote: > Howdy, >=20 > I was looking into trunking VLANs into a virtual machine via bridging, = and noted that transmit of 802.1q tagged packets worked from the guest = VM, but upon reception, the VLAN tag seemed to be stripped before the = packets hit the guest's interface. >=20 > Taking a look at the netgraph-based bridging implementation, it looks = like the VLAN tag is not being re-inserted at the head of the ethernet = frame prior to handing off the to VirtualBox, and VBox doesn't seem to = have an equivalent 'ether_vtag' field in its INTNETSG struct to handle = this. >=20 > Thus, to preserve the VLAN tag, I modified vboxNetFltFreeBSDMBufToSG() = to ether_vlanencap() to insert the VLAN tag before handing off to VBox. = With this in place, I was able to successfully trunk VLANs to a virtual = machine.=20 >=20 > Some caveats: > - If using virtio-kmod's if_vtnet, you must set vlanhwfilter (or = promisc) flags on the guest interface before virtualbox will pass the = VLAN tagged packets through. Otherwise, the VBox virtio-net device = implementation will filter out the incoming packets before handing them = to the VM hardware. > - VBox's em(4) host implementation does not appear to support = 'hardware' VLAN tagging, but it does declare it. If using a em(4) = virtualized NIC, you must set -vlanhwtag on the guest interface. >=20 > I welcome someone(s) with more experience than I eyeballing the (tiny) = attached patch. I'm also especially concerned as to whether this should = be considered supported functionality in VBox, or I'm just getting lucky = with the virtio-net code path. >=20 > Thanks, > Landon >=20 > = ______= _________________________________________ > freebsd-emulation@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-emulation > To unsubscribe, send any mail to = "freebsd-emulation-unsubscribe@freebsd.org" --Apple-Mail=_A25C6A19-0F06-4FEE-B1C0-CD2A395AF4BA--