summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorNiels Provos <provos@cvs.openbsd.org>1997-07-01 22:12:54 +0000
committerNiels Provos <provos@cvs.openbsd.org>1997-07-01 22:12:54 +0000
commit170afa951af5e94eeb4a824da6b926603c094be2 (patch)
treeb872ba634c7124715b485e7217b675eb6ffb4455 /sys
parent4baf2e1d61b5570ff1ad12415e822ea0a3d4f9f2 (diff)
major restructuring
Diffstat (limited to 'sys')
-rw-r--r--sys/net/encap.c326
-rw-r--r--sys/net/encap.h276
-rw-r--r--sys/net/if_enc.c254
-rw-r--r--sys/netinet/ip_ah.c4
-rw-r--r--sys/netinet/ip_ahhmacmd5.c5
-rw-r--r--sys/netinet/ip_ahhmacsha1.c5
-rw-r--r--sys/netinet/ip_ahmd5.c6
-rw-r--r--sys/netinet/ip_ahsha1.c5
-rw-r--r--sys/netinet/ip_esp.c4
-rw-r--r--sys/netinet/ip_esp3des.c5
-rw-r--r--sys/netinet/ip_esp3desmd5.c5
-rw-r--r--sys/netinet/ip_espdes.c5
-rw-r--r--sys/netinet/ip_espdesmd5.c5
-rw-r--r--sys/netinet/ip_ip4.c59
-rw-r--r--sys/netinet/ip_ip4.h16
-rw-r--r--sys/netinet/ip_ipsp.c70
-rw-r--r--sys/netinet/ip_ipsp.h19
-rw-r--r--sys/netinet/ip_output.c93
18 files changed, 526 insertions, 636 deletions
diff --git a/sys/net/encap.c b/sys/net/encap.c
index 898ff599dcf..ae2de47222a 100644
--- a/sys/net/encap.c
+++ b/sys/net/encap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: encap.c,v 1.5 1997/06/25 07:53:19 provos Exp $ */
+/* $OpenBSD: encap.c,v 1.6 1997/07/01 22:12:40 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -44,6 +44,7 @@
#include <net/encap.h>
#include <netinet/ip_ipsp.h>
+#include <netinet/ip_ip4.h>
extern struct ifnet loif;
@@ -51,7 +52,8 @@ extern int ipspkernfs_dirty;
void encap_init(void);
int encap_output __P((struct mbuf *, ...));
-int encap_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *);
+int encap_usrreq(struct socket *, int, struct mbuf *, struct mbuf *,
+ struct mbuf *);
extern int tdb_init(struct tdb *, struct mbuf *);
@@ -89,10 +91,11 @@ encap_init()
/*ARGSUSED*/
int
-encap_usrreq(register struct socket *so, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *control)
+encap_usrreq(register struct socket *so, int req, struct mbuf *m,
+ struct mbuf *nam, struct mbuf *control)
{
- register int error = 0;
register struct rawcb *rp = sotorawcb(so);
+ register int error = 0;
int s;
if (req == PRU_ATTACH)
@@ -133,16 +136,13 @@ va_dcl
#endif
{
#define SENDERR(e) do { error = e; goto flush;} while (0)
- struct socket *so;
- int len, emlen, error = 0, nspis, i;
+ int len, emlen, error = 0;
struct encap_msghdr *emp;
- struct ifnet *ifp;
- struct ifaddr *ifa;
- struct sockaddr_encap *sen, *sen2;
- struct sockaddr_in *sin;
- struct tdb *tdbp, *tprev;
- va_list ap;
+ struct tdb *tdbp, *tdbp2;
+ caddr_t buffer = 0;
+ struct socket *so;
u_int32_t spi;
+ va_list ap;
va_start(ap, m);
so = va_arg(ap, struct socket *);
@@ -156,75 +156,44 @@ va_dcl
panic("encap_output");
len = m->m_pkthdr.len;
+
emp = mtod(m, struct encap_msghdr *);
+
emlen = emp->em_msglen;
if ((len < emlen))
SENDERR(EINVAL);
if (m->m_len < emlen)
{
- m = m_pullup(m, emlen);
- if (m == NULL)
+ MALLOC(buffer, caddr_t, emlen, M_TEMP, M_WAITOK);
+ if (buffer == 0)
SENDERR(ENOBUFS);
-
- emp = mtod(m, struct encap_msghdr *);
+
+ m_copydata(m, 0, emlen, buffer);
+
+ emp = (struct encap_msghdr *) buffer;
}
+ if (emp->em_version != PFENCAP_VERSION_1)
+ SENDERR(EINVAL);
+
switch (emp->em_type)
{
- case EMT_IFADDR:
- if (emp->em_ifn >= nencap)
- SENDERR(ENODEV);
-
- /*
- * Set the default source address for an encap interface
- */
-
- ifp = &(enc_softc[emp->em_ifn].enc_if);
-
- if ((ifp->if_addrlist.tqh_first == NULL) ||
- (ifp->if_addrlist.tqh_first->ifa_addr == NULL) ||
- (ifp->if_addrlist.tqh_first->ifa_addr->sa_family != AF_ENCAP))
- {
- MALLOC(ifa, struct ifaddr *, sizeof (struct ifaddr) +
- 2 * SENT_DEFIF_LEN, M_IFADDR, M_WAITOK);
- if (ifa == NULL)
- SENDERR(ENOBUFS);
-
- bzero((caddr_t)ifa, sizeof (struct ifaddr) +
- 2 * SENT_DEFIF_LEN);
- sen = (struct sockaddr_encap *)(ifa + 1);
- sen2 = (struct sockaddr_encap *)((caddr_t)sen +
- SENT_DEFIF_LEN);
- ifa->ifa_addr = (struct sockaddr *)sen;
- ifa->ifa_dstaddr = (struct sockaddr *)sen2;
- ifa->ifa_ifp = ifp;
- TAILQ_INSERT_HEAD(&(ifp->if_addrlist), ifa, ifa_list);
- }
- else
- {
- sen = (struct sockaddr_encap *)((&(ifp->if_addrlist))->tqh_first->ifa_addr);
- sen2 = (struct sockaddr_encap *)((&(ifp->if_addrlist))->tqh_first->ifa_dstaddr);
- }
-
- sen->sen_family = AF_ENCAP;
- sen->sen_len = SENT_DEFIF_LEN;
- sen->sen_type = SENT_DEFIF;
- sin = (struct sockaddr_in *) &(sen->sen_dfl);
- sin->sin_len = sizeof(*sin);
- sin->sin_family = AF_INET;
- sin->sin_addr = emp->em_ifa;
-
- *sen2 = *sen;
-
- break;
-
case EMT_SETSPI:
- if (emp->em_if >= nencap)
- SENDERR(ENODEV);
+ if (emlen <= EMT_SETSPI_FLEN)
+ SENDERR(EINVAL);
+
tdbp = gettdb(emp->em_spi, emp->em_dst);
if (tdbp == NULL)
{
+ /*
+ * If only one of the two outter addresses is set, return
+ * error.
+ */
+ if ((emp->em_osrc.s_addr != 0) ^
+ (emp->em_odst.s_addr != 0))
+ SENDERR(EINVAL);
+
MALLOC(tdbp, struct tdb *, sizeof (*tdbp), M_TDB, M_WAITOK);
if (tdbp == NULL)
SENDERR(ENOBUFS);
@@ -233,8 +202,38 @@ va_dcl
tdbp->tdb_spi = emp->em_spi;
tdbp->tdb_dst = emp->em_dst;
- tdbp->tdb_rcvif = &(enc_softc[emp->em_if].enc_if);
+ tdbp->tdb_proto = emp->em_proto;
+ tdbp->tdb_sport = emp->em_sport;
+ tdbp->tdb_dport = emp->em_dport;
+
+ tdbp->tdb_src = emp->em_src;
+
+ /* Check if this is an encapsulating SPI */
+ if (emp->em_osrc.s_addr != 0)
+ {
+ tdbp->tdb_flags |= TDBF_TUNNELING;
+ tdbp->tdb_osrc = emp->em_osrc;
+ tdbp->tdb_odst = emp->em_odst;
+
+ /* TTL */
+ switch (emp->em_ttl)
+ {
+ case IP4_DEFAULT_TTL:
+ tdbp->tdb_ttl = 0;
+ break;
+
+ case IP4_SAME_TTL:
+ tdbp->tdb_flags |= TDBF_SAME_TTL;
+ break;
+
+ default:
+ /* Get just the least significant bits */
+ tdbp->tdb_ttl = emp->em_ttl % 256;
+ break;
+ }
+ }
+
puttdb(tdbp);
}
else
@@ -302,82 +301,77 @@ va_dcl
}
error = tdb_init(tdbp, m);
+ if (error)
+ SENDERR(EINVAL);
+
ipspkernfs_dirty = 1;
+
break;
case EMT_DELSPI:
- if (emp->em_if >= nencap)
- SENDERR(ENODEV);
- tdbp = gettdb(emp->em_spi, emp->em_dst);
+ if (emlen != EMT_DELSPI_FLEN)
+ SENDERR(EINVAL);
+
+ tdbp = gettdb(emp->em_gen_spi, emp->em_gen_dst);
if (tdbp == NULL)
- {
- error = EINVAL;
- break;
- }
-
- if (emp->em_alg != tdbp->tdb_xform->xf_type)
- {
- error = EINVAL;
- break;
- }
-
+ SENDERR(ENOENT);
+
error = tdb_delete(tdbp, 0);
+ if (error)
+ SENDERR(EINVAL);
+
break;
case EMT_DELSPICHAIN:
- if (emp->em_if >= nencap)
- SENDERR(ENODEV);
- tdbp = gettdb(emp->em_spi, emp->em_dst);
- if (tdbp == NULL)
- {
- error = EINVAL;
- break;
- }
-
- if (emp->em_alg != tdbp->tdb_xform->xf_type)
- {
- error = EINVAL;
- break;
- }
+ if (emlen != EMT_DELSPICHAIN_FLEN)
+ SENDERR(EINVAL);
+ tdbp = gettdb(emp->em_gen_spi, emp->em_gen_dst);
+ if (tdbp == NULL)
+ SENDERR(ENOENT);
+
error = tdb_delete(tdbp, 1);
+ if (error)
+ SENDERR(EINVAL);
+
break;
case EMT_GRPSPIS:
- nspis = (emlen - 4) / 12;
- if (nspis * 12 + 4 != emlen)
+ if (emlen != EMT_GRPSPIS_FLEN)
SENDERR(EINVAL);
- for (i = 0; i < nspis; i++)
- if ((tdbp = gettdb(emp->em_rel[i].emr_spi, emp->em_rel[i].emr_dst)) == NULL)
- SENDERR(ENOENT);
- else
- emp->em_rel[i].emr_tdb = tdbp;
+ tdbp = gettdb(emp->em_rel_spi, emp->em_rel_dst);
+ if (tdbp == NULL)
+ SENDERR(ENOENT);
- tprev = emp->em_rel[0].emr_tdb;
- tprev->tdb_inext = NULL;
- for (i = 1; i < nspis; i++)
- {
- tdbp = emp->em_rel[i].emr_tdb;
- tprev->tdb_onext = tdbp;
- tdbp->tdb_inext = tprev;
- tprev = tdbp;
- }
- tprev->tdb_onext = NULL;
+ tdbp2 = gettdb(emp->em_rel_spi2, emp->em_rel_dst2);
+ if (tdbp2 == NULL)
+ SENDERR(ENOENT);
+
+ tdbp->tdb_onext = tdbp2;
+ tdbp2->tdb_inext = tdbp;
+
ipspkernfs_dirty = 1;
error = 0;
break;
case EMT_RESERVESPI:
- spi = reserve_spi(emp->em_spi, emp->em_dst);
+ if (emlen != EMT_RESERVESPI_FLEN)
+ SENDERR(EINVAL);
+
+ spi = reserve_spi(emp->em_gen_spi, emp->em_gen_dst);
if (spi == 0)
- if (emp->em_spi == 0)
+ if (emp->em_gen_spi == 0)
SENDERR(ENOBUFS);
else
SENDERR(EINVAL);
- emp->em_spi = spi;
+ emp->em_gen_spi = spi;
+ /* If we're using a buffer, copy the data back to the mbuf */
+ if (buffer)
+ m_copyback(m, 0, emlen, buffer);
+
/* Send it back to us */
if (sbappendaddr(&so->so_rcv, &encap_src, m,
(struct mbuf *)0) == 0)
@@ -390,114 +384,66 @@ va_dcl
break;
case EMT_ENABLESPI:
- tdbp = gettdb(emp->em_spi, emp->em_dst);
+ if (emlen != EMT_ENABLESPI_FLEN)
+ SENDERR(EINVAL);
+
+ tdbp = gettdb(emp->em_gen_spi, emp->em_gen_dst);
if (tdbp == NULL)
SENDERR(ENOENT);
/* Clear the INVALID flag */
tdbp->tdb_flags &= (~TDBF_INVALID);
+
error = 0;
break;
case EMT_DISABLESPI:
- tdbp = gettdb(emp->em_spi, emp->em_dst);
+ if (emlen != EMT_DISABLESPI_FLEN)
+ SENDERR(EINVAL);
+
+ tdbp = gettdb(emp->em_gen_spi, emp->em_gen_dst);
if (tdbp == NULL)
SENDERR(ENOENT);
/* Set the INVALID flag */
tdbp->tdb_flags |= TDBF_INVALID;
+
error = 0;
break;
+
+ case EMT_NOTIFY:
+ if (emlen <= EMT_NOTIFY_FLEN)
+ SENDERR(EINVAL);
+
+ /* XXX Not yet finished */
+
+ SENDERR(EINVAL);
+
+ break;
default:
SENDERR(EINVAL);
}
+ if (buffer)
+ free(buffer, M_TEMP);
+
return error;
flush:
if (m)
m_freem(m);
+
+ if (buffer)
+ free(buffer, M_TEMP);
+
return error;
}
struct ifaddr *
encap_findgwifa(struct sockaddr *gw)
{
- struct sockaddr_encap *egw = (struct sockaddr_encap *)gw;
- u_char *op = (u_char *)gw;
- int i, j;
- struct ifaddr *retval = loif.if_addrlist.tqh_first;
- union
- {
- struct in_addr ia;
- u_char io[4];
- } iao;
-
- switch (egw->sen_type)
- {
- case SENT_IPSP:
- return enc_softc[egw->sen_ipsp_ifn].enc_if.if_addrlist.tqh_first;
- break;
-
- case SENT_IP4:
- /*
- * Pretty-much standard options walking code.
- * Repeated elsewhere as necessary
- */
-
- for (i = SENT_IP4_LEN; i < egw->sen_len;)
- switch (op[i])
- {
- case SENO_EOL:
- goto opt_done;
-
- case SENO_NOP:
- i++;
- continue;
-
- case SENO_IFN:
- if (op[i+1] != 3)
- {
- return NULL;
- }
- retval = enc_softc[op[i+2]].enc_if.if_addrlist.tqh_first;
- goto opt_done;
-
- case SENO_IFIP4A:
- if (op[i+1] != 6) /* XXX -- IPv4 address */
- {
- return NULL;
- }
- iao.io[0] = op[i+2];
- iao.io[1] = op[i+3];
- iao.io[2] = op[i+4];
- iao.io[3] = op[i+5];
-
- for (j = 0; j < nencap; j++)
- {
- struct ifaddr *ia = (struct ifaddr *)enc_softc[j].enc_if.if_addrlist.tqh_first;
-
- struct sockaddr_in *si = (struct sockaddr_in *)ia->ifa_addr;
-
- if ((si->sin_family == AF_INET) && (si->sin_addr.s_addr == iao.ia.s_addr))
- {
- retval = ia;
- goto opt_done;
- }
- }
- i += 6;
- break;
-
- default:
- if (op[i+1] == 0)
- return NULL;
- i += op[i+i];
- }
- opt_done:
- break;
- }
- return retval;
+ return enc_softc.if_addrlist.tqh_first;
}
diff --git a/sys/net/encap.h b/sys/net/encap.h
index d5b28c8a942..7305abd2a33 100644
--- a/sys/net/encap.h
+++ b/sys/net/encap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: encap.h,v 1.4 1997/06/25 07:53:20 provos Exp $ */
+/* $OpenBSD: encap.h,v 1.5 1997/07/01 22:12:40 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -46,7 +46,6 @@
* as far as the routing code is concerned.
*/
-
struct sockaddr_encap
{
u_int8_t sen_len; /* length */
@@ -55,19 +54,8 @@ struct sockaddr_encap
union
{
u_int8_t Data[16]; /* other stuff mapped here */
- struct sockaddr Dfl; /* SENT_DEFIF */
- struct /* SENT_SA */
- {
- struct sockaddr Src;
- struct sockaddr Dst;
- } Sa;
-#ifdef INET
- struct /* SENT_SAIN */
- {
- struct sockaddr_in Src;
- struct sockaddr_in Dst;
- } Sin;
- struct /* SENT_IP4 */
+
+ struct /* SENT_IP4 */
{
struct in_addr Src;
struct in_addr Dst;
@@ -76,36 +64,27 @@ struct sockaddr_encap
u_int8_t Proto;
u_int8_t Filler[3];
} Sip4;
- struct /* SENT_IPSP */
+
+ struct /* SENT_IPSP */
{
- struct in_addr Src;
struct in_addr Dst;
u_int32_t Spi;
- u_int8_t Ifn;
- u_int8_t Filler[3];
+ u_int8_t Filler[8];
} Sipsp;
-
-#endif
} Sen;
};
+#define PFENCAP_VERSION_0 0
+#define PFENCAP_VERSION_1 1
+
#define sen_data Sen.Data
-#define sen_dfl Sen.Dfl
-#define sen_sa_src Sen.Sa.Src
-#define sen_sa_dst Sen.Sa.Dst
-#ifdef INET
-#define sen_sin_src Sen.Sin.Src
-#define sen_sin_dst Sen.Sin.Dst
#define sen_ip_src Sen.Sip4.Src
#define sen_ip_dst Sen.Sip4.Dst
-#define sen_ipsp_src Sen.Sipsp.Src
-#define sen_ipsp_dst Sen.Sipsp.Dst
-#define sen_ipsp_spi Sen.Sipsp.Spi
-#define sen_ipsp_ifn Sen.Sipsp.Ifn
#define sen_proto Sen.Sip4.Proto
#define sen_sport Sen.Sip4.Sport
#define sen_dport Sen.Sip4.Dport
-#endif
+#define sen_ipsp_dst Sen.Sipsp.Dst
+#define sen_ipsp_spi Sen.Sipsp.Spi
/*
* The "type" is really part of the address as far as the routing
@@ -115,11 +94,8 @@ struct sockaddr_encap
*
*/
-#define SENT_DEFIF 0x0001 /* data is a default sockaddr for if */
-#define SENT_SA 0x0002 /* data is two struct sockaddr */
-#define SENT_SAIN 0x0004 /* data is two struct sockaddr_in */
-#define SENT_IP4 0x0008 /* data is two struct in_addr */
-#define SENT_IPSP 0x0010 /* data as in IP4 plus SPI and if# */
+#define SENT_IP4 0x0001 /* data is two struct in_addr */
+#define SENT_IPSP 0x0002 /* data as in IP4 plus SPI */
/*
* SENT_HDRLEN is the length of the "header"
@@ -127,79 +103,67 @@ struct sockaddr_encap
* SENT_*_OFF are the offsets in the sen_data array of various fields
*/
-#define SENT_HDRLEN (2*sizeof(u_int8_t)+sizeof(u_int16_t))
-
-#define SENT_DEFIF_LEN (SENT_HDRLEN + sizeof (struct sockaddr_in))
+#define SENT_HDRLEN (2 * sizeof(u_int8_t) + sizeof(u_int16_t))
#define SENT_IP4_SRCOFF (0)
#define SENT_IP4_DSTOFF (sizeof (struct in_addr))
-#define SENT_IP4_OPTOFF (2*sizeof(struct in_addr)+2*sizeof(u_int16_t)+sizeof(u_int8_t)+3*sizeof(u_int8_t))
-
-#define SENT_IP4_LEN (SENT_HDRLEN + SENT_IP4_OPTOFF)
-
-#define SENT_IPSP_LEN (SENT_HDRLEN + 2 * sizeof (struct in_addr) + sizeof (u_int32_t) + 4)
-
-/*
- * Options 0x00 and 01 are 1-byte options (no arguments).
- * The rest of the options are T-L-V fields, where the L includes
- * the T and L bytes; thus, the minimum length for an option with
- * no arguments is 2. An option of length less than 2 causes en EINVAL
- */
-
-#define SENO_EOL 0x00 /* End of Options, or placeholder */
-#define SENO_NOP 0x01 /* No Operation. Skip */
-#define SENO_NAME 0x02 /* tunnel name, NUL-terminated */
-#define SENO_SPI 0x03 /* Security Parameters Index */
-#define SENO_IFN 0x04 /* Encap interface number */
-#define SENO_IFIP4A 0x05 /* Encap interface IPv4 address */
-#define SENO_IPSA 0x06 /* Encap interface generic sockaddr */
-
-struct enc_softc
-{
- struct ifnet enc_if;
-};
+#define SENT_IP4_LEN 20
+#define SENT_IPSP_LEN 20
/*
* Tunnel descriptors are setup and torn down using a socket of the
* AF_ENCAP domain. The following defines the messages that can
* be sent down that socket.
*/
-
-#define EM_MAXRELSPIS 4 /* at most five chained xforms */
-
-
struct encap_msghdr
{
u_int16_t em_msglen; /* message length */
u_int8_t em_version; /* for future expansion */
u_int8_t em_type; /* message type */
+ u_int32_t foo; /* Alignment to 64 bit */
union
{
+ /*
+ * This is used to set/change the attributes of an SPI. If oSrc and
+ * oDst are set to non-zero values, the SPI will also do IP-in-IP
+ * encapsulation (tunneling). If only one of them is set, an error
+ * is returned. Both zero implies transport mode.
+ */
struct
{
- struct in_addr Ia;
- u_int8_t Ifn;
- u_int8_t xxx[3]; /* makes life a lot easier */
- } Ifa;
-
- struct
- {
- u_int32_t Spi; /* SPI */
+ u_int32_t Spi; /* SPI */
+ int32_t Alg; /* Algorithm to use */
struct in_addr Dst; /* Destination address */
- u_int64_t Relative_Hard; /* Expire relative to creation */
- u_int64_t Relative_Soft;
- u_int64_t First_Use_Hard; /* Expire relative to first use */
- u_int64_t First_Use_Soft;
- u_int64_t Expire_Hard; /* Expire at fixed point in time */
- u_int64_t Expire_Soft;
- u_int64_t Bytes_Hard; /* Expire after bytes recved/sent */
- u_int64_t Bytes_Soft;
- u_int64_t Packets_Hard; /* Expire after packets recved/sent */
- u_int64_t Packets_Soft;
- u_int32_t If; /* enc i/f for input */
- int32_t Alg; /* Algorithm to use */
- u_int8_t Dat[1]; /* Data */
+ struct in_addr Src; /* This is used to set our source
+ * address when doing tunneling and
+ * the outgoing packet does not
+ * have a source address (is zero) */
+ struct in_addr oSrc; /* Source... */
+ struct in_addr oDst; /* ...and destination in outter IP
+ * header, if we're doing IP-in-IP */
+ u_int64_t Relative_Hard; /* Expire relative to creation */
+ u_int64_t Relative_Soft;
+ u_int64_t First_Use_Hard; /* Expire relative to first use */
+ u_int64_t First_Use_Soft;
+ u_int64_t Expire_Hard; /* Expire at fixed point in time */
+ u_int64_t Expire_Soft;
+ u_int64_t Bytes_Hard; /* Expire after bytes recved/sent */
+ u_int64_t Bytes_Soft;
+ u_int64_t Packets_Hard; /* Expire after packets recved/sent */
+ u_int64_t Packets_Soft;
+ int32_t TTL; /* When tunneling, what TTL to use.
+ * If set to IP4_SAME_TTL, the ttl
+ * from the encapsulated packet will
+ * be copied. If set to IP4_DEFAULT_TTL,
+ * the system default TTL will be used.
+ * If set to anything else, then the
+ * ttl used will be TTL % 256 */
+ u_int16_t Sport; /* Source port, if applicable */
+ u_int16_t Dport; /* Destination port, if applicable */
+ u_int8_t Proto; /* Protocol, if applicable */
+ u_int8_t foo[3]; /* Alignment */
+ u_int8_t Dat[1]; /* Data */
} Xfm;
/*
@@ -217,54 +181,65 @@ struct encap_msghdr
*/
struct /* kernel->userland notifications */
{
- u_int32_t Notification_Type;
-#define NOTIFY_SOFT_EXPIRE 0 /* Soft expiration of SA */
-#define NOTIFY_HARD_EXPIRE 1 /* Hard expiration of SA */
-#define NOTIFY_REQUEST_SA 2 /* Establish an SA */
- u_int32_t MsgID; /* Request ID */
- u_int32_t Spi;
- u_int32_t Spi2;
- u_int32_t Spi3;
- u_int8_t Seclevel[3]; /* see netinet/in_pcb.h */
- u_int8_t Protocol; /* Transport mode for which protocol */
+ u_int32_t Notification_Type;
+ u_int32_t MsgID; /* Request ID */
+ u_int32_t Spi;
+ u_int32_t Spi2;
+ u_int32_t Spi3;
+ u_int8_t Seclevel[3]; /* see netinet/in_pcb.h */
+ u_int8_t Protocol; /* Transport mode for which protocol */
struct in_addr Dst; /* Peer */
struct in_addr Src; /* Might have our local address */
- u_int16_t Sport; /* Source port */
- u_int16_t Dport; /* Destination port */
- u_int8_t UserID[1]; /* Might be used to indicate user */
+ u_int16_t Sport; /* Source port */
+ u_int16_t Dport; /* Destination port */
+ u_int8_t UserID[1]; /* Might be used to indicate user */
} Notify;
-
+
+ /* Link two SPIs */
struct
{
- u_int32_t emr_spi; /* SPI */
- struct in_addr emr_dst; /* Dest */
- struct tdb *emr_tdb; /* used internally! */
-
- } Rel[EM_MAXRELSPIS];
+ u_int32_t emr_spi; /* SPI */
+ u_int32_t emr_spi2;
+ struct in_addr emr_dst; /* Dest */
+ struct in_addr emr_dst2;
+ } Rel;
+
+ /* For general use */
+ struct
+ {
+ u_int32_t emg_spi;
+ struct in_addr emg_dst;
+ } Gen;
} Eu;
};
-#define em_not_type Eu.Notify.Notification_Type
-#define em_not_spi Eu.Notify.Spi
-#define em_not_spi2 Eu.Notify.Spi2
-#define em_not_spi3 Eu.Notify.Spi3
-#define em_not_src Eu.Notify.Src
-#define em_not_dst Eu.Notify.Dst
-#define em_not_seclevel Eu.Notify.Seclevel
-#define em_not_userid Eu.Notify.UserID
-#define em_not_msgid Eu.Notify.MsgID
-#define em_not_sport Eu.Notify.Sport
-#define em_not_dport Eu.Notify.Dport
-#define em_not_protocol Eu.Notify.Protocol
+#define NOTIFY_SOFT_EXPIRE 0 /* Soft expiration of SA */
+#define NOTIFY_HARD_EXPIRE 1 /* Hard expiration of SA */
+#define NOTIFY_REQUEST_SA 2 /* Establish an SA */
+
+#define em_gen_spi Eu.Gen.emg_spi
+#define em_gen_dst Eu.Gen.emg_dst
-#define em_ifa Eu.Ifa.Ia
-#define em_ifn Eu.Ifa.Ifn
+#define em_not_type Eu.Notify.Notification_Type
+#define em_not_spi Eu.Notify.Spi
+#define em_not_spi2 Eu.Notify.Spi2
+#define em_not_spi3 Eu.Notify.Spi3
+#define em_not_dst Eu.Notify.Dst
+#define em_not_seclevel Eu.Notify.Seclevel
+#define em_not_userid Eu.Notify.UserID
+#define em_not_msgid Eu.Notify.MsgID
+#define em_not_sport Eu.Notify.Sport
+#define em_not_dport Eu.Notify.Dport
+#define em_not_protocol Eu.Notify.Protocol
-#define em_spi Eu.Xfm.Spi
-#define em_dst Eu.Xfm.Dst
-#define em_if Eu.Xfm.If
-#define em_alg Eu.Xfm.Alg
-#define em_dat Eu.Xfm.Dat
+#define em_spi Eu.Xfm.Spi
+#define em_dst Eu.Xfm.Dst
+#define em_src Eu.Xfm.Src
+#define em_osrc Eu.Xfm.oSrc
+#define em_odst Eu.Xfm.oDst
+#define em_if Eu.Xfm.If
+#define em_alg Eu.Xfm.Alg
+#define em_dat Eu.Xfm.Dat
#define em_relative_hard Eu.Xfm.Relative_Hard
#define em_relative_soft Eu.Xfm.Relative_Soft
#define em_first_use_hard Eu.Xfm.First_Use_Hard
@@ -275,28 +250,37 @@ struct encap_msghdr
#define em_bytes_soft Eu.Xfm.Bytes_Soft
#define em_packets_hard Eu.Xfm.Packets_Hard
#define em_packets_soft Eu.Xfm.Packets_Soft
+#define em_ttl Eu.Xfm.TTL
+#define em_proto Eu.Xfm.Proto
+#define em_sport Eu.Xfm.Sport
+#define em_dport Eu.Xfm.Dport
-#define em_rel Eu.Rel
+#define em_rel_spi Eu.Rel.emr_spi
+#define em_rel_spi2 Eu.Rel.emr_spi2
+#define em_rel_dst Eu.Rel.emr_dst
+#define em_rel_dst2 Eu.Rel.emr_dst2
-#define EMT_IFADDR 1 /* set enc if addr */
-#define EMT_SETSPI 2 /* Set SPI properties */
-#define EMT_GRPSPIS 3 /* Group SPIs (output order) */
-#define EMT_DELSPI 4 /* delete an SPI */
-#define EMT_DELSPICHAIN 5 /* delete an SPI chain starting from */
-#define EMT_RESERVESPI 6 /* Give us an SPI */
-#define EMT_ENABLESPI 7 /* Enable an SA */
-#define EMT_DISABLESPI 8 /* Disable an SA */
-#define EMT_NOTIFY 9 /* kernel->userland key mgmt not. */
+#define EMT_SETSPI 1 /* Set SPI properties */
+#define EMT_GRPSPIS 2 /* Group SPIs (output order) */
+#define EMT_DELSPI 3 /* delete an SPI */
+#define EMT_DELSPICHAIN 4 /* delete an SPI chain starting from */
+#define EMT_RESERVESPI 5 /* Give us an SPI */
+#define EMT_ENABLESPI 6 /* Enable an SA */
+#define EMT_DISABLESPI 7 /* Disable an SA */
+#define EMT_NOTIFY 8 /* kernel->userland key mgmt not. */
-#define EM_MINLEN 8 /* count!!! */
-#define EMT_IFADDR_LEN 12
-#define EMT_SETSPI_FLEN 20
-#define EMT_GRPSPIS_FLEN 4
-#define EMT_DELSPI_FLEN 20
-#define EMT_DELSPICHAIN_FLEN 20
+/* Total packet lengths */
+#define EMT_SETSPI_FLEN 124
+#define EMT_GRPSPIS_FLEN 20
+#define EMT_GENLEN 12
+#define EMT_DELSPI_FLEN EMT_GENLEN
+#define EMT_DELSPICHAIN_FLEN EMT_GENLEN
+#define EMT_ENABLESPI_FLEN EMT_GENLEN
+#define EMT_DISABLESPI_FLEN EMT_GENLEN
+#define EMT_RESERVESPI_FLEN EMT_GENLEN
+#define EMT_NOTIFY_FLEN 40
#ifdef _KERNEL
extern struct ifaddr *encap_findgwifa(struct sockaddr *);
-extern struct enc_softc *enc_softc;
-extern int32_t nencap;
+extern struct ifnet enc_softc;
#endif
diff --git a/sys/net/if_enc.c b/sys/net/if_enc.c
index 1f6d8e8509f..0f0cff17d8c 100644
--- a/sys/net/if_enc.c
+++ b/sys/net/if_enc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_enc.c,v 1.3 1997/02/27 04:05:45 angelos Exp $ */
+/* $OpenBSD: if_enc.c,v 1.4 1997/07/01 22:12:39 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -62,18 +62,7 @@ extern struct ifqueue nsintrq;
#define ENCMTU (1024+512)
-/*
- * Called from boot code to establish enc interfaces.
- */
-
-struct enc_softc
-{
- struct ifnet enc_if;
-} ;
-
-struct enc_softc *enc_softc;
-
-int nencap;
+struct ifnet enc_softc;
void encattach __P((int));
int encoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *,
@@ -84,30 +73,37 @@ void encrtrequest __P((int, struct rtentry *, struct sockaddr *));
void
encattach(int nenc)
{
- register struct enc_softc *enc;
- register int i = 0;
+ struct ifaddr *ifa;
+
+ bzero(&enc_softc, sizeof(struct ifnet));
+
+ /* We only need one interface anyway under the new mode of operation */
+ enc_softc.if_index = 0;
+
+ sprintf(enc_softc.if_xname, "enc0");
+
+ enc_softc.if_list.tqe_next = NULL;
+ enc_softc.if_mtu = ENCMTU;
+ enc_softc.if_flags = IFF_LOOPBACK;
+ enc_softc.if_type = IFT_ENC;
+ enc_softc.if_ioctl = encioctl;
+ enc_softc.if_output = encoutput;
+ enc_softc.if_hdrlen = 0;
+ enc_softc.if_addrlen = 0;
+
+ if_attach(&enc_softc);
- nencap = nenc;
-
- enc_softc = malloc(nenc * sizeof (*enc_softc), M_DEVBUF, M_WAIT);
- bzero(enc_softc, nenc * sizeof (*enc_softc));
- for (enc = enc_softc; i < nenc; enc++)
- {
- enc->enc_if.if_index = i;
- sprintf(enc->enc_if.if_xname, "enc%d", i++);
- enc->enc_if.if_list.tqe_next = NULL;
- enc->enc_if.if_mtu = ENCMTU;
- enc->enc_if.if_flags = IFF_LOOPBACK;
- enc->enc_if.if_type = IFT_ENC;
- enc->enc_if.if_ioctl = encioctl;
- enc->enc_if.if_output = encoutput;
- enc->enc_if.if_hdrlen = 0;
- enc->enc_if.if_addrlen = 0;
- if_attach(&enc->enc_if);
#if NBPFILTER > 0
- bpfattach(&enc->enc_if.if_bpf, &enc->enc_if, DLT_NULL, sizeof(u_int));
+ bpfattach(&(enc_softc.if_bpf), &enc_softc, DLT_NULL, sizeof(u_int32_t));
#endif
- }
+
+ /* Just a bogus entry */
+ ifa = (struct ifaddr *)malloc(sizeof(struct ifaddr) +
+ sizeof(struct sockaddr), M_IFADDR, M_WAITOK);
+ bzero(ifa, sizeof(struct ifaddr) + sizeof(struct sockaddr));
+ ifa->ifa_addr = ifa->ifa_dstaddr = (struct sockaddr *)(ifa + 1);
+ ifa->ifa_ifp = &enc_softc;
+ TAILQ_INSERT_HEAD(&(enc_softc.if_addrlist), ifa, ifa_list);
}
/*
@@ -120,93 +116,106 @@ register struct mbuf *m;
struct sockaddr *dst;
register struct rtentry *rt;
{
- int s, isr;
- register struct ifqueue *ifq = 0;
+ register struct ifqueue *ifq = 0;
+ int s, isr;
+
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("encoutput no HDR");
+
+ ifp->if_lastchange = time;
- /* register struct enc_softc *ec = &enc_softc[ifp->if_index]; */
-
- if ((m->m_flags & M_PKTHDR) == 0)
- panic("encoutput no HDR");
- ifp->if_lastchange = time;
#if NBPFILTER > 0
- if (ifp->if_bpf) {
- /*
- * We need to prepend the address family as
- * a four byte field. Cons up a dummy header
- * to pacify bpf. This is safe because bpf
- * will only read from the mbuf (i.e., it won't
- * try to free it or keep a pointer a to it).
- */
- struct mbuf m0;
- u_int af = dst->sa_family;
-
- m0.m_next = m;
- m0.m_len = 4;
- m0.m_data = (char *)&af;
-
- bpf_mtap(ifp->if_bpf, &m0);
- }
+ if (ifp->if_bpf)
+ {
+ /*
+ * We need to prepend the address family as
+ * a four byte field. Cons up a dummy header
+ * to pacify bpf. This is safe because bpf
+ * will only read from the mbuf (i.e., it won't
+ * try to free it or keep a pointer a to it).
+ */
+ struct mbuf m0;
+ u_int af = dst->sa_family;
+
+ m0.m_next = m;
+ m0.m_len = 4;
+ m0.m_data = (char *)&af;
+
+ bpf_mtap(ifp->if_bpf, &m0);
+ }
#endif
- m->m_pkthdr.rcvif = ifp;
- if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
- m_freem(m);
- return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
- rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
- }
- ifp->if_opackets++;
- ifp->if_obytes += m->m_pkthdr.len;
- switch (dst->sa_family) {
+ m->m_pkthdr.rcvif = ifp;
+
+ if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE))
+ {
+ m_freem(m);
+ return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
+ rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
+ }
+ ifp->if_opackets++;
+ ifp->if_obytes += m->m_pkthdr.len;
+
+ switch (dst->sa_family)
+ {
#ifdef INET
case AF_INET:
- ifq = &ipintrq;
- isr = NETISR_IP;
- break;
+ ifq = &ipintrq;
+ isr = NETISR_IP;
+ break;
#endif
#ifdef NS
case AF_NS:
- ifq = &nsintrq;
- isr = NETISR_NS;
- break;
+ ifq = &nsintrq;
+ isr = NETISR_NS;
+ break;
#endif
#ifdef ISO
case AF_ISO:
- ifq = &clnlintrq;
- isr = NETISR_ISO;
+ ifq = &clnlintrq;
+ isr = NETISR_ISO;
break;
#endif
default:
- m_freem(m);
- return (EAFNOSUPPORT);
- }
- s = splimp();
- if (IF_QFULL(ifq)) {
- IF_DROP(ifq);
- m_freem(m);
- splx(s);
- return (ENOBUFS);
- }
- IF_ENQUEUE(ifq, m);
- schednetisr(isr);
- ifp->if_ipackets++;
- ifp->if_ibytes += m->m_pkthdr.len;
+ m_freem(m);
+ return (EAFNOSUPPORT);
+ }
+
+ s = splimp();
+
+ if (IF_QFULL(ifq))
+ {
+ IF_DROP(ifq);
+ m_freem(m);
splx(s);
- return (0);
+ return (ENOBUFS);
+ }
+
+ IF_ENQUEUE(ifq, m);
+ schednetisr(isr);
+
+ /* Statistics */
+ ifp->if_ipackets++;
+ ifp->if_ibytes += m->m_pkthdr.len;
+
+ splx(s);
+
+ return (0);
}
/* ARGSUSED */
void
encrtrequest(cmd, rt, sa)
- int cmd;
- struct rtentry *rt;
- struct sockaddr *sa;
+int cmd;
+struct rtentry *rt;
+struct sockaddr *sa;
{
-
- if (rt)
- rt->rt_rmx.rmx_mtu = ENCMTU;
+ if (rt)
+ rt->rt_rmx.rmx_mtu = ENCMTU;
}
+
/*
* Process an ioctl request.
* Also shamelessly stolen from loioctl()
@@ -215,41 +224,28 @@ encrtrequest(cmd, rt, sa)
/* ARGSUSED */
int
encioctl(ifp, cmd, data)
- register struct ifnet *ifp;
- u_long cmd;
- caddr_t data;
+register struct ifnet *ifp;
+u_long cmd;
+caddr_t data;
{
- register struct ifaddr *ifa;
- register struct ifreq *ifr;
- register int error = 0;
-
- switch (cmd)
- {
- case SIOCSIFADDR:
- ifp->if_flags |= IFF_UP;
- ifa = (struct ifaddr *)data;
- /*
- * Everything else is done at a higher level.
- */
- break;
+ register struct ifaddr *ifa;
+ register int error = 0;
- switch (ifr->ifr_addr.sa_family) {
+ switch (cmd)
+ {
+ case SIOCSIFADDR:
+ /*
+ * Everything else is done at a higher level.
+ */
-#ifdef INET
- case AF_INET:
- break;
-#endif
- case AF_ENCAP:
- break;
-
- default:
- error = EAFNOSUPPORT;
- break;
- }
- break;
+ ifp->if_flags |= IFF_UP;
+ ifa = (struct ifaddr *)data;
+
+ break;
+
+ default:
+ error = EINVAL;
+ }
- default:
- error = EINVAL;
- }
- return error;
+ return error;
}
diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c
index d012fbdeba8..1e5cdddc26b 100644
--- a/sys/netinet/ip_ah.c
+++ b/sys/netinet/ip_ah.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ah.c,v 1.6 1997/06/25 07:53:21 provos Exp $ */
+/* $OpenBSD: ip_ah.c,v 1.7 1997/07/01 22:12:41 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -145,7 +145,7 @@ ah_input(register struct mbuf *m, int iphlen)
return;
}
- m->m_pkthdr.rcvif = tdbp->tdb_rcvif;
+ m->m_pkthdr.rcvif = &enc_softc;
/* Register first use */
if (tdbp->tdb_first_use == 0)
diff --git a/sys/netinet/ip_ahhmacmd5.c b/sys/netinet/ip_ahhmacmd5.c
index 3a3bd949caf..55284cd715e 100644
--- a/sys/netinet/ip_ahhmacmd5.c
+++ b/sys/netinet/ip_ahhmacmd5.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ahhmacmd5.c,v 1.12 1997/06/25 07:53:22 provos Exp $ */
+/* $OpenBSD: ip_ahhmacmd5.c,v 1.13 1997/07/01 22:12:42 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -374,7 +374,8 @@ ahhmacmd5_input(struct mbuf *m, struct tdb *tdb)
#define AHXPORT
int
-ahhmacmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp)
+ahhmacmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
+ struct mbuf **mp)
{
struct ahhmacmd5_xdata *xd;
struct ip *ip, ipo;
diff --git a/sys/netinet/ip_ahhmacsha1.c b/sys/netinet/ip_ahhmacsha1.c
index ac9b056a010..9e3fa61bdb9 100644
--- a/sys/netinet/ip_ahhmacsha1.c
+++ b/sys/netinet/ip_ahhmacsha1.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ahhmacsha1.c,v 1.10 1997/06/25 07:53:22 provos Exp $ */
+/* $OpenBSD: ip_ahhmacsha1.c,v 1.11 1997/07/01 22:12:43 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -377,7 +377,8 @@ ahhmacsha1_input(struct mbuf *m, struct tdb *tdb)
#define AHXPORT
int
-ahhmacsha1_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp)
+ahhmacsha1_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
+ struct mbuf **mp)
{
struct ahhmacsha1_xdata *xd;
struct ip *ip, ipo;
diff --git a/sys/netinet/ip_ahmd5.c b/sys/netinet/ip_ahmd5.c
index e19b596f172..f3d406dcd8f 100644
--- a/sys/netinet/ip_ahmd5.c
+++ b/sys/netinet/ip_ahmd5.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ahmd5.c,v 1.9 1997/06/25 07:53:23 provos Exp $ */
+/* $OpenBSD: ip_ahmd5.c,v 1.10 1997/07/01 22:12:44 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -99,6 +99,7 @@ ahmd5_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m)
}
m_copydata(m, EMT_SETSPI_FLEN, em->em_msglen - EMT_SETSPI_FLEN,
(caddr_t)xd);
+
bzero(ipseczeroes, IPSEC_ZEROES_SIZE); /* paranoid */
return 0;
}
@@ -294,7 +295,8 @@ ahmd5_input(struct mbuf *m, struct tdb *tdb)
#define AHXPORT
int
-ahmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp)
+ahmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
+ struct mbuf **mp)
{
struct ahmd5_xdata *xd;
struct ip *ip, ipo;
diff --git a/sys/netinet/ip_ahsha1.c b/sys/netinet/ip_ahsha1.c
index 61bece49bc2..6aa40c07612 100644
--- a/sys/netinet/ip_ahsha1.c
+++ b/sys/netinet/ip_ahsha1.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ahsha1.c,v 1.5 1997/06/25 07:53:23 provos Exp $ */
+/* $OpenBSD: ip_ahsha1.c,v 1.6 1997/07/01 22:12:45 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -293,7 +293,8 @@ ahsha1_input(struct mbuf *m, struct tdb *tdb)
#define AHXPORT
int
-ahsha1_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp)
+ahsha1_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
+ struct mbuf **mp)
{
struct ahsha1_xdata *xd;
struct ip *ip, ipo;
diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c
index dad0caaaa96..fc3f12bd412 100644
--- a/sys/netinet/ip_esp.c
+++ b/sys/netinet/ip_esp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_esp.c,v 1.6 1997/06/25 07:53:24 provos Exp $ */
+/* $OpenBSD: ip_esp.c,v 1.7 1997/07/01 22:12:45 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -142,7 +142,7 @@ esp_input(register struct mbuf *m, int iphlen)
return;
}
- m->m_pkthdr.rcvif = tdbp->tdb_rcvif;
+ m->m_pkthdr.rcvif = &enc_softc;
/* Register first use */
if (tdbp->tdb_first_use == 0)
diff --git a/sys/netinet/ip_esp3des.c b/sys/netinet/ip_esp3des.c
index 175a2594c8a..9489f6c9f51 100644
--- a/sys/netinet/ip_esp3des.c
+++ b/sys/netinet/ip_esp3des.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_esp3des.c,v 1.6 1997/06/25 07:53:25 provos Exp $ */
+/* $OpenBSD: ip_esp3des.c,v 1.7 1997/07/01 22:12:46 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -307,7 +307,8 @@ esp3des_input(struct mbuf *m, struct tdb *tdb)
}
int
-esp3des_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp)
+esp3des_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
+ struct mbuf **mp)
{
struct esp3des_xdata *xd;
struct ip *ip, ipo;
diff --git a/sys/netinet/ip_esp3desmd5.c b/sys/netinet/ip_esp3desmd5.c
index d52969c457b..3bfe161f2f2 100644
--- a/sys/netinet/ip_esp3desmd5.c
+++ b/sys/netinet/ip_esp3desmd5.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_esp3desmd5.c,v 1.10 1997/06/25 07:53:25 provos Exp $ */
+/* $OpenBSD: ip_esp3desmd5.c,v 1.11 1997/07/01 22:12:47 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -517,7 +517,8 @@ esp3desmd5_input(struct mbuf *m, struct tdb *tdb)
}
int
-esp3desmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp)
+esp3desmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
+ struct mbuf **mp)
{
struct esp3desmd5_xdata *xd;
struct ip *ip, ipo;
diff --git a/sys/netinet/ip_espdes.c b/sys/netinet/ip_espdes.c
index d0b925c4aa0..cfbd603b514 100644
--- a/sys/netinet/ip_espdes.c
+++ b/sys/netinet/ip_espdes.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_espdes.c,v 1.8 1997/06/25 07:53:26 provos Exp $ */
+/* $OpenBSD: ip_espdes.c,v 1.9 1997/07/01 22:12:48 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -294,7 +294,8 @@ espdes_input(struct mbuf *m, struct tdb *tdb)
}
int
-espdes_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp)
+espdes_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
+ struct mbuf **mp)
{
struct espdes_xdata *xd;
struct ip *ip, ipo;
diff --git a/sys/netinet/ip_espdesmd5.c b/sys/netinet/ip_espdesmd5.c
index 2700e34b888..4e50b1d6501 100644
--- a/sys/netinet/ip_espdesmd5.c
+++ b/sys/netinet/ip_espdesmd5.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_espdesmd5.c,v 1.10 1997/06/25 07:53:26 provos Exp $ */
+/* $OpenBSD: ip_espdesmd5.c,v 1.11 1997/07/01 22:12:49 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -501,7 +501,8 @@ espdesmd5_input(struct mbuf *m, struct tdb *tdb)
}
int
-espdesmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp)
+espdesmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
+ struct mbuf **mp)
{
struct espdesmd5_xdata *xd;
struct ip *ip, ipo;
diff --git a/sys/netinet/ip_ip4.c b/sys/netinet/ip_ip4.c
index ff113083e91..ee878138a39 100644
--- a/sys/netinet/ip_ip4.c
+++ b/sys/netinet/ip_ip4.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ip4.c,v 1.9 1997/06/25 07:53:27 provos Exp $ */
+/* $OpenBSD: ip_ip4.c,v 1.10 1997/07/01 22:12:49 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -155,10 +155,10 @@ ip4_input(register struct mbuf *m, int iphlen)
}
int
-ipe4_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct mbuf **mp)
+ipe4_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb,
+ struct mbuf **mp)
{
struct ip *ipo, *ipi;
- struct ip4_xdata *xd;
ushort ilen;
ip4stat.ip4s_opackets++;
@@ -178,23 +178,19 @@ ipe4_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct m
/* ipo->ip_id = htons(ip_id++); */
get_random_bytes((void *)&(ipo->ip_id), sizeof(ipo->ip_id));
ipo->ip_off = ipi->ip_off & ~(IP_MF | IP_OFFMASK); /* keep C and DF */
- xd = (struct ip4_xdata *)tdb->tdb_xdata;
- switch (xd->ip4_ttl)
- {
- case IP4_SAME_TTL:
- ipo->ip_ttl = ipi->ip_ttl;
- break;
- case IP4_DEFAULT_TTL:
- ipo->ip_ttl = ip_defttl;
- break;
- default:
- ipo->ip_ttl = xd->ip4_ttl;
- }
+
+ if (tdb->tdb_flags & TDBF_SAME_TTL)
+ ipo->ip_ttl = ipi->ip_ttl;
+ else
+ if (tdb->tdb_ttl == 0)
+ ipo->ip_ttl = ip_defttl;
+ else
+ ipi->ip_ttl = tdb->tdb_ttl;
ipo->ip_p = IPPROTO_IPIP;
ipo->ip_sum = 0;
- ipo->ip_src = gw->sen_ipsp_src;
- ipo->ip_dst = gw->sen_ipsp_dst;
+ ipo->ip_src = tdb->tdb_osrc;
+ ipo->ip_dst = tdb->tdb_odst;
/*
* printf("ip4_output: [%x->%x](l=%d, p=%d)",
@@ -208,8 +204,11 @@ ipe4_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, struct m
*mp = m;
/* Update the counters */
- tdb->tdb_cur_packets++;
- tdb->tdb_cur_bytes += ntohs(ipo->ip_len) - (ipo->ip_hl << 2);
+ if (tdb->tdb_xform->xf_type == XF_IP4)
+ {
+ tdb->tdb_cur_packets++;
+ tdb->tdb_cur_bytes += ntohs(ipo->ip_len) - (ipo->ip_hl << 2);
+ }
return 0;
@@ -225,39 +224,17 @@ ipe4_attach()
int
ipe4_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m)
{
- struct ip4_xdata *xd;
- struct ip4_xencap txd;
- struct encap_msghdr *em;
-
#ifdef ENCDEBUG
if (encdebug)
printf("ipe4_init: setting up\n");
#endif
tdbp->tdb_xform = xsp;
- MALLOC(tdbp->tdb_xdata, caddr_t, sizeof (struct ip4_xdata), M_XDATA,
- M_WAITOK);
- if (tdbp->tdb_xdata == NULL)
- return ENOBUFS;
- bzero(tdbp->tdb_xdata, sizeof (struct ip4_xdata));
- xd = (struct ip4_xdata *)tdbp->tdb_xdata;
-
- em = mtod(m, struct encap_msghdr *);
- if (em->em_msglen - EMT_SETSPI_FLEN > sizeof (struct ip4_xencap))
- {
- free((caddr_t)tdbp->tdb_xdata, M_XDATA);
- tdbp->tdb_xdata = NULL;
- return EINVAL;
- }
- m_copydata(m, EMT_SETSPI_FLEN, em->em_msglen - EMT_SETSPI_FLEN,
- (caddr_t)&txd);
- xd->ip4_ttl = txd.ip4_ttl;
return 0;
}
int
ipe4_zeroize(struct tdb *tdbp)
{
- FREE(tdbp->tdb_xdata, M_XDATA);
return 0;
}
diff --git a/sys/netinet/ip_ip4.h b/sys/netinet/ip_ip4.h
index d489d3c1dc3..fd9d3d40070 100644
--- a/sys/netinet/ip_ip4.h
+++ b/sys/netinet/ip_ip4.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ip4.h,v 1.6 1997/06/25 07:53:27 provos Exp $ */
+/* $OpenBSD: ip_ip4.h,v 1.7 1997/07/01 22:12:50 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -28,16 +28,6 @@
* Not quite all the functionality of RFC-1853, but the main idea is there.
*/
-struct ip4_xdata
-{
- int32_t ip4_ttl;
-};
-
-struct ip4_xencap
-{
- int32_t ip4_ttl;
-};
-
struct ip4stat
{
u_int32_t ip4s_ipackets; /* total input packets */
@@ -48,8 +38,8 @@ struct ip4stat
u_int32_t ip4s_qfull;
};
-#define IP4_SAME_TTL 0
-#define IP4_DEFAULT_TTL -1
+#define IP4_DEFAULT_TTL 0
+#define IP4_SAME_TTL -1
#ifdef _KERNEL
struct ip4stat ip4stat;
diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c
index 99bbddb5ebe..f49eef36ff3 100644
--- a/sys/netinet/ip_ipsp.c
+++ b/sys/netinet/ip_ipsp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.c,v 1.10 1997/06/25 07:53:28 provos Exp $ */
+/* $OpenBSD: ip_ipsp.c,v 1.11 1997/07/01 22:12:51 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -71,34 +71,36 @@ int encdebug = 1;
*/
struct xformsw xformsw[] = {
- { XF_IP4, 0, "IPv4 Simple Encapsulation",
- ipe4_attach, ipe4_init, ipe4_zeroize,
+ { XF_IP4, 0, "IPv4 Simple Encapsulation",
+ ipe4_attach, ipe4_init, ipe4_zeroize,
(struct mbuf * (*)(struct mbuf *, struct tdb *))ipe4_input,
ipe4_output, },
- { XF_AHMD5, XFT_AUTH, "Keyed MD5 Authentication",
- ahmd5_attach, ahmd5_init, ahmd5_zeroize,
- ahmd5_input, ahmd5_output, },
- { XF_AHSHA1, XFT_AUTH, "Keyed SHA1 Authentication",
- ahsha1_attach, ahsha1_init, ahsha1_zeroize,
- ahsha1_input, ahsha1_output, },
- { XF_ESPDES, XFT_CONF, "DES-CBC Encryption",
- espdes_attach, espdes_init, espdes_zeroize,
- espdes_input, espdes_output, },
- { XF_ESP3DES, XFT_CONF, "3DES-CBC Encryption",
- esp3des_attach, esp3des_init, esp3des_zeroize,
- esp3des_input, esp3des_output, },
- { XF_AHHMACMD5, XFT_AUTH, "HMAC MD5 Authentication",
- ahhmacmd5_attach, ahhmacmd5_init, ahhmacmd5_zeroize,
- ahhmacmd5_input, ahhmacmd5_output, },
- { XF_AHHMACSHA1, XFT_AUTH, "HMAC SHA1 Authentication",
- ahhmacsha1_attach, ahhmacsha1_init, ahhmacsha1_zeroize,
- ahhmacsha1_input, ahhmacsha1_output, },
- { XF_ESPDESMD5, XFT_CONF|XFT_AUTH, "DES-CBC Encryption + MD5 Authentication",
- espdesmd5_attach, espdesmd5_init, espdesmd5_zeroize,
- espdesmd5_input, espdesmd5_output, },
- { XF_ESP3DESMD5, XFT_CONF|XFT_AUTH, "3DES-CBC Encryption + MD5 Authentication",
- esp3desmd5_attach, esp3desmd5_init, esp3desmd5_zeroize,
- esp3desmd5_input, esp3desmd5_output, },
+ { XF_AHMD5, XFT_AUTH, "Keyed MD5 Authentication",
+ ahmd5_attach, ahmd5_init, ahmd5_zeroize,
+ ahmd5_input, ahmd5_output, },
+ { XF_AHSHA1, XFT_AUTH, "Keyed SHA1 Authentication",
+ ahsha1_attach, ahsha1_init, ahsha1_zeroize,
+ ahsha1_input, ahsha1_output, },
+ { XF_ESPDES, XFT_CONF, "DES-CBC Encryption",
+ espdes_attach, espdes_init, espdes_zeroize,
+ espdes_input, espdes_output, },
+ { XF_ESP3DES, XFT_CONF, "3DES-CBC Encryption",
+ esp3des_attach, esp3des_init, esp3des_zeroize,
+ esp3des_input, esp3des_output, },
+ { XF_AHHMACMD5, XFT_AUTH, "HMAC MD5 Authentication",
+ ahhmacmd5_attach, ahhmacmd5_init, ahhmacmd5_zeroize,
+ ahhmacmd5_input, ahhmacmd5_output, },
+ { XF_AHHMACSHA1, XFT_AUTH, "HMAC SHA1 Authentication",
+ ahhmacsha1_attach, ahhmacsha1_init, ahhmacsha1_zeroize,
+ ahhmacsha1_input, ahhmacsha1_output, },
+ { XF_ESPDESMD5, XFT_CONF|XFT_AUTH,
+ "DES-CBC Encryption + MD5 Authentication",
+ espdesmd5_attach, espdesmd5_init, espdesmd5_zeroize,
+ espdesmd5_input, espdesmd5_output, },
+ { XF_ESP3DESMD5, XFT_CONF|XFT_AUTH,
+ "3DES-CBC Encryption + MD5 Authentication",
+ esp3desmd5_attach, esp3desmd5_init, esp3desmd5_zeroize,
+ esp3desmd5_input, esp3desmd5_output, },
};
struct xformsw *xformswNXFORMSW = &xformsw[sizeof(xformsw)/sizeof(xformsw[0])];
@@ -111,7 +113,7 @@ int ipspkernfs_dirty = 1;
/*
* Reserve an SPI; the SA is not valid yet though. Zero is reserved as
* an error return value. If tspi is not zero, we try to allocate that
- * SPI.
+ * SPI. SPIs less than 255 are reserved, so we check for those too.
*/
u_int32_t
@@ -122,7 +124,7 @@ reserve_spi(u_int32_t tspi, struct in_addr src)
while (1)
{
- while (spi == 0) /* Get a new SPI */
+ while (spi <= 255) /* Get a new SPI */
get_random_bytes((void *)&spi, sizeof(spi));
/* Check whether we're using this SPI already */
@@ -247,6 +249,9 @@ tdb_init(struct tdb *tdbp, struct mbuf *m)
return EINVAL;
}
+/*
+ * XXX This should change to something cleaner.
+ */
int
ipsp_kern(int off, char **bufp, int len)
{
@@ -277,10 +282,6 @@ ipsp_kern(int off, char **bufp, int len)
/* Being paranoid to avoid buffer overflows */
k += 126 + strlen(tdbp->tdb_xform->xf_name);
- if (tdbp->tdb_rcvif)
- k += strlen(tdbp->tdb_rcvif->if_xname);
- else
- k += 4;
}
if (k == 0)
@@ -295,10 +296,9 @@ ipsp_kern(int off, char **bufp, int len)
{
b = (char *)&(tdbp->tdb_dst.s_addr);
k += sprintf(ipspkernfs + k,
- "SPI=%x, destination=%d.%d.%d.%d, interface=%s\n algorithm=%d (%s)\n next SPI=%x, previous SPI=%x\n",
+ "SPI=%x, destination=%d.%d.%d.%d\n algorithm=%d (%s)\n next SPI=%x, previous SPI=%x\n",
ntohl(tdbp->tdb_spi), ((int)b[0] & 0xff), ((int)b[1] & 0xff),
((int)b[2] & 0xff), ((int)b[3] & 0xff),
- (tdbp->tdb_rcvif ? tdbp->tdb_rcvif->if_xname : "none"),
tdbp->tdb_xform->xf_type, tdbp->tdb_xform->xf_name,
(tdbp->tdb_onext ? ntohl(tdbp->tdb_onext->tdb_spi) : 0),
(tdbp->tdb_inext ? ntohl(tdbp->tdb_inext->tdb_spi) : 0));
diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h
index 2bf82d5b554..8d7c65e7ae3 100644
--- a/sys/netinet/ip_ipsp.h
+++ b/sys/netinet/ip_ipsp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.h,v 1.8 1997/06/25 07:53:28 provos Exp $ */
+/* $OpenBSD: ip_ipsp.h,v 1.9 1997/07/01 22:12:52 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -32,6 +32,7 @@ struct tdb /* tunnel descriptor block */
struct tdb *tdb_hnext; /* next in hash chain */
struct tdb *tdb_onext; /* next in output */
struct tdb *tdb_inext; /* next in input (prev!) */
+ struct xformsw *tdb_xform; /* transformation to use */
u_int32_t tdb_spi; /* SPI to use */
u_int32_t tdb_flags; /* Flags related to this TDB */
#define TDBF_UNIQUE 0x00001 /* This should not be used by others */
@@ -46,6 +47,8 @@ struct tdb /* tunnel descriptor block */
#define TDBF_SOFT_PACKETS 0x00200 /* Soft expiration */
#define TDBF_SOFT_FIRSTUSE 0x00400 /* Soft expiration */
#define TDBF_SOFT_RELATIVE 0x00800 /* Soft expiration */
+#define TDBF_TUNNELING 0x01000 /* Do IP-in-IP encapsulation */
+#define TDBF_SAME_TTL 0x02000 /* Keep the packet TTL, in tunneling */
u_int64_t tdb_exp_packets; /* Expire after so many packets s|r */
u_int64_t tdb_soft_packets; /* Expiration warning */
u_int64_t tdb_cur_packets; /* Current number of packets s|r'ed */
@@ -63,9 +66,19 @@ struct tdb /* tunnel descriptor block */
u_int64_t tdb_exp_first_use; /* Expire if tdb_first_use +
tdb_exp_first_use <= curtime */
struct in_addr tdb_dst; /* dest address for this SPI */
- struct ifnet *tdb_rcvif; /* related rcv encap interface */
- struct xformsw *tdb_xform; /* transformation to use */
+ struct in_addr tdb_src; /* source address for this SPI,
+ * used when tunneling */
+ struct in_addr tdb_osrc;
+ struct in_addr tdb_odst; /* Source and destination addresses
+ * of outter IP header if we're doing
+ * tunneling */
caddr_t tdb_xdata; /* transformation data (opaque) */
+ u_int16_t tdb_sport; /* Source port, if applicable */
+ u_int16_t tdb_dport; /* Destination port, if applicable */
+
+ u_int8_t tdb_ttl; /* TTL used in tunneling */
+ u_int8_t tdb_proto; /* Protocol carried */
+ u_int16_t tdb_foo; /* alignment */
};
#define TDB_HASHMOD 257
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index d420438f7dc..a282dd5eedb 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_output.c,v 1.14 1997/06/25 07:53:29 provos Exp $ */
+/* $OpenBSD: ip_output.c,v 1.15 1997/07/01 22:12:53 provos Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
@@ -198,57 +198,6 @@ ip_output(m0, va_alist)
return EHOSTUNREACH;
}
- ifp = re->re_rt->rt_ifp;
-
- if (ip->ip_src.s_addr == INADDR_ANY) {
- struct sockaddr_encap *sen;
- struct sockaddr_in *sinp;
-
- if (ifp->if_addrlist.tqh_first)
- sen = (struct sockaddr_encap *)
- ifp->if_addrlist.tqh_first->ifa_addr;
- else {
-#ifdef ENCDEBUG
- if (encdebug)
- printf("ip_output: interface %s has no default address\n",
- ifp->if_xname);
-#endif /* ENCDEBUG */
- m_freem(m);
- RTFREE(re->re_rt);
- return ENXIO;
- }
-
- if (sen->sen_family != AF_ENCAP) {
-#ifdef ENCDEBUG
- if (encdebug)
- printf("ip_output: %s does not have AF_ENCAP address\n",
- ifp->if_xname);
-#endif /* ENCDEBUG */
- m_freem(m);
- RTFREE(re->re_rt);
- return EHOSTDOWN;
- }
-
- if (sen->sen_type != SENT_DEFIF) {
-#ifdef ENCDEBUG
- if (encdebug)
- printf("ip_output: %s does not have SENT_DEFIF address\n",
- ifp->if_xname);
-#endif /* ENCDEBUG */
- m_freem(m);
- RTFREE(re->re_rt);
- return EHOSTDOWN;
- }
- sinp = (struct sockaddr_in *)&(sen->sen_dfl);
- ip->ip_src = sinp->sin_addr;
- }
-
-#ifdef ENCDEBUG
- if (encdebug)
- printf("ip_output: encapsulating %x->%x through %x->%x\n",
- ip->ip_src.s_addr, ip->ip_dst.s_addr,
- gw->sen_ipsp_src, gw->sen_ipsp_dst);
-#endif
ip->ip_len = htons((u_short)ip->ip_len);
ip->ip_off = htons((u_short)ip->ip_off);
ip->ip_sum = 0;
@@ -263,6 +212,10 @@ ip_output(m0, va_alist)
tdb = (struct tdb *) gettdb(gw->sen_ipsp_spi, gw->sen_ipsp_dst);
+ /* Fix the ip_src field if necessary */
+ if ((ip->ip_src.s_addr == INADDR_ANY) && tdb)
+ ip->ip_src = tdb->tdb_src;
+
/*
* If we're doing IP-in-IP first, let the options be.
* Otherwise, get rid of them.
@@ -271,11 +224,12 @@ ip_output(m0, va_alist)
* XXX subsequently authenticated).
*/
if (tdb && tdb->tdb_xform)
- if (tdb->tdb_xform->xf_type != XF_IP4)
- if (hlen > sizeof (struct ip)) { /* XXX IPOPT */
- ip_stripoptions(m, (struct mbuf *)0);
- hlen = sizeof (struct ip);
- }
+ if ((tdb->tdb_xform->xf_type != XF_IP4) ||
+ (tdb->tdb_flags & TDBF_TUNNELING))
+ if (hlen > sizeof (struct ip)) { /* XXX IPOPT */
+ ip_stripoptions(m, (struct mbuf *)0);
+ hlen = sizeof (struct ip);
+ }
/* Now fix the checksum */
ip->ip_sum = in_cksum(m, hlen);
@@ -300,6 +254,27 @@ ip_output(m0, va_alist)
return ENXIO;
}
+ /* Check for tunneling */
+ if (tdb->tdb_flags & TDBF_TUNNELING) {
+#ifdef ENCDEBUG
+ if (encdebug)
+ printf("ip_output: doing tunneling\n");
+#endif /* ENCDEBUG */
+
+ /* Register first use */
+ if (tdb->tdb_first_use == 0)
+ tdb->tdb_first_use = time.tv_sec;
+
+ error = ipe4_output(m, gw, tdb, &mp);
+ if (mp == NULL)
+ error = EFAULT;
+ if (error) {
+ RTFREE(re->re_rt);
+ return error;
+ }
+ m = mp;
+ }
+
#ifdef ENCDEBUG
if (encdebug)
printf("ip_output: calling %s\n",
@@ -308,7 +283,7 @@ ip_output(m0, va_alist)
/* Register first use */
if (tdb->tdb_first_use == 0)
- tdb->tdb_first_use = time.tv_sec;
+ tdb->tdb_first_use = time.tv_sec;
error = (*(tdb->tdb_xform->xf_output))(m, gw, tdb, &mp);
if (mp == NULL)
@@ -322,7 +297,7 @@ ip_output(m0, va_alist)
}
/*
- * At this point, mp is pointing to an mbuf chain with the
+ * At this point, m is pointing to an mbuf chain with the
* processed packet. Call ourselves recursively, but
* bypass the encap code.
*/