diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2010-05-11 09:36:08 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2010-05-11 09:36:08 +0000 |
commit | 62fc95fd847703423c4902b3205c6d9517f20006 (patch) | |
tree | 7d05c62bdb72350f0f01022800ac767f57e999a4 /sys/netinet/in_gif.c | |
parent | 1b7752fdde26fac73c4c3bb416b412ce523cc945 (diff) |
Massiv cleanup of the gif(4) mess. Move encapsulation into gif_output()
where it is not necessary to guess protocols by looking at the first nibble.
in_gif_output() will encapsulate the packet but not send it. Because of
etherip support and the way the bridge works a minimal hack is needed in
gif_start() to ensure that the bridged packets are encapsulated as well.
This actually started with the idea to add MPLS support but that turned out
to be not as simple as in the gre(4) case.
Tested by myself (IP, IPv6, etherip, MPLS), sthen@ (IP, IPv6), naddy (IPv6)
OK sthen@
Diffstat (limited to 'sys/netinet/in_gif.c')
-rw-r--r-- | sys/netinet/in_gif.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/sys/netinet/in_gif.c b/sys/netinet/in_gif.c index e2a92c0c57c..3cf02f75490 100644 --- a/sys/netinet/in_gif.c +++ b/sys/netinet/in_gif.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in_gif.c,v 1.37 2009/11/21 14:08:14 claudio Exp $ */ +/* $OpenBSD: in_gif.c,v 1.38 2010/05/11 09:36:07 claudio Exp $ */ /* $KAME: in_gif.c,v 1.50 2001/01/22 07:27:16 itojun Exp $ */ /* @@ -54,13 +54,16 @@ #include "gif.h" #include "bridge.h" +#if NBRIDGE > 0 +#include <netinet/ip_ether.h> +#endif #if NPF > 0 #include <net/pfvar.h> #endif int -in_gif_output(struct ifnet *ifp, int family, struct mbuf *m) +in_gif_output(struct ifnet *ifp, int family, struct mbuf **m0) { struct gif_softc *sc = (struct gif_softc*)ifp; struct sockaddr_in *sin_src = (struct sockaddr_in *)sc->gif_psrc; @@ -68,7 +71,7 @@ in_gif_output(struct ifnet *ifp, int family, struct mbuf *m) struct tdb tdb; struct xformsw xfs; int error; - struct mbuf *mp; + struct mbuf *m = *m0; if (sin_src == NULL || sin_dst == NULL || sin_src->sin_family != AF_INET || @@ -85,7 +88,7 @@ in_gif_output(struct ifnet *ifp, int family, struct mbuf *m) } #endif - /* setup dummy tdb. it highly depends on ipipoutput() code. */ + /* setup dummy tdb. it highly depends on ipip_output() code. */ bzero(&tdb, sizeof(tdb)); bzero(&xfs, sizeof(xfs)); tdb.tdb_src.sin.sin_family = AF_INET; @@ -107,7 +110,11 @@ in_gif_output(struct ifnet *ifp, int family, struct mbuf *m) #if NBRIDGE > 0 case AF_LINK: break; -#endif /* NBRIDGE */ +#endif +#if MPLS + case AF_MPLS: + break; +#endif default: #ifdef DEBUG printf("in_gif_output: warning: unknown family %d passed\n", @@ -118,26 +125,30 @@ in_gif_output(struct ifnet *ifp, int family, struct mbuf *m) } /* encapsulate into IPv4 packet */ - mp = NULL; + *m0 = NULL; #if NBRIDGE > 0 if (family == AF_LINK) - error = etherip_output(m, &tdb, &mp, 0, 0); + error = etherip_output(m, &tdb, m0, IPPROTO_ETHERIP); else #endif /* NBRIDGE */ - error = ipip_output(m, &tdb, &mp, 0, 0); +#ifdef MPLS + if (family == AF_MPLS) + error = etherip_output(m, &tdb, m0, IPPROTO_MPLS); + else +#endif + error = ipip_output(m, &tdb, m0, 0, 0); if (error) return error; - else if (mp == NULL) + else if (*m0 == NULL) return EFAULT; - m = mp; + m = *m0; m->m_pkthdr.rdomain = sc->gif_rtableid; #if NPF > 0 pf_pkt_addr_changed(m); #endif - return ip_output(m, (void *)NULL, (void *)NULL, 0, (void *)NULL, - (void *)NULL); + return 0; } void @@ -186,7 +197,8 @@ in_gif_input(struct mbuf *m, ...) m->m_pkthdr.rdomain = gifp->if_rdomain; gifp->if_ipackets++; gifp->if_ibytes += m->m_pkthdr.len; - ipip_input(m, off, gifp); /* We have a configured GIF */ + /* We have a configured GIF */ + ipip_input(m, off, gifp, ip->ip_p); return; } |