this avoids having to parse the gif packet before sending it to
bpf. instead, we stash the address family in the mbuf and add it
after bpf.

however, a gif_encap error will not be propagated back to the sender.
i dont think this is a huge loss as the ip packet is usually
encapsulated itself after ip_send/ip_output (eg, by ethernet), which
could fail without propagating an error back either.

ok?

Index: if_gif.c
===================================================================
RCS file: /cvs/src/sys/net/if_gif.c,v
retrieving revision 1.107
diff -u -p -r1.107 if_gif.c
--- if_gif.c    9 Jan 2018 15:24:24 -0000       1.107
+++ if_gif.c    11 Jan 2018 03:22:09 -0000
@@ -175,55 +175,16 @@ gif_start(struct ifnet *ifp)
 
 #if NBPFILTER > 0
                if (ifp->if_bpf) {
-                       int offset;
-                       sa_family_t family;
-                       u_int8_t proto;
-
-                       /* must decapsulate outer header for bpf */
-                       switch (sc->gif_psrc->sa_family) {
-                       case AF_INET:
-                               offset = sizeof(struct ip);
-                               proto = mtod(m, struct ip *)->ip_p;
-                               break;
-#ifdef INET6
-                       case AF_INET6:
-                               offset = sizeof(struct ip6_hdr);
-                               proto = mtod(m, struct ip6_hdr *)->ip6_nxt;
-                               break;
-#endif
-                       default:
-                               proto = 0;
-                               break;
-                       }
-                       switch (proto) {
-                       case IPPROTO_IPV4:
-                               family = AF_INET;
-                               break;
-                       case IPPROTO_IPV6:
-                               family = AF_INET6;
-                               break;
-                       case IPPROTO_ETHERIP:
-                               family = AF_LINK;
-                               offset += sizeof(struct etherip_header);
-                               break;
-                       case IPPROTO_MPLS:
-                               family = AF_MPLS;
-                               break;
-                       default:
-                               offset = 0;
-                               family = sc->gif_psrc->sa_family;
-                               break;
-                       }
-                       m->m_data += offset;
-                       m->m_len -= offset;
-                       m->m_pkthdr.len -= offset;
-                       bpf_mtap_af(ifp->if_bpf, family, m, BPF_DIRECTION_OUT);
-                       m->m_data -= offset;
-                       m->m_len += offset;
-                       m->m_pkthdr.len += offset;
+                       bpf_mtap_af(ifp->if_bpf, m->m_pkthdr.ph_family, m,
+                           BPF_DIRECTION_OUT);
                }
 #endif
 
+               if (gif_encap(ifp, &m, m->m_pkthdr.ph_family) != 0) {
+                       m_freem(m);
+                       continue;
+               }
+
                /* XXX we should cache the outgoing route */
 
                switch (sc->gif_psrc->sa_family) {
@@ -294,9 +255,7 @@ gif_output(struct ifnet *ifp, struct mbu
                goto end;
        }
 
-       error = gif_encap(ifp, &m, dst->sa_family);
-       if (error)
-               goto end;
+       m->m_pkthdr.ph_family = dst->sa_family;
 
        error = if_enqueue(ifp, m);
 

Reply via email to