Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/net Handling frames that vlan id is 0 as non-VLAN frames
details: https://anonhg.NetBSD.org/src/rev/bb506c6bce0b
branches: trunk
changeset: 367257:bb506c6bce0b
user: yamaguchi <yamaguchi%NetBSD.org@localhost>
date: Mon Jun 20 08:02:25 2022 +0000
description:
Handling frames that vlan id is 0 as non-VLAN frames
even if a vlan tag is stripped by harware offloading
diffstat:
sys/net/agr/if_agr.c | 14 +++--
sys/net/if.h | 5 +-
sys/net/if_ethersubr.c | 114 ++++++++++++++++++++++++------------------------
sys/net/if_vlan.c | 25 +++++-----
sys/net/if_vlanvar.h | 4 +-
5 files changed, 83 insertions(+), 79 deletions(-)
diffs (truncated from 316 to 300 lines):
diff -r 4b3f481e184d -r bb506c6bce0b sys/net/agr/if_agr.c
--- a/sys/net/agr/if_agr.c Sun Jun 19 18:51:06 2022 +0000
+++ b/sys/net/agr/if_agr.c Mon Jun 20 08:02:25 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_agr.c,v 1.54 2021/12/31 14:25:24 riastradh Exp $ */
+/* $NetBSD: if_agr.c,v 1.55 2022/06/20 08:02:25 yamaguchi Exp $ */
/*-
* Copyright (c)2005 YAMAMOTO Takashi,
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_agr.c,v 1.54 2021/12/31 14:25:24 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_agr.c,v 1.55 2022/06/20 08:02:25 yamaguchi Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -167,10 +167,12 @@
* see if the device performed the decapsulation and
* provided us with the tag.
*/
- if (ec->ec_nvlans && vlan_has_tag(m)) {
- MODULE_HOOK_CALL_VOID(if_vlan_vlan_input_hook, (ifp, m),
- m_freem(m));
- return;
+ if (ec->ec_nvlans && vlan_has_tag(m) &&
+ EVL_VLANOFTAG(vlan_get_tag(m)) != 0) {
+ MODULE_HOOK_CALL(if_vlan_vlan_input_hook, (ifp, m),
+ m, m);
+ if (m == NULL)
+ return;
}
if_percpuq_enqueue(ifp->if_percpuq, m);
diff -r 4b3f481e184d -r bb506c6bce0b sys/net/if.h
--- a/sys/net/if.h Sun Jun 19 18:51:06 2022 +0000
+++ b/sys/net/if.h Mon Jun 20 08:02:25 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if.h,v 1.296 2021/12/31 14:24:26 riastradh Exp $ */
+/* $NetBSD: if.h,v 1.297 2022/06/20 08:02:25 yamaguchi Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -1409,7 +1409,8 @@
/*
* Hook for if_vlan - needed by if_agr
*/
-MODULE_HOOK(if_vlan_vlan_input_hook, void, (struct ifnet *, struct mbuf *));
+MODULE_HOOK(if_vlan_vlan_input_hook,
+ struct mbuf *, (struct ifnet *, struct mbuf *));
#endif /* _KERNEL */
diff -r 4b3f481e184d -r bb506c6bce0b sys/net/if_ethersubr.c
--- a/sys/net/if_ethersubr.c Sun Jun 19 18:51:06 2022 +0000
+++ b/sys/net/if_ethersubr.c Mon Jun 20 08:02:25 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ethersubr.c,v 1.311 2022/04/04 06:10:00 yamaguchi Exp $ */
+/* $NetBSD: if_ethersubr.c,v 1.312 2022/06/20 08:02:25 yamaguchi 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.311 2022/04/04 06:10:00 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.312 2022/06/20 08:02:25 yamaguchi Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -725,19 +725,6 @@
if_statadd(ifp, if_ibytes, m->m_pkthdr.len);
-#if NCARP > 0
- if (__predict_false(ifp->if_carp && ifp->if_type != IFT_CARP)) {
- /*
- * Clear M_PROMISC, in case the packet comes from a
- * vlan.
- */
- m->m_flags &= ~M_PROMISC;
- if (carp_input(m, (uint8_t *)&eh->ether_shost,
- (uint8_t *)&eh->ether_dhost, eh->ether_type) == 0)
- return;
- }
-#endif
-
if ((m->m_flags & (M_BCAST | M_MCAST | M_PROMISC)) == 0 &&
(ifp->if_flags & IFF_PROMISC) != 0 &&
memcmp(CLLADDR(ifp->if_sadl), eh->ether_dhost,
@@ -755,6 +742,10 @@
etype = ntohs(eh->ether_type);
}
+ /*
+ * Processing a logical interfaces that are able
+ * to configure vlan(4).
+ */
#if NAGR > 0
if (ifp->if_lagg != NULL &&
__predict_true(etype != ETHERTYPE_SLOWPROTOCOLS)) {
@@ -765,59 +756,68 @@
#endif
/*
- * If VLANs are configured on the interface, check to
- * see if the device performed the decapsulation and
- * provided us with the tag.
+ * VLAN processing.
+ *
+ * VLAN provides service delimiting so the frames are
+ * processed before other handlings. If a VLAN interface
+ * does not exist to take those frames, they're returned
+ * to ether_input().
*/
- if (ec->ec_nvlans && vlan_has_tag(m)) {
+ if (vlan_has_tag(m) || etype == ETHERTYPE_VLAN) {
+ struct ether_vlan_header *evl = (void *)eh;
+ uint16_t vlan_id;
+
+ if (vlan_has_tag(m)) {
+ vlan_id = EVL_VLANOFTAG(vlan_get_tag(m));
+ } else {
+ if (m->m_len < sizeof(*evl))
+ goto error;
+
+ vlan_id = EVL_VLANOFTAG(ntohs(evl->evl_tag));
+ etype = ntohs(evl->evl_proto);
+ ehlen = sizeof(*evl);
+ }
+
+ if (vlan_id == 0) {
+ if (etype == ETHERTYPE_VLAN ||
+ etype == ETHERTYPE_QINQ)
+ goto drop;
+
+ /* XXX we should actually use the prio value? */
+ m->m_flags &= ~M_VLANTAG;
+ } else {
#if NVLAN > 0
+ if (ec->ec_nvlans > 0) {
+ m = vlan_input(ifp, m);
+
+ /* vlan_input() called ether_input() recursively */
+ if (m == NULL)
+ return;
+ }
+#endif
+ /* drop VLAN frames not for this port. */
+ goto noproto;
+ }
+ }
+
+#if NCARP > 0
+ if (__predict_false(ifp->if_carp && ifp->if_type != IFT_CARP)) {
/*
- * vlan_input() will either recursively call ether_input()
- * or drop the packet.
+ * Clear M_PROMISC, in case the packet comes from a
+ * vlan.
*/
- vlan_input(ifp, m);
- return;
-#else
- goto noproto;
+ m->m_flags &= ~M_PROMISC;
+ if (carp_input(m, (uint8_t *)&eh->ether_shost,
+ (uint8_t *)&eh->ether_dhost, eh->ether_type) == 0)
+ return;
+ }
#endif
- }
/*
* Handle protocols that expect to have the Ethernet header
* (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(ntohs(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
- /*
- * vlan_input() will either recursively call ether_input()
- * or drop the packet.
- */
- if (ec->ec_nvlans != 0) {
- vlan_input(ifp, m);
- return;
- } else
-#endif
- goto noproto;
- }
-
#if NPPPOE > 0
case ETHERTYPE_PPPOEDISC:
pppoedisc_input(ifp, m);
diff -r 4b3f481e184d -r bb506c6bce0b sys/net/if_vlan.c
--- a/sys/net/if_vlan.c Sun Jun 19 18:51:06 2022 +0000
+++ b/sys/net/if_vlan.c Mon Jun 20 08:02:25 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_vlan.c,v 1.167 2021/12/24 04:50:40 yamaguchi Exp $ */
+/* $NetBSD: if_vlan.c,v 1.168 2022/06/20 08:02:25 yamaguchi 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.167 2021/12/24 04:50:40 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.168 2022/06/20 08:02:25 yamaguchi Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -204,12 +204,13 @@
static void vlan_hash_init(void);
static int vlan_hash_fini(void);
static int vlan_tag_hash(uint16_t, u_long);
-static struct ifvlan_linkmib* vlan_getref_linkmib(struct ifvlan *,
- struct psref *);
+static struct ifvlan_linkmib*
+ vlan_getref_linkmib(struct ifvlan *, struct psref *);
static void vlan_putref_linkmib(struct ifvlan_linkmib *, struct psref *);
static void vlan_linkmib_update(struct ifvlan *, struct ifvlan_linkmib *);
-static struct ifvlan_linkmib* vlan_lookup_tag_psref(struct ifnet *,
- uint16_t, struct psref *);
+static struct ifvlan_linkmib*
+ vlan_lookup_tag_psref(struct ifnet *, uint16_t,
+ struct psref *);
#if !defined(VLAN_TAG_HASH_SIZE)
#define VLAN_TAG_HASH_SIZE 32
@@ -1518,7 +1519,7 @@
* given source interface and tag, then run the real packet through the
* parent's input routine.
*/
-void
+struct mbuf *
vlan_input(struct ifnet *ifp, struct mbuf *m)
{
struct ifvlan *ifv;
@@ -1543,14 +1544,14 @@
sizeof(struct ether_vlan_header))) == NULL) {
printf("%s: no memory for VLAN header, "
"dropping packet.\n", ifp->if_xname);
- return;
+ return NULL;
}
if (m_makewritable(&m, 0,
sizeof(struct ether_vlan_header), M_DONTWAIT)) {
m_freem(m);
if_statinc(ifp, if_ierrors);
- return;
+ return NULL;
}
evl = mtod(m, struct ether_vlan_header *);
@@ -1566,11 +1567,10 @@
evl->evl_encap_proto = evl->evl_proto;
}
+ KASSERT(vid != 0);
mib = vlan_lookup_tag_psref(ifp, vid, &psref);
if (mib == NULL) {
- m_freem(m);
- if_statinc(ifp, if_noproto);
- return;
+ return m;
}
KASSERT(mib->ifvm_encaplen == ETHER_VLAN_ENCAP_LEN);
@@ -1621,6 +1621,7 @@
if_input(&ifv->ifv_if, m);
out:
vlan_putref_linkmib(mib, &psref);
+ return NULL;
}
/*
diff -r 4b3f481e184d -r bb506c6bce0b sys/net/if_vlanvar.h
--- a/sys/net/if_vlanvar.h Sun Jun 19 18:51:06 2022 +0000
Home |
Main Index |
Thread Index |
Old Index