summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2015-07-17 18:05:59 +0000
committermpi <mpi@openbsd.org>2015-07-17 18:05:59 +0000
commit523c597e0dc364cfb9deace4040af07d9adb8799 (patch)
tree1e0c7baa60050ed386dc172b0c396af9c2d21bd8
parentreturn 0 when using "getall" (diff)
downloadwireguard-openbsd-523c597e0dc364cfb9deace4040af07d9adb8799.tar.xz
wireguard-openbsd-523c597e0dc364cfb9deace4040af07d9adb8799.zip
Explicitly do EtherIP encapsulation in bridge_ifenqueue().
The way gif(4) and bridge(4) are plugged together is disgusting but at least this makes the layer violation obvious. Fix a regression introduced by the M_PROTO1 loop prevention cleaning because gif(4) was abusing this flag to figure out if the packet was coming from a bridge(4). Thanks to goda@ for finding this! ok goda@, claudio@
-rw-r--r--sys/net/if_bridge.c14
-rw-r--r--sys/net/if_gif.c77
-rw-r--r--sys/net/if_gif.h4
3 files changed, 42 insertions, 53 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 4fcb1974ffa..1feead383c7 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.254 2015/07/16 21:14:21 mpi Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.255 2015/07/17 18:05:59 mpi Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -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 mbuf *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 mbuf *m)
return (NULL);
}
}
+#endif /* NGIF */
return (m);
}
@@ -2556,8 +2562,12 @@ bridge_ifenqueue(struct bridge_softc *sc, struct ifnet *ifp, struct mbuf *m)
/* 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);
diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c
index 18e499a8216..f89d0579277 100644
--- a/sys/net/if_gif.c
+++ b/sys/net/if_gif.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_gif.c,v 1.76 2015/07/16 21:21:49 mpi Exp $ */
+/* $OpenBSD: if_gif.c,v 1.77 2015/07/17 18:05:59 mpi Exp $ */
/* $KAME: if_gif.c,v 1.43 2001/02/20 08:51:07 itojun Exp $ */
/*
@@ -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);
diff --git a/sys/net/if_gif.h b/sys/net/if_gif.h
index df3d52ce604..563fd70f1aa 100644
--- a/sys/net/if_gif.h
+++ b/sys/net/if_gif.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_gif.h,v 1.12 2015/07/16 21:21:49 mpi Exp $ */
+/* $OpenBSD: if_gif.h,v 1.13 2015/07/17 18:05:59 mpi Exp $ */
/* $KAME: if_gif.h,v 1.17 2000/09/11 11:36:41 sumikawa Exp $ */
/*
@@ -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_ */