Module Name: src Committed By: yamaguchi Date: Mon Jun 20 08:02:26 UTC 2022
Modified Files: src/sys/net: if.h if_ethersubr.c if_vlan.c if_vlanvar.h src/sys/net/agr: if_agr.c Log Message: Handling frames that vlan id is 0 as non-VLAN frames even if a vlan tag is stripped by harware offloading To generate a diff of this commit: cvs rdiff -u -r1.296 -r1.297 src/sys/net/if.h cvs rdiff -u -r1.311 -r1.312 src/sys/net/if_ethersubr.c cvs rdiff -u -r1.167 -r1.168 src/sys/net/if_vlan.c cvs rdiff -u -r1.16 -r1.17 src/sys/net/if_vlanvar.h cvs rdiff -u -r1.54 -r1.55 src/sys/net/agr/if_agr.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.h diff -u src/sys/net/if.h:1.296 src/sys/net/if.h:1.297 --- src/sys/net/if.h:1.296 Fri Dec 31 14:24:26 2021 +++ src/sys/net/if.h Mon Jun 20 08:02:25 2022 @@ -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 @@ int sysctl_ifq(int *name, u_int namelen, /* * 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 */ Index: src/sys/net/if_ethersubr.c diff -u src/sys/net/if_ethersubr.c:1.311 src/sys/net/if_ethersubr.c:1.312 --- src/sys/net/if_ethersubr.c:1.311 Mon Apr 4 06:10:00 2022 +++ src/sys/net/if_ethersubr.c Mon Jun 20 08:02:25 2022 @@ -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 @@ ether_input(struct ifnet *ifp, struct mb 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 @@ ether_input(struct ifnet *ifp, struct mb 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 @@ ether_input(struct ifnet *ifp, struct mb #endif /* - * If VLANs are configured on the interface, check to - * see if the device performed the decapsulation and - * provided us with the tag. - */ - if (ec->ec_nvlans && vlan_has_tag(m)) { -#if NVLAN > 0 - /* - * vlan_input() will either recursively call ether_input() - * or drop the packet. - */ - vlan_input(ifp, m); - return; -#else - goto noproto; -#endif - } - - /* - * Handle protocols that expect to have the Ethernet header - * (and possibly FCS) intact. + * 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(). */ - switch (etype) { - case ETHERTYPE_VLAN: { + if (vlan_has_tag(m) || etype == ETHERTYPE_VLAN) { struct ether_vlan_header *evl = (void *)eh; + uint16_t vlan_id; - /* - * 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) { + 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 ((m->m_flags & M_PROMISC) == 0 && - (etype == ETHERTYPE_IP || - etype == ETHERTYPE_IPV6)) - break; } + 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. */ - if (ec->ec_nvlans != 0) { - vlan_input(ifp, m); + m->m_flags &= ~M_PROMISC; + if (carp_input(m, (uint8_t *)&eh->ether_shost, + (uint8_t *)&eh->ether_dhost, eh->ether_type) == 0) return; - } else -#endif - goto noproto; } +#endif + /* + * Handle protocols that expect to have the Ethernet header + * (and possibly FCS) intact. + */ + switch (etype) { #if NPPPOE > 0 case ETHERTYPE_PPPOEDISC: pppoedisc_input(ifp, m); Index: src/sys/net/if_vlan.c diff -u src/sys/net/if_vlan.c:1.167 src/sys/net/if_vlan.c:1.168 --- src/sys/net/if_vlan.c:1.167 Fri Dec 24 04:50:40 2021 +++ src/sys/net/if_vlan.c Mon Jun 20 08:02:25 2022 @@ -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 int vlan_unconfig_locked(struct i 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 @@ out: * 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 @@ vlan_input(struct ifnet *ifp, struct mbu 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 @@ vlan_input(struct ifnet *ifp, struct mbu 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 @@ vlan_input(struct ifnet *ifp, struct mbu if_input(&ifv->ifv_if, m); out: vlan_putref_linkmib(mib, &psref); + return NULL; } /* Index: src/sys/net/if_vlanvar.h diff -u src/sys/net/if_vlanvar.h:1.16 src/sys/net/if_vlanvar.h:1.17 --- src/sys/net/if_vlanvar.h:1.16 Thu Sep 30 04:13:42 2021 +++ src/sys/net/if_vlanvar.h Mon Jun 20 08:02:25 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: if_vlanvar.h,v 1.16 2021/09/30 04:13:42 yamaguchi Exp $ */ +/* $NetBSD: if_vlanvar.h,v 1.17 2022/06/20 08:02:25 yamaguchi Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -81,7 +81,7 @@ struct vlanreq { #define SIOCGETVLAN SIOCGIFGENERIC #ifdef _KERNEL -void vlan_input(struct ifnet *, struct mbuf *); +struct mbuf * vlan_input(struct ifnet *, struct mbuf *); /* * Locking notes: Index: src/sys/net/agr/if_agr.c diff -u src/sys/net/agr/if_agr.c:1.54 src/sys/net/agr/if_agr.c:1.55 --- src/sys/net/agr/if_agr.c:1.54 Fri Dec 31 14:25:24 2021 +++ src/sys/net/agr/if_agr.c Mon Jun 20 08:02:25 2022 @@ -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 @@ agr_input(struct ifnet *ifp_port, struct * 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);