summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2015-06-08 13:44:09 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2015-06-08 13:44:09 +0000
commitb49c17a11ecba7f4834182882d1a9f424c912f65 (patch)
treed05e293e0a6275203f1f4bf9968ef03c1deef954
parent1312915bfb7e97794655d1302d1dba05889baec2 (diff)
Merge multiple copies of the code doing VLAN tag insertion back into
vlan_start(). ok sthen@, phessler@
-rw-r--r--sys/net/if_bridge.c46
-rw-r--r--sys/net/if_ethersubr.c82
-rw-r--r--sys/net/if_vlan.c107
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)
{
@@ -2680,45 +2675,6 @@ bridge_ifenqueue(struct bridge_softc *sc, struct ifnet *ifp, struct mbuf *m)
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;
error = if_output(ifp, m);
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 <license@ipv6.nrl.navy.mil>.
#include <net/if_bridge.h>
#endif
-#include "vlan.h"
-#if NVLAN > 0
-#include <net/if_vlan_var.h>
-#endif /* NVLAN > 0 */
-
#include "pppoe.h"
#if NPPPOE > 0
#include <net/if_pppoe.h>
@@ -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 <sys/param.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
@@ -59,11 +56,6 @@
#include <sys/sockio.h>
#include <sys/systm.h>
-#include "bpfilter.h"
-#if NBPFILTER > 0
-#include <net/bpf.h>
-#endif
-
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>
@@ -73,6 +65,16 @@
#include <net/if_vlan_var.h>
+#include "bpfilter.h"
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+
+#include "bridge.h"
+#if NBRIDGE > 0
+#include <net/if_bridge.h>
+#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++;