Module Name:    src
Committed By:   msaitoh
Date:           Wed Nov 22 02:35:25 UTC 2017

Modified Files:
        src/sys/net: if_ether.h if_vlan.c if_vlanvar.h

Log Message:
 Fix a bug that a vlan packet which has priority or CFI bit in the tag causes
panic.


To generate a diff of this commit:
cvs rdiff -u -r1.68 -r1.69 src/sys/net/if_ether.h
cvs rdiff -u -r1.107 -r1.108 src/sys/net/if_vlan.c
cvs rdiff -u -r1.10 -r1.11 src/sys/net/if_vlanvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/if_ether.h
diff -u src/sys/net/if_ether.h:1.68 src/sys/net/if_ether.h:1.69
--- src/sys/net/if_ether.h:1.68	Thu Sep 28 16:26:14 2017
+++ src/sys/net/if_ether.h	Wed Nov 22 02:35:24 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ether.h,v 1.68 2017/09/28 16:26:14 christos Exp $	*/
+/*	$NetBSD: if_ether.h,v 1.69 2017/11/22 02:35:24 msaitoh Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1993
@@ -59,9 +59,11 @@
 /*
  * Some Ethernet extensions.
  */
-#define	ETHER_VLAN_ENCAP_LEN 4	/* length of 802.1Q VLAN encapsulation */
-#define	ETHER_VLAN_MASK	0xFFF	/* bits in a vlan tag */
-#define	ETHER_PPPOE_ENCAP_LEN 8	/* length of PPPoE encapsulation */
+#define	ETHER_VLAN_ENCAP_LEN	4      /* length of 802.1Q VLAN encapsulation */
+#define	EVL_VLANOFTAG(tag)	((tag) & 4095)		/* VLAN ID */
+#define	EVL_PRIOFTAG(tag)	(((tag) >> 13) & 7)	/* Priority */
+#define	EVL_CFIOFTAG(tag)	(((tag) >> 12) & 1)	/* CFI */
+#define	ETHER_PPPOE_ENCAP_LEN	8	/* length of PPPoE encapsulation */
 
 /*
  * Ethernet address - 6 octets
@@ -297,12 +299,12 @@ struct ether_multistep {
 
 /* add VLAN tag to input/received packet */
 static inline void
-vlan_set_tag(struct mbuf *m, u_int16_t vlanid)
+vlan_set_tag(struct mbuf *m, u_int16_t vlantag)
 {
 
-	KASSERT((vlanid & ~ETHER_VLAN_MASK) == 0);
+	/* VLAN tag contains priority, CFI and VLAN ID */
 
-	m->m_pkthdr.ether_vtag = vlanid;
+	m->m_pkthdr.ether_vtag = vlantag;
 	m->m_flags |= M_VLANTAG;
 	return;
 }

Index: src/sys/net/if_vlan.c
diff -u src/sys/net/if_vlan.c:1.107 src/sys/net/if_vlan.c:1.108
--- src/sys/net/if_vlan.c:1.107	Thu Nov 16 03:07:18 2017
+++ src/sys/net/if_vlan.c	Wed Nov 22 02:35:24 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_vlan.c,v 1.107 2017/11/16 03:07:18 ozaki-r Exp $	*/
+/*	$NetBSD: if_vlan.c,v 1.108 2017/11/22 02:35:24 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
@@ -78,7 +78,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.107 2017/11/16 03:07:18 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.108 2017/11/22 02:35:24 msaitoh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -399,6 +399,7 @@ vlan_config(struct ifvlan *ifv, struct i
 	struct ifvlan_linkmib *omib = NULL;
 	struct ifvlan_linkmib *checkmib = NULL;
 	struct psref_target *nmib_psref = NULL;
+	uint16_t vid = EVL_VLANOFTAG(tag);
 	int error = 0;
 	int idx;
 	bool omib_cleanup = false;
@@ -415,7 +416,7 @@ vlan_config(struct ifvlan *ifv, struct i
 	}
 
 	/* Duplicate check */
-	checkmib = vlan_lookup_tag_psref(p, tag, &psref);
+	checkmib = vlan_lookup_tag_psref(p, vid, &psref);
 	if (checkmib != NULL) {
 		vlan_putref_linkmib(checkmib, &psref);
 		error = EEXIST;
@@ -485,7 +486,7 @@ vlan_config(struct ifvlan *ifv, struct i
 	}
 
 	nmib->ifvm_p = p;
-	nmib->ifvm_tag = tag;
+	nmib->ifvm_tag = vid;
 	ifv->ifv_if.if_mtu = p->if_mtu - nmib->ifvm_mtufudge;
 	ifv->ifv_if.if_flags = p->if_flags &
 	    (IFF_UP | IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
@@ -497,7 +498,7 @@ vlan_config(struct ifvlan *ifv, struct i
 	ifv->ifv_if.if_type = p->if_type;
 
 	PSLIST_ENTRY_INIT(ifv, ifv_hash);
-	idx = tag_hash_func(tag, ifv_hash.mask);
+	idx = tag_hash_func(vid, ifv_hash.mask);
 
 	mutex_enter(&ifv_hash.lock);
 	PSLIST_WRITER_INSERT_HEAD(&ifv_hash.lists[idx], ifv, ifv_hash);
@@ -1476,14 +1477,14 @@ void
 vlan_input(struct ifnet *ifp, struct mbuf *m)
 {
 	struct ifvlan *ifv;
-	u_int tag;
+	uint16_t vid;
 	struct ifvlan_linkmib *mib;
 	struct psref psref;
 	bool have_vtag;
 
 	have_vtag = vlan_has_tag(m);
 	if (have_vtag) {
-		tag = EVL_VLANOFTAG(vlan_get_tag(m));
+		vid = EVL_VLANOFTAG(vlan_get_tag(m));
 		m->m_flags &= ~M_VLANTAG;
 	} else {
 		switch (ifp->if_type) {
@@ -1501,7 +1502,7 @@ vlan_input(struct ifnet *ifp, struct mbu
 			evl = mtod(m, struct ether_vlan_header *);
 			KASSERT(ntohs(evl->evl_encap_proto) == ETHERTYPE_VLAN);
 
-			tag = EVL_VLANOFTAG(ntohs(evl->evl_tag));
+			vid = EVL_VLANOFTAG(ntohs(evl->evl_tag));
 
 			/*
 			 * Restore the original ethertype.  We'll remove
@@ -1513,14 +1514,14 @@ vlan_input(struct ifnet *ifp, struct mbu
 		    }
 
 		default:
-			tag = (u_int) -1;	/* XXX GCC */
+			vid = (uint16_t) -1;	/* XXX GCC */
 #ifdef DIAGNOSTIC
 			panic("vlan_input: impossible");
 #endif
 		}
 	}
 
-	mib = vlan_lookup_tag_psref(ifp, tag, &psref);
+	mib = vlan_lookup_tag_psref(ifp, vid, &psref);
 	if (mib == NULL) {
 		m_freem(m);
 		ifp->if_noproto++;

Index: src/sys/net/if_vlanvar.h
diff -u src/sys/net/if_vlanvar.h:1.10 src/sys/net/if_vlanvar.h:1.11
--- src/sys/net/if_vlanvar.h:1.10	Wed Jun  7 03:53:11 2017
+++ src/sys/net/if_vlanvar.h	Wed Nov 22 02:35:24 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_vlanvar.h,v 1.10 2017/06/07 03:53:11 knakahara Exp $	*/
+/*	$NetBSD: if_vlanvar.h,v 1.11 2017/11/22 02:35:24 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -71,9 +71,6 @@ struct ether_vlan_header {
 	uint16_t	evl_proto;
 } __packed;
 
-#define	EVL_VLANOFTAG(tag)	((tag) & 4095)
-#define	EVL_PRIOFTAG(tag)	(((tag) >> 13) & 7)
-
 /* Configuration structure for SIOCSETVLAN and SIOCGETVLAN ioctls. */
 struct vlanreq {
 	char	vlr_parent[IFNAMSIZ];

Reply via email to