Some plumbing to move the tag mechanism outside of net/if_bridge.c .

bridge_rtlookup() now returns an interface pointer and "bridge_rtnode"
are modified with the mutex held.

This will make locking in bridge_output() simpler.

Ok?

Index: net/bridgectl.c
===================================================================
RCS file: /cvs/src/sys/net/bridgectl.c,v
retrieving revision 1.16
diff -u -p -r1.16 bridgectl.c
--- net/bridgectl.c     20 Feb 2019 17:11:51 -0000      1.16
+++ net/bridgectl.c     22 Feb 2019 14:21:43 -0000
@@ -291,10 +291,11 @@ want:
        return (error);
 }
 
-struct bridge_rtnode *
-bridge_rtlookup(struct bridge_softc *sc, struct ether_addr *ea)
+struct ifnet *
+bridge_rtlookup(struct bridge_softc *sc, struct ether_addr *ea, struct mbuf *m)
 {
        struct bridge_rtnode *p = NULL;
+       struct ifnet *ifp = NULL;
        u_int32_t h;
        int dir;
 
@@ -309,9 +310,20 @@ bridge_rtlookup(struct bridge_softc *sc,
                        break;
                }
        }
+       if (p != NULL) {
+               ifp = p->brt_if;
+
+               if (p->brt_family != AF_UNSPEC && m != NULL) {
+                       struct bridge_tunneltag *brtag;
+
+                       brtag = bridge_tunneltag(m);
+                       if (brtag != NULL)
+                               bridge_copytag(&p->brt_tunnel, brtag);
+               }
+       }
        mtx_leave(&sc->sc_mtx);
 
-       return (p);
+       return (ifp);
 }
 
 u_int32_t
@@ -795,5 +807,64 @@ bridge_flushrule(struct bridge_iflist *b
                pf_tag_unref(p->brl_tag);
 #endif
                free(p, M_DEVBUF, sizeof *p);
+       }
+}
+
+struct bridge_tunneltag *
+bridge_tunnel(struct mbuf *m)
+{
+       struct m_tag    *mtag;
+
+       if ((mtag = m_tag_find(m, PACKET_TAG_TUNNEL, NULL)) == NULL)
+               return (NULL);
+
+       return ((struct bridge_tunneltag *)(mtag + 1));
+}
+
+struct bridge_tunneltag *
+bridge_tunneltag(struct mbuf *m)
+{
+       struct m_tag    *mtag;
+
+       if ((mtag = m_tag_find(m, PACKET_TAG_TUNNEL, NULL)) == NULL) {
+               mtag = m_tag_get(PACKET_TAG_TUNNEL,
+                   sizeof(struct bridge_tunneltag), M_NOWAIT);
+               if (mtag == NULL)
+                       return (NULL);
+               bzero(mtag + 1, sizeof(struct bridge_tunneltag));
+               m_tag_prepend(m, mtag);
+       }
+
+       return ((struct bridge_tunneltag *)(mtag + 1));
+}
+
+void
+bridge_tunneluntag(struct mbuf *m)
+{
+       struct m_tag    *mtag;
+       if ((mtag = m_tag_find(m, PACKET_TAG_TUNNEL, NULL)) != NULL)
+               m_tag_delete(m, mtag);
+}
+
+void
+bridge_copyaddr(struct sockaddr *src, struct sockaddr *dst)
+{
+       if (src != NULL && src->sa_family != AF_UNSPEC)
+               memcpy(dst, src, src->sa_len);
+       else {
+               dst->sa_family = AF_UNSPEC;
+               dst->sa_len = 0;
+       }
+}
+
+void
+bridge_copytag(struct bridge_tunneltag *src, struct bridge_tunneltag *dst)
+{
+       if (src == NULL) {
+               memset(dst, 0, sizeof(*dst));
+       } else {
+               bridge_copyaddr(&src->brtag_peer.sa, &dst->brtag_peer.sa);
+               bridge_copyaddr(&src->brtag_local.sa, &dst->brtag_local.sa);
+               dst->brtag_id = src->brtag_id;
        }
 }
Index: net/if_bridge.c
===================================================================
RCS file: /cvs/src/sys/net/if_bridge.c,v
retrieving revision 1.322
diff -u -p -r1.322 if_bridge.c
--- net/if_bridge.c     20 Feb 2019 17:11:51 -0000      1.322
+++ net/if_bridge.c     22 Feb 2019 14:21:43 -0000
@@ -768,17 +768,10 @@ bridge_output(struct ifnet *ifp, struct 
 
        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);
-               }
+               dst_if = bridge_rtlookup(sc, dst, m);
        }
 
        /*
@@ -929,10 +922,7 @@ bridgeintr_frame(struct bridge_softc *sc
         * 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;
+               dst_if = bridge_rtlookup(sc, dst, NULL);
                if (dst_if == src_if) {
                        m_freem(m);
                        return;
@@ -1970,63 +1960,4 @@ bridge_send_icmp_err(struct ifnet *ifp,
 
  dropit:
        m_freem(n);
-}
-
-struct bridge_tunneltag *
-bridge_tunnel(struct mbuf *m)
-{
-       struct m_tag    *mtag;
-
-       if ((mtag = m_tag_find(m, PACKET_TAG_TUNNEL, NULL)) == NULL)
-               return (NULL);
-
-       return ((struct bridge_tunneltag *)(mtag + 1));
-}
-
-struct bridge_tunneltag *
-bridge_tunneltag(struct mbuf *m)
-{
-       struct m_tag    *mtag;
-
-       if ((mtag = m_tag_find(m, PACKET_TAG_TUNNEL, NULL)) == NULL) {
-               mtag = m_tag_get(PACKET_TAG_TUNNEL,
-                   sizeof(struct bridge_tunneltag), M_NOWAIT);
-               if (mtag == NULL)
-                       return (NULL);
-               bzero(mtag + 1, sizeof(struct bridge_tunneltag));
-               m_tag_prepend(m, mtag);
-       }
-
-       return ((struct bridge_tunneltag *)(mtag + 1));
-}
-
-void
-bridge_tunneluntag(struct mbuf *m)
-{
-       struct m_tag    *mtag;
-       if ((mtag = m_tag_find(m, PACKET_TAG_TUNNEL, NULL)) != NULL)
-               m_tag_delete(m, mtag);
-}
-
-void
-bridge_copyaddr(struct sockaddr *src, struct sockaddr *dst)
-{
-       if (src != NULL && src->sa_family != AF_UNSPEC)
-               memcpy(dst, src, src->sa_len);
-       else {
-               dst->sa_family = AF_UNSPEC;
-               dst->sa_len = 0;
-       }
-}
-
-void
-bridge_copytag(struct bridge_tunneltag *src, struct bridge_tunneltag *dst)
-{
-       if (src == NULL) {
-               memset(dst, 0, sizeof(*dst));
-       } else {
-               bridge_copyaddr(&src->brtag_peer.sa, &dst->brtag_peer.sa);
-               bridge_copyaddr(&src->brtag_local.sa, &dst->brtag_local.sa);
-               dst->brtag_id = src->brtag_id;
-       }
 }
Index: net/if_bridge.h
===================================================================
RCS file: /cvs/src/sys/net/if_bridge.h,v
retrieving revision 1.62
diff -u -p -r1.62 if_bridge.h
--- net/if_bridge.h     20 Feb 2019 17:11:51 -0000      1.62
+++ net/if_bridge.h     22 Feb 2019 14:21:43 -0000
@@ -518,8 +518,8 @@ void        bstp_ifsflags(struct bstp_port *, u
 int    bridgectl_ioctl(struct ifnet *, u_long, caddr_t);
 int    bridge_rtupdate(struct bridge_softc *,
     struct ether_addr *, struct ifnet *ifp, int, u_int8_t, struct mbuf *);
-struct bridge_rtnode *bridge_rtlookup(struct bridge_softc *,
-    struct ether_addr *);
+struct ifnet *bridge_rtlookup(struct bridge_softc *,
+    struct ether_addr *, struct mbuf *);
 void   bridge_rtflush(struct bridge_softc *, int);
 void   bridge_rtage(void *);
 

Reply via email to