From 62fc95fd847703423c4902b3205c6d9517f20006 Mon Sep 17 00:00:00 2001 From: Claudio Jeker Date: Tue, 11 May 2010 09:36:08 +0000 Subject: 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@ --- sys/netinet/in_gif.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'sys/netinet/in_gif.c') 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 +#endif #if NPF > 0 #include #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; } -- cgit v1.2.3