Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Feb 2000 20:53:09 -0500 (EST)
From:      "Matthew N. Dodd" <winter@jurai.net>
To:        Jasper Wallace <jasper@ivision.co.uk>
Cc:        Mike Nowlin <mike@argos.org>, freebsd-net@FreeBSD.ORG
Subject:   Re: 802.1Q VLANs
Message-ID:  <Pine.BSF.4.21.0002022049240.479-200000@sasami.jurai.net>
In-Reply-To: <Pine.GSO.4.21.0002022029090.248-100000@avengers.ivision.co.uk>

index | next in thread | previous in thread | raw e-mail

[-- Attachment #1 --]
On Wed, 2 Feb 2000, Jasper Wallace wrote:
> oh well, with the vlan code in -stable i could ping, but tcp or udp packets
> would eventually panic the machine, it's fine with the patches from the
> above url.

Ok, I've reviewed the patches (crap) and fixed the problem (easy).

I'm not terribly happy with how the double queuing ends up working but its
much better than polluting sys/net/if_ethersubr.c with all sorts of VLAN
defines.

The correct solution will be to write a vlan_output() routine that does
the right thing so we can place packets right on the parent interface's
queue instead of calling ether_output twice.  I'm not inclined to do this
so close to release so the brief patch will have to do.

Patch follows:

Index: if_vlan.c
===================================================================
RCS file: /cvs/src/sys/net/if_vlan.c,v
retrieving revision 1.13
diff -u -1 -2 -r1.13 if_vlan.c
--- if_vlan.c	2000/01/29 16:56:24	1.13
+++ if_vlan.c	2000/02/02 22:36:55
@@ -184,25 +184,25 @@
 static void
 vlan_ifinit(void *foo)
 {
 	return;
 }
 
 static void
 vlan_start(struct ifnet *ifp)
 {
 	struct ifvlan *ifv;
 	struct ifnet *p;
 	struct ether_vlan_header *evl;
-	struct mbuf *m;
+	struct mbuf *m, *m0;
 
 	ifv = ifp->if_softc;
 	p = ifv->ifv_p;
 
 	ifp->if_flags |= IFF_OACTIVE;
 	for (;;) {
 		IF_DEQUEUE(&ifp->if_snd, m);
 		if (m == 0)
 			break;
 		if (ifp->if_bpf)
 			bpf_mtap(ifp, m);
 
@@ -220,27 +220,39 @@
 		 * valid. We need to do this because sometimes mbufs will
 		 * be allocated by other parts of the system that contain
 		 * garbage in the rcvif pointer. Using the M_PROTO1 flag
 		 * lets the driver perform a proper sanity check and avoid
 		 * following potentially bogus rcvif pointers off into
 		 * never-never land.
 		 */
 		if (ifp->if_flags & IFF_LINK0) {
 			m->m_pkthdr.rcvif = ifp;
 			m->m_flags |= M_PROTO1;
 		} else {
 			M_PREPEND(m, EVL_ENCAPLEN, M_DONTWAIT);
-			if (m == 0)
+			if (m == NULL) {
+				printf("vlan%d: M_PREPEND failed", ifp->if_unit );
+				ifp->if_ierrors++;
 				continue;
+			}
 			/* M_PREPEND takes care of m_len, m_pkthdr.len for us */
+
+			m0 = m_pullup(m, ETHER_HDR_LEN + EVL_ENCAPLEN);
+			if (m0 == NULL) {
+				printf("vlan%d: m_pullup failed", ifp->if_unit );
+				ifp->if_ierrors++;
+				m_freem(m);
+				continue;
+			}
+			m = m0;
 
 			/*
 			 * Transform the Ethernet header into an Ethernet header
 			 * with 802.1Q encapsulation.
 			 */
 			bcopy(mtod(m, char *) + EVL_ENCAPLEN, mtod(m, char *),
 			      sizeof(struct ether_header));
 			evl = mtod(m, struct ether_vlan_header *);
 			evl->evl_proto = evl->evl_encap_proto;
 			evl->evl_encap_proto = htons(vlan_proto);
 			evl->evl_tag = htons(ifv->ifv_tag);
 #ifdef DEBUG

-- 
| Matthew N. Dodd  | '78 Datsun 280Z | '75 Volvo 164E | FreeBSD/NetBSD  |
| winter@jurai.net |       2 x '84 Volvo 245DL        | ix86,sparc,pmax |
| http://www.jurai.net/~winter | This Space For Rent  | ISO8802.5 4ever |

[-- Attachment #2 --]
Index: if_vlan.c
===================================================================
RCS file: /cvs/src/sys/net/if_vlan.c,v
retrieving revision 1.13
diff -u -1 -2 -r1.13 if_vlan.c
--- if_vlan.c	2000/01/29 16:56:24	1.13
+++ if_vlan.c	2000/02/02 22:36:55
@@ -184,25 +184,25 @@
 static void
 vlan_ifinit(void *foo)
 {
 	return;
 }
 
 static void
 vlan_start(struct ifnet *ifp)
 {
 	struct ifvlan *ifv;
 	struct ifnet *p;
 	struct ether_vlan_header *evl;
-	struct mbuf *m;
+	struct mbuf *m, *m0;
 
 	ifv = ifp->if_softc;
 	p = ifv->ifv_p;
 
 	ifp->if_flags |= IFF_OACTIVE;
 	for (;;) {
 		IF_DEQUEUE(&ifp->if_snd, m);
 		if (m == 0)
 			break;
 		if (ifp->if_bpf)
 			bpf_mtap(ifp, m);
 
@@ -220,27 +220,39 @@
 		 * valid. We need to do this because sometimes mbufs will
 		 * be allocated by other parts of the system that contain
 		 * garbage in the rcvif pointer. Using the M_PROTO1 flag
 		 * lets the driver perform a proper sanity check and avoid
 		 * following potentially bogus rcvif pointers off into
 		 * never-never land.
 		 */
 		if (ifp->if_flags & IFF_LINK0) {
 			m->m_pkthdr.rcvif = ifp;
 			m->m_flags |= M_PROTO1;
 		} else {
 			M_PREPEND(m, EVL_ENCAPLEN, M_DONTWAIT);
-			if (m == 0)
+			if (m == NULL) {
+				printf("vlan%d: M_PREPEND failed", ifp->if_unit );
+				ifp->if_ierrors++;
 				continue;
+			}
 			/* M_PREPEND takes care of m_len, m_pkthdr.len for us */
+
+			m0 = m_pullup(m, ETHER_HDR_LEN + EVL_ENCAPLEN);
+			if (m0 == NULL) {
+				printf("vlan%d: m_pullup failed", ifp->if_unit );
+				ifp->if_ierrors++;
+				m_freem(m);
+				continue;
+			}
+			m = m0;
 
 			/*
 			 * Transform the Ethernet header into an Ethernet header
 			 * with 802.1Q encapsulation.
 			 */
 			bcopy(mtod(m, char *) + EVL_ENCAPLEN, mtod(m, char *),
 			      sizeof(struct ether_header));
 			evl = mtod(m, struct ether_vlan_header *);
 			evl->evl_proto = evl->evl_encap_proto;
 			evl->evl_encap_proto = htons(vlan_proto);
 			evl->evl_tag = htons(ifv->ifv_tag);
 #ifdef DEBUG
help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0002022049240.479-200000>