diff options
author | 2019-01-29 17:47:35 +0000 | |
---|---|---|
committer | 2019-01-29 17:47:35 +0000 | |
commit | 41b46478563d3002e1a8322e7d953bf1f41e0c79 (patch) | |
tree | 448afbb4597cfa32270c59106ebd131c3e5b56b4 | |
parent | Rename 1-letter variables to be coherent with others futex(2) based (diff) | |
download | wireguard-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.c | 53 | ||||
-rw-r--r-- | sys/net/if_bridge.h | 3 |
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 |