Author: ae
Date: Sat Jan 10 08:28:50 2015
New Revision: 276907
URL: https://svnweb.freebsd.org/changeset/base/276907

Log:
  Restore Ethernet-within-IP Encapsulation support that was broken after
  r273087. Move all checks from gif_output() into gif_transmit(). Previously
  they were checked always, because if_start always called gif_output.
  Now gif_transmit() can be called directly from if_bridge() code and we need
  do checks here.
  
  PR:           196646
  MFC after:    1 week

Modified:
  head/sys/net/if_gif.c

Modified: head/sys/net/if_gif.c
==============================================================================
--- head/sys/net/if_gif.c       Sat Jan 10 07:22:38 2015        (r276906)
+++ head/sys/net/if_gif.c       Sat Jan 10 08:28:50 2015        (r276907)
@@ -118,6 +118,7 @@ void        (*ng_gif_input_orphan_p)(struct ifn
 void   (*ng_gif_attach_p)(struct ifnet *ifp);
 void   (*ng_gif_detach_p)(struct ifnet *ifp);
 
+static int     gif_check_nesting(struct ifnet *, struct mbuf *);
 static int     gif_set_tunnel(struct ifnet *, struct sockaddr *,
     struct sockaddr *);
 static void    gif_delete_tunnel(struct ifnet *);
@@ -351,18 +352,32 @@ gif_transmit(struct ifnet *ifp, struct m
        uint8_t proto, ecn;
        int error;
 
+#ifdef MAC
+       error = mac_ifnet_check_transmit(ifp, m);
+       if (error) {
+               m_freem(m);
+               goto err;
+       }
+#endif
        error = ENETDOWN;
        sc = ifp->if_softc;
-       if (sc->gif_family == 0) {
+       if ((ifp->if_flags & IFF_MONITOR) != 0 ||
+           (ifp->if_flags & IFF_UP) == 0 ||
+           sc->gif_family == 0 ||
+           (error = gif_check_nesting(ifp, m)) != 0) {
                m_freem(m);
                goto err;
        }
        /* Now pull back the af that we stashed in the csum_data. */
-       af = m->m_pkthdr.csum_data;
+       if (ifp->if_bridge)
+               af = AF_LINK;
+       else
+               af = m->m_pkthdr.csum_data;
+       m->m_flags &= ~(M_BCAST|M_MCAST);
+       M_SETFIB(m, sc->gif_fibnum);
        BPF_MTAP2(ifp, &af, sizeof(af), m);
        if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
        if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len);
-       M_SETFIB(m, sc->gif_fibnum);
        /* inner AF-specific encapsulation */
        ecn = 0;
        switch (af) {
@@ -488,28 +503,11 @@ gif_output(struct ifnet *ifp, struct mbu
        struct route *ro)
 {
        uint32_t af;
-       int error = 0;
-#ifdef MAC
-       error = mac_ifnet_check_transmit(ifp, m);
-       if (error)
-               goto err;
-#endif
-       if ((ifp->if_flags & IFF_MONITOR) != 0 ||
-           (ifp->if_flags & IFF_UP) == 0) {
-               error = ENETDOWN;
-               goto err;
-       }
 
-       error = gif_check_nesting(ifp, m);
-       if (error != 0)
-               goto err;
-       m->m_flags &= ~(M_BCAST|M_MCAST);
        if (dst->sa_family == AF_UNSPEC)
                bcopy(dst->sa_data, &af, sizeof(af));
        else
                af = dst->sa_family;
-       if (ifp->if_bridge)
-               af = AF_LINK;
        /*
         * Now save the af in the inbound pkt csum data, this is a cheat since
         * we are using the inbound csum_data field to carry the af over to
@@ -517,10 +515,6 @@ gif_output(struct ifnet *ifp, struct mbu
         */
        m->m_pkthdr.csum_data = af;
        return (ifp->if_transmit(ifp, m));
-err:
-       if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
-       m_freem(m);
-       return (error);
 }
 
 void
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to