From c2fe9baf0158777b1a36c86a630b3ea2341fe7a6 Mon Sep 17 00:00:00 2001 From: mpi Date: Mon, 8 Jun 2015 13:44:08 +0000 Subject: [PATCH] Merge multiple copies of the code doing VLAN tag insertion back into vlan_start(). ok sthen@, phessler@ --- sys/net/if_bridge.c | 46 +----------------- sys/net/if_ethersubr.c | 82 ++++--------------------------- sys/net/if_vlan.c | 107 ++++++++++++++++++----------------------- 3 files changed, 57 insertions(+), 178 deletions(-) diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 8e962441308..887ae427ad5 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bridge.c,v 1.240 2015/06/02 13:21:21 mpi Exp $ */ +/* $OpenBSD: if_bridge.c,v 1.241 2015/06/08 13:44:08 mpi Exp $ */ /* * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) @@ -2660,11 +2660,6 @@ bridge_fragment(struct bridge_softc *sc, struct ifnet *ifp, m_freem(m); } -#if NVLAN > 0 -extern int vlan_output(struct ifnet *, struct mbuf *, struct sockaddr *, - struct rtentry *); -#endif - int bridge_ifenqueue(struct bridge_softc *sc, struct ifnet *ifp, struct mbuf *m) { @@ -2679,45 +2674,6 @@ bridge_ifenqueue(struct bridge_softc *sc, struct ifnet *ifp, struct mbuf *m) ifp->if_ipackets++; ifp->if_ibytes += m->m_pkthdr.len; } -#endif -#if NVLAN > 0 - /* - * If the underlying interface cannot do VLAN tag insertion itself, - * create an encapsulation header. - */ - if (ifp->if_output == vlan_output) { - struct ifvlan *ifv = ifp->if_softc; - struct ifnet *p = ifv->ifv_p; - u_int8_t prio = m->m_pkthdr.pf.prio; - - /* IEEE 802.1p has prio 0 and 1 swapped */ - if (prio <= 1) - prio = !prio; - - /* should we use the tx tagging hw offload at all? */ - if ((p->if_capabilities & IFCAP_VLAN_HWTAGGING) && - (ifv->ifv_type == ETHERTYPE_VLAN)) { - m->m_pkthdr.ether_vtag = ifv->ifv_tag + - (prio << EVL_PRIO_BITS); - m->m_flags |= M_VLANTAG; - } else { - struct ether_vlan_header evh; - - m_copydata(m, 0, ETHER_HDR_LEN, (caddr_t)&evh); - evh.evl_proto = evh.evl_encap_proto; - evh.evl_encap_proto = htons(ifv->ifv_type); - evh.evl_tag = htons(ifv->ifv_tag + - (prio << EVL_PRIO_BITS)); - m_adj(m, ETHER_HDR_LEN); - M_PREPEND(m, sizeof(evh), M_DONTWAIT); - if (m == NULL) { - sc->sc_if.if_oerrors++; - return (ENOBUFS); - } - m_copyback(m, 0, sizeof(evh), &evh, M_NOWAIT); - m->m_flags &= ~M_VLANTAG; - } - } #endif len = m->m_pkthdr.len; diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 842dbe0c882..61b303b3ea5 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ethersubr.c,v 1.203 2015/06/08 13:40:48 mpi Exp $ */ +/* $OpenBSD: if_ethersubr.c,v 1.204 2015/06/08 13:44:08 mpi Exp $ */ /* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */ /* @@ -108,11 +108,6 @@ didn't get a copy, you may request one from . #include #endif -#include "vlan.h" -#if NVLAN > 0 -#include -#endif /* NVLAN > 0 */ - #include "pppoe.h" #if NPPPOE > 0 #include @@ -135,9 +130,6 @@ u_char etherbroadcastaddr[ETHER_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; #define senderr(e) { error = (e); goto bad;} -static inline int ether_addheader(struct mbuf **, struct ifnet *, - u_int16_t, u_char *, u_char *); - int ether_ioctl(struct ifnet *ifp, struct arpcom *arp, u_long cmd, caddr_t data) { @@ -172,79 +164,18 @@ ether_ioctl(struct ifnet *ifp, struct arpcom *arp, u_long cmd, caddr_t data) return (error); } -static inline int -ether_addheader(struct mbuf **m, struct ifnet *ifp, u_int16_t etype, - u_char *esrc, u_char *edst) -{ - struct ether_header *eh; - -#if NVLAN > 0 - if ((*m)->m_flags & M_VLANTAG) { - struct ifvlan *ifv = ifp->if_softc; - struct ifnet *p = ifv->ifv_p; - u_int8_t prio = (*m)->m_pkthdr.pf.prio; - - /* IEEE 802.1p has prio 0 and 1 swapped */ - if (prio <= 1) - prio = !prio; - -#if NBRIDGE > 0 - /* - * The bridge might send on non-vlan interfaces -- which - * do not need this header -- or add the vlan-header itself - * in bridge_ifenqueue -- which would add a second header. - */ - if (ifp->if_bridgeport) - (*m)->m_flags &= ~M_VLANTAG; - else -#endif - /* should we use the tx tagging hw offload at all? */ - if ((p->if_capabilities & IFCAP_VLAN_HWTAGGING) && - (ifv->ifv_type == ETHERTYPE_VLAN)) { - (*m)->m_pkthdr.ether_vtag = ifv->ifv_tag + - (prio << EVL_PRIO_BITS); - /* don't return, need to add regular ethernet header */ - } else { - struct ether_vlan_header *evh; - - M_PREPEND(*m, sizeof(*evh), M_DONTWAIT); - if (*m == NULL) - return (-1); - evh = mtod(*m, struct ether_vlan_header *); - memcpy(evh->evl_dhost, edst, sizeof(evh->evl_dhost)); - memcpy(evh->evl_shost, esrc, sizeof(evh->evl_shost)); - evh->evl_proto = etype; - evh->evl_encap_proto = htons(ifv->ifv_type); - evh->evl_tag = htons(ifv->ifv_tag + - (prio << EVL_PRIO_BITS)); - (*m)->m_flags &= ~M_VLANTAG; - return (0); - } - } -#endif /* NVLAN > 0 */ - M_PREPEND(*m, ETHER_HDR_LEN, M_DONTWAIT); - if (*m == NULL) - return (-1); - eh = mtod(*m, struct ether_header *); - eh->ether_type = etype; - memcpy(eh->ether_dhost, edst, sizeof(eh->ether_dhost)); - memcpy(eh->ether_shost, esrc, sizeof(eh->ether_shost)); - return (0); -} - /* * Ethernet output routine. * Encapsulate a packet of type family for the local net. * Assumes that ifp is actually pointer to arpcom structure. */ int -ether_output(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst, +ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct rtentry *rt) { u_int16_t etype; u_char edst[ETHER_ADDR_LEN]; u_char *esrc; - struct mbuf *m = m0; struct mbuf *mcopy = NULL; struct ether_header *eh; struct arpcom *ac = (struct arpcom *)ifp; @@ -338,8 +269,13 @@ ether_output(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst, if (mcopy) (void) looutput(ifp, mcopy, dst, rt); - if (ether_addheader(&m, ifp, etype, esrc, edst) == -1) - senderr(ENOBUFS); + M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT); + if (m == NULL) + return (ENOBUFS); + eh = mtod(m, struct ether_header *); + eh->ether_type = etype; + memcpy(eh->ether_dhost, edst, sizeof(eh->ether_dhost)); + memcpy(eh->ether_shost, esrc, sizeof(eh->ether_shost)); #if NBRIDGE > 0 /* diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index e3dd261e746..632ace29c6d 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vlan.c,v 1.127 2015/05/27 12:23:44 dlg Exp $ */ +/* $OpenBSD: if_vlan.c,v 1.128 2015/06/08 13:44:08 mpi Exp $ */ /* * Copyright 1998 Massachusetts Institute of Technology @@ -47,9 +47,6 @@ * will not modify the ethernet header. */ -#include "bridge.h" -#include "vlan.h" - #include #include #include @@ -59,11 +56,6 @@ #include #include -#include "bpfilter.h" -#if NBPFILTER > 0 -#include -#endif - #include #include #include @@ -73,6 +65,16 @@ #include +#include "bpfilter.h" +#if NBPFILTER > 0 +#include +#endif + +#include "bridge.h" +#if NBRIDGE > 0 +#include +#endif + u_long vlan_tagmask, svlan_tagmask; #define TAG_HASH_SIZE 32 @@ -81,8 +83,6 @@ LIST_HEAD(vlan_taghash, ifvlan) *vlan_tagh, *svlan_tagh; int vlan_input(struct mbuf *); -int vlan_output(struct ifnet *, struct mbuf *, struct sockaddr *, - struct rtentry *); void vlan_start(struct ifnet *ifp); int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr); int vlan_unconfig(struct ifnet *ifp, struct ifnet *newp); @@ -152,7 +152,6 @@ vlan_clone_create(struct if_clone *ifc, int unit) if_attach(ifp); ether_ifattach(ifp); ifp->if_hdrlen = EVL_ENCAPLEN; - ifp->if_output = vlan_output; return (0); } @@ -176,24 +175,13 @@ vlan_ifdetach(void *ptr) vlan_clone_destroy(&ifv->ifv_if); } -int -vlan_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, - struct rtentry *rt) -{ - /* - * we have to use a custom output function because ether_output - * can't figure out ifp is a vlan in a reasonable way - */ - m->m_flags |= M_VLANTAG; - return (ether_output(ifp, m, dst, rt)); -} - void vlan_start(struct ifnet *ifp) { - struct ifvlan *ifv; + struct ifvlan *ifv; struct ifnet *p; struct mbuf *m; + uint8_t prio; ifv = ifp->if_softc; p = ifv->ifv_p; @@ -203,6 +191,11 @@ vlan_start(struct ifnet *ifp) if (m == NULL) break; +#if NBPFILTER > 0 + if (ifp->if_bpf) + bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_OUT); +#endif /* NBPFILTER > 0 */ + if ((p->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) { IF_DROP(&p->if_snd); @@ -211,43 +204,37 @@ vlan_start(struct ifnet *ifp) continue; } -#if NBPFILTER > 0 - if (ifp->if_bpf) { - if ((p->if_capabilities & IFCAP_VLAN_HWTAGGING) && - (ifv->ifv_type == ETHERTYPE_VLAN)) - bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); - else { - struct mbuf *m0; - u_int off; - struct m_hdr mh; - struct { - uint8_t dst[ETHER_ADDR_LEN]; - uint8_t src[ETHER_ADDR_LEN]; - } hdr; - - /* copy the ether addresses off the front */ - m_copydata(m, 0, sizeof(hdr), (caddr_t)&hdr); - - /* find the ethertype after the vlan subhdr*/ - m0 = m_getptr(m, - offsetof(struct ether_vlan_header, - evl_proto), &off); - KASSERT(m0 != NULL); - - /* pretend the vlan subhdr isnt there */ - mh.mh_flags = 0; - mh.mh_data = mtod(m0, caddr_t) + off; - mh.mh_len = m0->m_len - off; - mh.mh_next = m0->m_next; - - /* dst+src + ethertype == ethernet header */ - bpf_mtap_hdr(ifp->if_bpf, - (caddr_t)&hdr, sizeof(hdr), - (struct mbuf *)&mh, BPF_DIRECTION_OUT, - NULL); + /* IEEE 802.1p has prio 0 and 1 swapped */ + prio = m->m_pkthdr.pf.prio; + if (prio <= 1) + prio = !prio; + + /* + * If the underlying interface cannot do VLAN tag insertion + * itself, create an encapsulation header. + */ + if ((p->if_capabilities & IFCAP_VLAN_HWTAGGING) && + (ifv->ifv_type == ETHERTYPE_VLAN)) { + m->m_pkthdr.ether_vtag = ifv->ifv_tag + + (prio << EVL_PRIO_BITS); + m->m_flags |= M_VLANTAG; + } else { + struct ether_vlan_header evh; + + m_copydata(m, 0, ETHER_HDR_LEN, (caddr_t)&evh); + evh.evl_proto = evh.evl_encap_proto; + evh.evl_encap_proto = htons(ifv->ifv_type); + evh.evl_tag = htons(ifv->ifv_tag + + (prio << EVL_PRIO_BITS)); + m_adj(m, ETHER_HDR_LEN); + M_PREPEND(m, sizeof(evh), M_DONTWAIT); + if (m == NULL) { + ifp->if_oerrors++; + continue; } + m_copyback(m, 0, sizeof(evh), &evh, M_NOWAIT); + m->m_flags &= ~M_VLANTAG; } -#endif /* NBPFILTER > 0 */ if (if_output(p, m)) { ifp->if_oerrors++; -- 2.20.1