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_ */