summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2019-01-29 17:47:35 +0000
committermpi <mpi@openbsd.org>2019-01-29 17:47:35 +0000
commit41b46478563d3002e1a8322e7d953bf1f41e0c79 (patch)
tree448afbb4597cfa32270c59106ebd131c3e5b56b4
parentRename 1-letter variables to be coherent with others futex(2) based (diff)
downloadwireguard-openbsd-41b46478563d3002e1a8322e7d953bf1f41e0c79.tar.xz
wireguard-openbsd-41b46478563d3002e1a8322e7d953bf1f41e0c79.zip
Plumbing to simplify upcoming locking.
- Do checks that do not access shared data structures first, they don't need locking and save us some dances. - Use the common !ETHER_IS_MULTICAST() idiom and move some code that won't be executed if the bridge(4) is down. ok bluhm@, visa@
-rw-r--r--sys/net/if_bridge.c53
-rw-r--r--sys/net/if_bridge.h3
2 files changed, 29 insertions, 27 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 9232930fb51..f52ae79ee5e 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.318 2019/01/23 15:27:08 mpi Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.319 2019/01/29 17:47:35 mpi Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -732,10 +732,7 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
struct bridge_iflist *bif;
struct ether_header *eh;
struct ifnet *dst_if = NULL;
- struct bridge_rtnode *dst_p = NULL;
- struct ether_addr *dst;
struct bridge_softc *sc;
- struct bridge_tunneltag *brtag;
#if NBPFILTER > 0
caddr_t if_bpf;
#endif
@@ -743,27 +740,25 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
KERNEL_ASSERT_LOCKED();
+ if (m->m_len < sizeof(*eh)) {
+ m = m_pullup(m, sizeof(*eh));
+ if (m == NULL)
+ return (ENOBUFS);
+ }
+
/* ifp must be a member interface of the bridge. */
bif = (struct bridge_iflist *)ifp->if_bridgeport;
if (bif == NULL) {
m_freem(m);
return (EINVAL);
}
- sc = bif->bridge_sc;
-
- if (m->m_len < sizeof(*eh)) {
- m = m_pullup(m, sizeof(*eh));
- if (m == NULL)
- return (ENOBUFS);
- }
- eh = mtod(m, struct ether_header *);
- dst = (struct ether_addr *)&eh->ether_dhost[0];
/*
* If bridge is down, but original output interface is up,
* go ahead and send out that interface. Otherwise the packet
* is dropped below.
*/
+ sc = bif->bridge_sc;
if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
dst_if = ifp;
goto sendunicast;
@@ -779,13 +774,26 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
bridge_span(sc, m);
+ eh = mtod(m, struct ether_header *);
+ if (!ETHER_IS_MULTICAST(eh->ether_dhost)) {
+ struct bridge_rtnode *dst_p;
+ struct bridge_tunneltag *brtag;
+ struct ether_addr *dst;
+
+ dst = (struct ether_addr *)&eh->ether_dhost[0];
+ if ((dst_p = bridge_rtlookup(sc, dst)) != NULL) {
+ dst_if = dst_p->brt_if;
+ if ((dst_p->brt_family != AF_UNSPEC) &&
+ ((brtag = bridge_tunneltag(m)) != NULL))
+ bridge_copytag(&dst_p->brt_tunnel, brtag);
+ }
+ }
+
/*
* If the packet is a broadcast or we don't know a better way to
* get there, send to all interfaces.
*/
- if ((dst_p = bridge_rtlookup(sc, dst)) != NULL)
- dst_if = dst_p->brt_if;
- if (dst_if == NULL || ETHER_IS_MULTICAST(eh->ether_dhost)) {
+ if (dst_if == NULL) {
struct bridge_iflist *bif, *bif0;
struct mbuf *mc;
int used = 0;
@@ -845,11 +853,6 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
}
sendunicast:
- if ((dst_p != NULL) &&
- (dst_p->brt_tunnel.brtag_peer.sa.sa_family != AF_UNSPEC) &&
- ((brtag = bridge_tunneltag(m)) != NULL))
- bridge_copytag(&dst_p->brt_tunnel, brtag);
-
if ((dst_if->if_flags & IFF_RUNNING) == 0) {
m_freem(m);
return (ENETDOWN);
@@ -894,9 +897,8 @@ bridgeintr(void)
void
bridgeintr_frame(struct bridge_softc *sc, struct ifnet *src_if, struct mbuf *m)
{
- struct ifnet *dst_if;
+ struct ifnet *dst_if = NULL;
struct bridge_iflist *bif;
- struct bridge_rtnode *dst_p;
struct ether_addr *dst, *src;
struct ether_header eh;
u_int32_t protected;
@@ -944,10 +946,10 @@ bridgeintr_frame(struct bridge_softc *sc, struct ifnet *src_if, struct mbuf *m)
* side of the bridge, drop it.
*/
if (!ETHER_IS_MULTICAST(eh.ether_dhost)) {
+ struct bridge_rtnode *dst_p;
+
if ((dst_p = bridge_rtlookup(sc, dst)) != NULL)
dst_if = dst_p->brt_if;
- else
- dst_if = NULL;
if (dst_if == src_if) {
m_freem(m);
return;
@@ -958,7 +960,6 @@ bridgeintr_frame(struct bridge_softc *sc, struct ifnet *src_if, struct mbuf *m)
m->m_flags |= M_BCAST;
else
m->m_flags |= M_MCAST;
- dst_if = NULL;
}
/*
diff --git a/sys/net/if_bridge.h b/sys/net/if_bridge.h
index 431378988e6..e51ae587f3f 100644
--- a/sys/net/if_bridge.h
+++ b/sys/net/if_bridge.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.h,v 1.59 2019/01/17 16:07:42 mpi Exp $ */
+/* $OpenBSD: if_bridge.h,v 1.60 2019/01/29 17:47:35 mpi Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -456,6 +456,7 @@ struct bridge_rtnode {
struct ether_addr brt_addr; /* dst addr */
struct bridge_tunneltag brt_tunnel; /* tunnel endpoint */
};
+#define brt_family brt_tunnel.brtag_peer.sa.sa_family
#ifndef BRIDGE_RTABLE_SIZE
#define BRIDGE_RTABLE_SIZE 1024