diff options
author | 2015-07-17 18:05:59 +0000 | |
---|---|---|
committer | 2015-07-17 18:05:59 +0000 | |
commit | 523c597e0dc364cfb9deace4040af07d9adb8799 (patch) | |
tree | 1e0c7baa60050ed386dc172b0c396af9c2d21bd8 | |
parent | return 0 when using "getall" (diff) | |
download | wireguard-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.c | 14 | ||||
-rw-r--r-- | sys/net/if_gif.c | 77 | ||||
-rw-r--r-- | sys/net/if_gif.h | 4 |
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_ */ |