I tested this patch and etherip is working.
ok goda

On 2015/07/16 17:52, Martin Pieuchot wrote:
goda@ found a regression due to the recent M_PROTO1 change.  Apparently
gif(4) is using this flag to know that a packet comes from bridge(4) and
wants etherip encapsulation.

Instead of hiding another layer-violation (yeah for bridge!) make it
obvious.  Diff below, any ok?

Index: net/if_bridge.c
===================================================================
RCS file: /cvs/src/sys/net/if_bridge.c,v
retrieving revision 1.254
diff -u -p -r1.254 if_bridge.c
--- net/if_bridge.c     16 Jul 2015 21:14:21 -0000      1.254
+++ net/if_bridge.c     16 Jul 2015 23:13:33 -0000
@@ -91,6 +91,10 @@
  #include <net/if_vlan_var.h>
  #endif

+#if NGIF > 0
+#include <net/if_gif.h>
+#endif
+
  #include <net/if_bridge.h>

  /*
@@ -1355,6 +1359,7 @@ bridge_input(struct ifnet *ifp, struct m
                IF_ENQUEUE(&sc->sc_if.if_snd, mc);
                splx(s);
                schednetisr(NETISR_BRIDGE);
+#if NGIF > 0
                if (ifp->if_type == IFT_GIF) {
                        TAILQ_FOREACH(ifl, &sc->sc_iflist, next) {
                                if (ifl->ifp->if_type != IFT_ETHER)
@@ -1366,6 +1371,7 @@ bridge_input(struct ifnet *ifp, struct m
                                return (NULL);
                        }
                }
+#endif /* NGIF */
                return (m);
        }

@@ -2556,8 +2562,12 @@ bridge_ifenqueue(struct bridge_softc *sc
                /* Count packets input into the gif from outside */
                ifp->if_ipackets++;
                ifp->if_ibytes += m->m_pkthdr.len;
+
+               error = gif_encap(ifp, &m, AF_LINK);
+               if (error)
+                       return (error);
        }
-#endif
+#endif /* NGIF */
        len = m->m_pkthdr.len;

        error = if_enqueue(ifp, m);
Index: net/if_gif.c
===================================================================
RCS file: /cvs/src/sys/net/if_gif.c,v
retrieving revision 1.76
diff -u -p -r1.76 if_gif.c
--- net/if_gif.c        16 Jul 2015 21:21:49 -0000      1.76
+++ net/if_gif.c        16 Jul 2015 23:09:57 -0000
@@ -169,39 +169,6 @@ gif_start(struct ifnet *ifp)
                        continue;
                }

-               /*
-                * Check if the packet is coming via bridge and needs
-                * etherip encapsulation or not. bridge(4) directly calls
-                * the start function and bypasses the if_output function
-                * so we need to do the encap here.
-                */
-               if (ifp->if_bridgeport && (m->m_flags & M_PROTO1)) {
-                       int error = 0;
-                       /*
-                        * Remove multicast and broadcast flags or encapsulated
-                        * packet ends up as multicast or broadcast packet.
-                        */
-                       m->m_flags &= ~(M_BCAST|M_MCAST);
-                       switch (sc->gif_psrc->sa_family) {
-                       case AF_INET:
-                               error = in_gif_output(ifp, AF_LINK, &m);
-                               break;
-#ifdef INET6
-                       case AF_INET6:
-                               error = in6_gif_output(ifp, AF_LINK, &m);
-                               break;
-#endif
-                       default:
-                               error = EAFNOSUPPORT;
-                               m_freem(m);
-                               break;
-                       }
-                       if (error)
-                               continue;
-                       if (gif_checkloop(ifp, m))
-                               continue;
-               }
-
  #if NBPFILTER > 0
                if (ifp->if_bpf) {
                        int offset;
@@ -279,48 +246,58 @@ gif_start(struct ifnet *ifp)
  }

  int
-gif_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
-    struct rtentry *rt)
+gif_encap(struct ifnet *ifp, struct mbuf **mp, sa_family_t af)
  {
        struct gif_softc *sc = (struct gif_softc*)ifp;
        int error = 0;
-
-       if (!(ifp->if_flags & IFF_UP) ||
-           sc->gif_psrc == NULL || sc->gif_pdst == NULL ||
-           sc->gif_psrc->sa_family != sc->gif_pdst->sa_family) {
-               m_freem(m);
-               error = ENETDOWN;
-               goto end;
-       }
-
        /*
         * Remove multicast and broadcast flags or encapsulated packet
         * ends up as multicast or broadcast packet.
         */
-       m->m_flags &= ~(M_BCAST|M_MCAST);
+       (*mp)->m_flags &= ~(M_BCAST|M_MCAST);

        /*
         * Encapsulate packet. Add IP or IP6 header depending on tunnel AF.
         */
        switch (sc->gif_psrc->sa_family) {
        case AF_INET:
-               error = in_gif_output(ifp, dst->sa_family, &m);
+               error = in_gif_output(ifp, af, mp);
                break;
  #ifdef INET6
        case AF_INET6:
-               error = in6_gif_output(ifp, dst->sa_family, &m);
+               error = in6_gif_output(ifp, af, mp);
                break;
  #endif
        default:
-               m_freem(m);
+               m_freem(*mp);
                error = EAFNOSUPPORT;
                break;
        }

        if (error)
+               return (error);
+
+       error = gif_checkloop(ifp, *mp);
+       return (error);
+}
+
+int
+gif_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
+    struct rtentry *rt)
+{
+       struct gif_softc *sc = (struct gif_softc*)ifp;
+       int error = 0;
+
+       if (!(ifp->if_flags & IFF_UP) ||
+           sc->gif_psrc == NULL || sc->gif_pdst == NULL ||
+           sc->gif_psrc->sa_family != sc->gif_pdst->sa_family) {
+               m_freem(m);
+               error = ENETDOWN;
                goto end;
+       }

-       if ((error = gif_checkloop(ifp, m)))
+       error = gif_encap(ifp, &m, dst->sa_family);
+       if (error)
                goto end;

        error = if_enqueue(ifp, m);
Index: net/if_gif.h
===================================================================
RCS file: /cvs/src/sys/net/if_gif.h,v
retrieving revision 1.12
diff -u -p -r1.12 if_gif.h
--- net/if_gif.h        16 Jul 2015 21:21:49 -0000      1.12
+++ net/if_gif.h        16 Jul 2015 23:09:05 -0000
@@ -47,4 +47,6 @@ struct gif_softc {

  extern LIST_HEAD(gif_softc_head, gif_softc) gif_softc_list;

+int gif_encap(struct ifnet *, struct mbuf **, sa_family_t);
+
  #endif /* _NET_IF_GIF_H_ */


Reply via email to