Module Name: src
Committed By: matt
Date: Tue May 24 17:16:43 UTC 2011
Modified Files:
src/sys/net: if_ethersubr.c
Log Message:
Add code to auto-deencapsulate 0 tagged VLANs.
To generate a diff of this commit:
cvs rdiff -u -r1.186 -r1.187 src/sys/net/if_ethersubr.c
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_ethersubr.c
diff -u src/sys/net/if_ethersubr.c:1.186 src/sys/net/if_ethersubr.c:1.187
--- src/sys/net/if_ethersubr.c:1.186 Mon Apr 25 22:14:45 2011
+++ src/sys/net/if_ethersubr.c Tue May 24 17:16:43 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ethersubr.c,v 1.186 2011/04/25 22:14:45 yamt Exp $ */
+/* $NetBSD: if_ethersubr.c,v 1.187 2011/05/24 17:16:43 matt Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.186 2011/04/25 22:14:45 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.187 2011/05/24 17:16:43 matt Exp $");
#include "opt_inet.h"
#include "opt_atalk.h"
@@ -115,9 +115,7 @@
#include <net/bpf.h>
#include <net/if_ether.h>
-#if NVLAN > 0
#include <net/if_vlanvar.h>
-#endif
#if NPPPOE > 0
#include <net/if_pppoe.h>
@@ -637,6 +635,7 @@
struct ifqueue *inq;
uint16_t etype;
struct ether_header *eh;
+ size_t ehlen;
#if defined (ISO) || defined (LLC) || defined(NETATALK)
struct llc *l;
#endif
@@ -651,6 +650,7 @@
#endif
eh = mtod(m, struct ether_header *);
etype = ntohs(eh->ether_type);
+ ehlen = sizeof(*eh);
/*
* Determine if the packet is within its size limits.
@@ -748,6 +748,7 @@
eh = mtod(m, struct ether_header *);
etype = ntohs(eh->ether_type);
+ ehlen = sizeof(*eh);
}
#endif
@@ -783,8 +784,23 @@
* (and possibly FCS) intact.
*/
switch (etype) {
+ case ETHERTYPE_VLAN: {
+ struct ether_vlan_header *evl = (void *)eh;
+ /*
+ * If there is a tag of 0, then the VLAN header was probably
+ * just being used to store the priority. Extract the ether
+ * type, and if IP or IPV6, let them deal with it.
+ */
+ if (m->m_len <= sizeof(*evl)
+ && EVL_VLANOFTAG(evl->evl_tag) == 0) {
+ etype = ntohs(evl->evl_proto);
+ ehlen = sizeof(*evl);
+ if ((m->m_flags & M_PROMISC) == 0
+ && (etype == ETHERTYPE_IP
+ || etype == ETHERTYPE_IPV6))
+ break;
+ }
#if NVLAN > 0
- case ETHERTYPE_VLAN:
/*
* vlan_input() will either recursively call ether_input()
* or drop the packet.
@@ -792,9 +808,10 @@
if (((struct ethercom *)ifp)->ec_nvlans != 0)
vlan_input(ifp, m);
else
+#endif /* NVLAN > 0 */
m_freem(m);
return;
-#endif /* NVLAN > 0 */
+ }
#if NPPPOE > 0
case ETHERTYPE_PPPOEDISC:
case ETHERTYPE_PPPOE:
@@ -872,7 +889,7 @@
if (etype > ETHERMTU + sizeof (struct ether_header)) {
/* Strip off the Ethernet header. */
- m_adj(m, sizeof(struct ether_header));
+ m_adj(m, ehlen);
switch (etype) {
#ifdef INET