summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2015-06-23 09:42:24 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2015-06-23 09:42:24 +0000
commit105ae6f314a0a8905afb0be0bc1d530fa1dd0657 (patch)
tree58453f7eecb1926c4a736752d876921b9a6c26c3 /sys
parentfa005873106ace803df5360e5fe94da5eb21183e (diff)
Adapt bridge(4) to the new if_input() framework.
Move bridge_input() outside of ether_input() in order to duplicate packets flowing through a bridge port before applying any transformation on mbufs. This saves a various m_adj(9)/M_PREPEND(9) dances and remove the bridge(4) hack from vlan(4). Tested by mxb <mxb AT alumni DOT chalmers DOT se> and kettenis@ ok bluhm@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if.c11
-rw-r--r--sys/net/if_bridge.c69
-rw-r--r--sys/net/if_bridge.h5
-rw-r--r--sys/net/if_ethersubr.c24
-rw-r--r--sys/net/if_vlan.c15
-rw-r--r--sys/netinet/ip_ether.c20
6 files changed, 37 insertions, 107 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index a9180400ba3..453c43e0a07 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.340 2015/06/16 11:09:39 mpi Exp $ */
+/* $OpenBSD: if.c,v 1.341 2015/06/23 09:42:23 mpi Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -530,6 +530,15 @@ if_input_process(void *xmq)
continue;
}
+#if NBRIDGE > 0
+ if (ifp->if_bridgeport && (m->m_flags & M_PROTO1) == 0) {
+ m = bridge_input(m);
+ if (m == NULL)
+ continue;
+ }
+ m->m_flags &= ~M_PROTO1; /* Loop prevention */
+#endif
+
/*
* Pass this mbuf to all input handlers of its
* interface until it is consumed.
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 15d77b216cc..9bf5fda2476 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.244 2015/06/16 11:09:39 mpi Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.245 2015/06/23 09:42:23 mpi Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -116,8 +116,6 @@ void bridge_broadcast(struct bridge_softc *, struct ifnet *,
void bridge_localbroadcast(struct bridge_softc *, struct ifnet *,
struct ether_header *, struct mbuf *);
void bridge_span(struct bridge_softc *, struct mbuf *);
-struct mbuf *bridge_dispatch(struct bridge_iflist *, struct ifnet *,
- struct mbuf *);
void bridge_stop(struct bridge_softc *);
void bridge_init(struct bridge_softc *);
int bridge_bifconf(struct bridge_softc *, struct ifbifconf *);
@@ -1198,7 +1196,7 @@ bridgeintr_frame(struct bridge_softc *sc, struct mbuf *m)
* If packet is unicast, destined for someone on "this"
* side of the bridge, drop it.
*/
- if ((m->m_flags & (M_BCAST | M_MCAST)) == 0) {
+ if (!ETHER_IS_MULTICAST(eh.ether_dhost)) {
if ((dst_p = bridge_rtlookup(sc, dst)) != NULL)
dst_if = dst_p->brt_if;
else
@@ -1207,8 +1205,14 @@ bridgeintr_frame(struct bridge_softc *sc, struct mbuf *m)
m_freem(m);
return;
}
- } else
+ } else {
+ if (memcmp(etherbroadcastaddr, eh.ether_dhost,
+ sizeof(etherbroadcastaddr)) == 0)
+ m->m_flags |= M_BCAST;
+ else
+ m->m_flags |= M_MCAST;
dst_if = NULL;
+ }
/*
* Multicast packets get handled a little differently:
@@ -1302,37 +1306,31 @@ bridgeintr_frame(struct bridge_softc *sc, struct mbuf *m)
* not for us, and schedule an interrupt.
*/
struct mbuf *
-bridge_input(struct ifnet *ifp, struct ether_header *eh0, struct mbuf *m)
+bridge_input(struct mbuf *m)
{
+ struct ifnet *ifp;
struct bridge_softc *sc;
struct bridge_iflist *ifl;
+ struct bridge_iflist *srcifl;
struct ether_header *eh;
-#if NVLAN > 0
- uint16_t etype = ntohs(eh0->ether_type);
-#endif /* NVLAN > 0 */
+ struct arpcom *ac;
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
+ struct mbuf *mc;
+ int s;
- /*
- * Make sure this interface is a bridge member.
- */
- if (ifp == NULL || ifp->if_bridgeport == NULL || m == NULL)
+ ifp = if_get(m->m_pkthdr.ph_ifidx);
+ KASSERT(ifp != NULL);
+ if (((ifp->if_flags & IFF_UP) == 0) || (ifp->if_bridgeport == NULL))
return (m);
if ((m->m_flags & M_PKTHDR) == 0)
panic("bridge_input(): no HDR");
- m->m_flags &= ~M_PROTO1; /* Loop prevention */
-
ifl = (struct bridge_iflist *)ifp->if_bridgeport;
sc = ifl->bridge_sc;
if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
return (m);
- M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
- if (m == NULL)
- return (NULL);
- eh = mtod(m, struct ether_header *);
- memmove(eh, eh0, sizeof(*eh));
-
#if NBPFILTER > 0
if (sc->sc_if.if_bpf)
bpf_mtap_ether(sc->sc_if.if_bpf, m, BPF_DIRECTION_IN);
@@ -1340,35 +1338,8 @@ bridge_input(struct ifnet *ifp, struct ether_header *eh0, struct mbuf *m)
bridge_span(sc, m);
- m = bridge_dispatch(ifl, ifp, m);
-
-#if NVLAN > 0
- if ((m != NULL) && ((m->m_flags & M_VLANTAG) ||
- etype == ETHERTYPE_VLAN || etype == ETHERTYPE_QINQ)) {
- /* The bridge did not want the vlan frame either, drop it. */
- ifp->if_noproto++;
- m_freem(m);
- m = NULL;
- }
-#endif /* NVLAN > 0 */
-
- return (m);
-}
-
-struct mbuf *
-bridge_dispatch(struct bridge_iflist *ifl, struct ifnet *ifp, struct mbuf *m)
-{
- struct bridge_softc *sc = ifl->bridge_sc;
- struct bridge_iflist *srcifl;
- struct ether_header *eh;
- struct arpcom *ac;
- struct mbuf_list ml = MBUF_LIST_INITIALIZER();
- struct mbuf *mc;
- int s;
-
eh = mtod(m, struct ether_header *);
-
- if (m->m_flags & (M_BCAST | M_MCAST)) {
+ if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
/*
* Reserved destination MAC addresses (01:80:C2:00:00:0x)
* should not be forwarded to bridge members according to
diff --git a/sys/net/if_bridge.h b/sys/net/if_bridge.h
index 6dbdb0dc0d9..3a373825295 100644
--- a/sys/net/if_bridge.h
+++ b/sys/net/if_bridge.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.h,v 1.42 2015/04/12 09:57:54 dlg Exp $ */
+/* $OpenBSD: if_bridge.h,v 1.43 2015/06/23 09:42:23 mpi Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -437,8 +437,7 @@ struct bridge_softc {
extern const u_int8_t bstp_etheraddr[];
void bridge_ifdetach(struct ifnet *);
-struct mbuf *bridge_input(struct ifnet *, struct ether_header *,
- struct mbuf *);
+struct mbuf *bridge_input(struct mbuf *);
int bridge_output(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *);
void bridge_update(struct ifnet *, struct ether_addr *, int);
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index c6ae0229045..94d7370a57f 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ethersubr.c,v 1.205 2015/06/16 11:09:39 mpi Exp $ */
+/* $OpenBSD: if_ethersubr.c,v 1.206 2015/06/23 09:42:23 mpi Exp $ */
/* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */
/*
@@ -379,28 +379,6 @@ ether_input(struct mbuf *m)
etype = ntohs(eh->ether_type);
-#if NBRIDGE > 0
- /*
- * Tap the packet off here for a bridge, if configured and
- * active for this interface. bridge_input returns
- * NULL if it has consumed the packet, otherwise, it
- * gets processed as normal.
- */
- if (ifp->if_bridgeport) {
- if (m->m_flags & M_PROTO1)
- m->m_flags &= ~M_PROTO1;
- else {
- m = bridge_input(ifp, eh, m);
- if (m == NULL)
- return (1);
- /* The bridge has determined it's for us. */
- ifp = if_get(m->m_pkthdr.ph_ifidx);
- KASSERT(ifp != NULL);
- m_adj(m, ETHER_HDR_LEN);
- }
- }
-#endif
-
ac = (struct arpcom *)ifp;
/*
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index 6371b96536b..8c359fde4e9 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_vlan.c,v 1.129 2015/06/16 11:09:39 mpi Exp $ */
+/* $OpenBSD: if_vlan.c,v 1.130 2015/06/23 09:42:23 mpi Exp $ */
/*
* Copyright 1998 Massachusetts Institute of Technology
@@ -70,11 +70,6 @@
#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
@@ -304,14 +299,6 @@ vlan_input(struct mbuf *m)
}
if (ifv == NULL) {
-#if NBRIDGE > 0
- /*
- * If the packet hasn't been through its bridge(4) give
- * it a chance.
- */
- if (ifp->if_bridgeport && (m->m_flags & M_PROTO1) == 0)
- return (0);
-#endif
ifp->if_noproto++;
m_freem(m);
return (1);
diff --git a/sys/netinet/ip_ether.c b/sys/netinet/ip_ether.c
index f581082c6a1..78bf0cbc083 100644
--- a/sys/netinet/ip_ether.c
+++ b/sys/netinet/ip_ether.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ether.c,v 1.72 2015/06/16 11:09:40 mpi Exp $ */
+/* $OpenBSD: ip_ether.c,v 1.73 2015/06/23 09:42:23 mpi Exp $ */
/*
* The author of this code is Angelos D. Keromytis (kermit@adk.gr)
*
@@ -162,7 +162,6 @@ etherip_input6(struct mbuf **m, int *offp, int proto)
void
etherip_decap(struct mbuf *m, int iphlen)
{
- struct ether_header eh;
struct etherip_header eip;
struct gif_softc *sc;
int s;
@@ -229,27 +228,14 @@ etherip_decap(struct mbuf *m, int iphlen)
/* Statistics */
etheripstat.etherip_ibytes += m->m_pkthdr.len;
- /* Copy ethernet header */
- m_copydata(m, 0, sizeof(eh), (void *) &eh);
-
/* Reset the flags based on the inner packet */
- m->m_flags &= ~(M_BCAST|M_MCAST|M_AUTH|M_CONF);
- if (eh.ether_dhost[0] & 1) {
- if (memcmp(etherbroadcastaddr, eh.ether_dhost,
- sizeof(etherbroadcastaddr)) == 0)
- m->m_flags |= M_BCAST;
- else
- m->m_flags |= M_MCAST;
- }
+ m->m_flags &= ~(M_BCAST|M_MCAST|M_AUTH|M_CONF|M_PROTO1);
#if NBPFILTER > 0
if (sc->gif_if.if_bpf)
bpf_mtap_af(sc->gif_if.if_bpf, AF_LINK, m, BPF_DIRECTION_IN);
#endif
- /* Trim the beginning of the mbuf, to remove the ethernet header. */
- m_adj(m, sizeof(struct ether_header));
-
/*
* Tap the packet off here for a bridge. bridge_input() returns
* NULL if it has consumed the packet. In the case of gif's,
@@ -264,7 +250,7 @@ etherip_decap(struct mbuf *m, int iphlen)
sc->gif_if.if_imcasts++;
s = splnet();
- m = bridge_input(&sc->gif_if, &eh, m);
+ m = bridge_input(m);
splx(s);
if (m == NULL)
return;