Module Name: src Committed By: yamaguchi Date: Mon Jun 20 08:09:13 UTC 2022
Modified Files: src/sys/net: if_vlan.c Log Message: Determine the length of VLAN encapsulation by an interface type, and remove it from struct ifvlan_linkmib To generate a diff of this commit: cvs rdiff -u -r1.168 -r1.169 src/sys/net/if_vlan.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_vlan.c diff -u src/sys/net/if_vlan.c:1.168 src/sys/net/if_vlan.c:1.169 --- src/sys/net/if_vlan.c:1.168 Mon Jun 20 08:02:25 2022 +++ src/sys/net/if_vlan.c Mon Jun 20 08:09:13 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: if_vlan.c,v 1.168 2022/06/20 08:02:25 yamaguchi Exp $ */ +/* $NetBSD: if_vlan.c,v 1.169 2022/06/20 08:09:13 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.168 2022/06/20 08:02:25 yamaguchi Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.169 2022/06/20 08:09:13 yamaguchi Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -138,7 +138,6 @@ struct vlan_mc_entry { struct ifvlan_linkmib { struct ifvlan *ifvm_ifvlan; const struct vlan_multisw *ifvm_msw; - int ifvm_encaplen; /* encapsulation length */ int ifvm_mtufudge; /* MTU fudged by this much */ int ifvm_mintu; /* min transmission unit */ uint16_t ifvm_proto; /* encapsulation ethertype */ @@ -170,7 +169,6 @@ struct ifvlan { #define ifv_if ifv_ec.ec_if #define ifv_msw ifv_mib.ifvm_msw -#define ifv_encaplen ifv_mib.ifvm_encaplen #define ifv_mtufudge ifv_mib.ifvm_mtufudge #define ifv_mintu ifv_mib.ifvm_mintu #define ifv_tag ifv_mib.ifvm_tag @@ -437,7 +435,6 @@ vlan_config(struct ifvlan *ifv, struct i struct ethercom *ec = (void *)p; nmib->ifvm_msw = &vlan_ether_multisw; - nmib->ifvm_encaplen = ETHER_VLAN_ENCAP_LEN; nmib->ifvm_mintu = ETHERMIN; error = ether_add_vlantag(p, tag, NULL); @@ -454,7 +451,7 @@ vlan_config(struct ifvlan *ifv, struct i * the feature with other NetBSD * implementations, which might still be useful. */ - nmib->ifvm_mtufudge = nmib->ifvm_encaplen; + nmib->ifvm_mtufudge = ETHER_VLAN_ENCAP_LEN; } /* @@ -1281,19 +1278,19 @@ vlan_start(struct ifnet *ifp) /* * insert the tag ourselves */ - M_PREPEND(m, mib->ifvm_encaplen, M_DONTWAIT); - if (m == NULL) { - printf("%s: unable to prepend encap header", - p->if_xname); - if_statinc(ifp, if_oerrors); - continue; - } switch (p->if_type) { case IFT_ETHER: { struct ether_vlan_header *evl; + M_PREPEND(m, ETHER_VLAN_ENCAP_LEN, M_DONTWAIT); + if (m == NULL) { + printf("%s: unable to prepend encap header", + p->if_xname); + if_statinc(ifp, if_oerrors); + continue; + } if (m->m_len < sizeof(struct ether_vlan_header)) m = m_pullup(m, sizeof(struct ether_vlan_header)); @@ -1309,7 +1306,7 @@ vlan_start(struct ifnet *ifp) * Ethernet header with 802.1Q encapsulation. */ memmove(mtod(m, void *), - mtod(m, char *) + mib->ifvm_encaplen, + mtod(m, char *) + ETHER_VLAN_ENCAP_LEN, sizeof(struct ether_header)); evl = mtod(m, struct ether_vlan_header *); evl->evl_proto = evl->evl_encap_proto; @@ -1425,20 +1422,19 @@ vlan_transmit(struct ifnet *ifp, struct /* * insert the tag ourselves */ - M_PREPEND(m, mib->ifvm_encaplen, M_DONTWAIT); - if (m == NULL) { - printf("%s: unable to prepend encap header", - p->if_xname); - if_statinc(ifp, if_oerrors); - error = ENOBUFS; - goto out; - } - switch (p->if_type) { case IFT_ETHER: { struct ether_vlan_header *evl; + M_PREPEND(m, ETHER_VLAN_ENCAP_LEN, M_DONTWAIT); + if (m == NULL) { + printf("%s: unable to prepend encap header", + p->if_xname); + if_statinc(ifp, if_oerrors); + error = ENOBUFS; + goto out; + } if (m->m_len < sizeof(struct ether_vlan_header)) m = m_pullup(m, sizeof(struct ether_vlan_header)); @@ -1455,7 +1451,7 @@ vlan_transmit(struct ifnet *ifp, struct * Ethernet header with 802.1Q encapsulation. */ memmove(mtod(m, void *), - mtod(m, char *) + mib->ifvm_encaplen, + mtod(m, char *) + ETHER_VLAN_ENCAP_LEN, sizeof(struct ether_header)); evl = mtod(m, struct ether_vlan_header *); evl->evl_proto = evl->evl_encap_proto; @@ -1526,12 +1522,9 @@ vlan_input(struct ifnet *ifp, struct mbu uint16_t vid; struct ifvlan_linkmib *mib; struct psref psref; - bool have_vtag; - have_vtag = vlan_has_tag(m); - if (have_vtag) { + if (vlan_has_tag(m)) { vid = EVL_VLANOFTAG(vlan_get_tag(m)); - m->m_flags &= ~M_VLANTAG; } else { struct ether_vlan_header *evl; @@ -1558,6 +1551,7 @@ vlan_input(struct ifnet *ifp, struct mbu KASSERT(ntohs(evl->evl_encap_proto) == ETHERTYPE_VLAN); vid = EVL_VLANOFTAG(ntohs(evl->evl_tag)); + vlan_set_tag(m, ntohs(evl->evl_tag)); /* * Restore the original ethertype. We'll remove @@ -1565,6 +1559,14 @@ vlan_input(struct ifnet *ifp, struct mbu * interface corresponding to the tag. */ evl->evl_encap_proto = evl->evl_proto; + + /* + * Remove the encapsulation header and append tag. + * The original header has already been fixed up above. + */ + memmove((char *)evl + ETHER_VLAN_ENCAP_LEN, evl, + offsetof(struct ether_vlan_header, evl_encap_proto)); + m_adj(m, ETHER_VLAN_ENCAP_LEN); } KASSERT(vid != 0); @@ -1572,7 +1574,6 @@ vlan_input(struct ifnet *ifp, struct mbu if (mib == NULL) { return m; } - KASSERT(mib->ifvm_encaplen == ETHER_VLAN_ENCAP_LEN); ifv = mib->ifvm_ifvlan; if ((ifv->ifv_if.if_flags & (IFF_UP | IFF_RUNNING)) != @@ -1583,14 +1584,11 @@ vlan_input(struct ifnet *ifp, struct mbu } /* - * Now, remove the encapsulation header. The original - * header has already been fixed up above. + * Having found a valid vlan interface corresponding to + * the given source interface and vlan tag. + * remove the vlan tag. */ - if (!have_vtag) { - memmove(mtod(m, char *) + mib->ifvm_encaplen, - mtod(m, void *), sizeof(struct ether_header)); - m_adj(m, mib->ifvm_encaplen); - } + m->m_flags &= ~M_VLANTAG; /* * Drop promiscuously received packets if we are not in