summaryrefslogtreecommitdiff
path: root/sys/netinet/in_gif.c
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2010-05-11 09:36:08 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2010-05-11 09:36:08 +0000
commit62fc95fd847703423c4902b3205c6d9517f20006 (patch)
tree7d05c62bdb72350f0f01022800ac767f57e999a4 /sys/netinet/in_gif.c
parent1b7752fdde26fac73c4c3bb416b412ce523cc945 (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.c38
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;
}