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];