summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/net/if_bridge.c8
-rw-r--r--sys/net/if_enc.c67
-rw-r--r--sys/net/if_enc.h6
-rw-r--r--sys/net/pfkeyv2.c13
-rw-r--r--sys/net/pfkeyv2.h13
-rw-r--r--sys/net/pfkeyv2_convert.c21
-rw-r--r--sys/net/pfkeyv2_parsemessage.c25
-rw-r--r--sys/net/route.c4
-rw-r--r--sys/netinet/ip_ah.c4
-rw-r--r--sys/netinet/ip_esp.c4
-rw-r--r--sys/netinet/ip_ipcomp.c4
-rw-r--r--sys/netinet/ip_ipsp.h3
-rw-r--r--sys/netinet/ip_output.c22
-rw-r--r--sys/netinet/ipsec_input.c21
-rw-r--r--sys/netinet6/ip6_forward.c19
-rw-r--r--sys/netinet6/ip6_output.c29
16 files changed, 183 insertions, 80 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index ba3e830841d..3ffd4a4bc98 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.179 2010/06/29 21:28:37 reyk Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.180 2010/07/01 02:09:45 reyk Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -2457,7 +2457,8 @@ bridge_ipsec(struct bridge_softc *sc, struct ifnet *ifp,
switch (af) {
#ifdef INET
case AF_INET:
- if ((encif = enc_getif(0)) == NULL ||
+ if ((encif = enc_getif(0,
+ tdb->tdb_tap)) == NULL ||
pf_test(dir, encif,
&m, NULL) != PF_PASS) {
m_freem(m);
@@ -2467,7 +2468,8 @@ bridge_ipsec(struct bridge_softc *sc, struct ifnet *ifp,
#endif /* INET */
#ifdef INET6
case AF_INET6:
- if ((encif = enc_getif(0)) == NULL ||
+ if ((encif = enc_getif(0,
+ tdb->tdb_tap)) == NULL ||
pf_test6(dir, encif,
&m, NULL) != PF_PASS) {
m_freem(m);
diff --git a/sys/net/if_enc.c b/sys/net/if_enc.c
index c0ac2545299..8ea76cfe231 100644
--- a/sys/net/if_enc.c
+++ b/sys/net/if_enc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_enc.c,v 1.50 2010/07/01 01:55:03 reyk Exp $ */
+/* $OpenBSD: if_enc.c,v 1.51 2010/07/01 02:09:45 reyk Exp $ */
/*
* Copyright (c) 2010 Reyk Floeter <reyk@vantronix.net>
@@ -35,9 +35,11 @@
#include <net/bpf.h>
#endif
-TAILQ_HEAD(__enchead, enc_softc) enc_list; /* all enc interfaces */
struct ifnet **enc_ifps; /* rdomain-mapped enc ifs */
-u_int enc_max_id;
+u_int enc_max_id;
+struct ifnet **enc_allifps; /* unit-mapped enc ifs */
+u_int enc_max_unit;
+#define ENC_MAX_UNITS 4096 /* XXX n per rdomain */
void encattach(int);
@@ -57,8 +59,6 @@ struct if_clone enc_cloner =
void
encattach(int count)
{
- TAILQ_INIT(&enc_list);
-
/* Create enc0 by default */
(void)enc_clone_create(&enc_cloner, 0);
@@ -70,6 +70,11 @@ enc_clone_create(struct if_clone *ifc, int unit)
{
struct enc_softc *sc;
struct ifnet *ifp;
+ struct ifnet **new;
+ size_t newlen;
+
+ if (unit > ENC_MAX_UNITS)
+ return (EINVAL);
if ((sc = malloc(sizeof(struct enc_softc),
M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
@@ -103,7 +108,21 @@ enc_clone_create(struct if_clone *ifc, int unit)
return (-1);
}
- TAILQ_INSERT_TAIL(&enc_list, sc, sc_entry);
+ if (unit == 0 || unit > enc_max_unit) {
+ newlen = sizeof(struct ifnet *) * (unit + 1);
+
+ if ((new = malloc(newlen, M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
+ return (-1);
+ if (enc_allifps != NULL) {
+ memcpy(new, enc_allifps,
+ sizeof(struct ifnet *) * (enc_max_unit + 1));
+ free(enc_allifps, M_DEVBUF);
+ }
+ enc_allifps = new;
+ enc_max_unit = unit;
+ }
+ enc_allifps[unit] = ifp;
+
return (0);
}
@@ -118,7 +137,7 @@ enc_clone_destroy(struct ifnet *ifp)
return (EPERM);
s = splnet();
- TAILQ_REMOVE(&enc_list, sc, sc_entry);
+ enc_allifps[sc->sc_unit] = NULL;
enc_unsetif(ifp);
if_detach(ifp);
free(sc, M_DEVBUF);
@@ -177,8 +196,21 @@ enc_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
struct ifnet *
-enc_getif(u_int id)
+enc_getif(u_int id, u_int unit)
{
+ struct ifnet *ifp;
+
+ /* Check if the caller wants to get a non-default enc interface */
+ if (unit > 0) {
+ if (unit > enc_max_unit)
+ return (NULL);
+ ifp = enc_allifps[unit];
+ if (ifp == NULL || ifp->if_rdomain != id)
+ return (NULL);
+ return (ifp);
+ }
+
+ /* Otherwise return the default enc interface for this rdomain */
if (enc_ifps == NULL)
return (NULL);
else if (id > RT_TABLEID_MAX)
@@ -202,7 +234,7 @@ enc_setif(struct ifnet *ifp, u_int id)
* for this rdomain, so only the first enc interface that
* was added for this rdomain becomes the default.
*/
- if (enc_getif(id) != NULL)
+ if (enc_getif(id, 0) != NULL)
return (0);
if (id > RT_TABLEID_MAX)
@@ -233,11 +265,10 @@ enc_setif(struct ifnet *ifp, u_int id)
void
enc_unsetif(struct ifnet *ifp)
{
- u_int id = ifp->if_rdomain;
- struct ifnet *oifp;
- struct enc_softc *sc;
+ u_int id = ifp->if_rdomain, i;
+ struct ifnet *oifp, *nifp;
- if ((oifp = enc_getif(id)) == NULL || oifp != ifp)
+ if ((oifp = enc_getif(id, 0)) == NULL || oifp != ifp)
return;
/* Clear slot for this rdomain */
@@ -248,12 +279,14 @@ enc_unsetif(struct ifnet *ifp)
* Now find the next available encif to be the default interface
* for this rdomain.
*/
- TAILQ_FOREACH(sc, &enc_list, sc_entry) {
- if (&sc->sc_if == ifp || sc->sc_if.if_rdomain != id)
+ for (i = 0; i < (enc_max_unit + 1); i++) {
+ nifp = enc_allifps[i];
+
+ if (nifp == NULL || nifp == ifp || nifp->if_rdomain != id)
continue;
- enc_ifps[id] = &sc->sc_if;
- sc->sc_if.if_link_state = LINK_STATE_UP;
+ enc_ifps[id] = nifp;
+ nifp->if_link_state = LINK_STATE_UP;
break;
}
}
diff --git a/sys/net/if_enc.h b/sys/net/if_enc.h
index 9220ded4445..7dee1d7a032 100644
--- a/sys/net/if_enc.h
+++ b/sys/net/if_enc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_enc.h,v 1.9 2010/06/29 21:28:37 reyk Exp $ */
+/* $OpenBSD: if_enc.h,v 1.10 2010/07/01 02:09:45 reyk Exp $ */
/*
* Copyright (c) 2010 Reyk Floeter <reyk@vantronix.net>
@@ -25,8 +25,6 @@
struct enc_softc {
struct ifnet sc_if; /* virtual interface */
u_int sc_unit;
-
- TAILQ_ENTRY(enc_softc) sc_entry;
};
struct enchdr {
@@ -35,6 +33,6 @@ struct enchdr {
u_int32_t flags;
};
-struct ifnet *enc_getif(u_int);
+struct ifnet *enc_getif(u_int, u_int);
#endif /* _NET_ENC_H */
diff --git a/sys/net/pfkeyv2.c b/sys/net/pfkeyv2.c
index 3b666a9ed68..b5c0178406f 100644
--- a/sys/net/pfkeyv2.c
+++ b/sys/net/pfkeyv2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkeyv2.c,v 1.119 2008/05/09 15:48:15 claudio Exp $ */
+/* $OpenBSD: pfkeyv2.c,v 1.120 2010/07/01 02:09:45 reyk Exp $ */
/*
* @(#)COPYRIGHT 1.1 (NRL) 17 January 1995
@@ -583,6 +583,8 @@ pfkeyv2_get(struct tdb *sa, void **headers, void **buffer, int *lenp)
#if NPF > 0
if (sa->tdb_tag)
i+= PADUP(PF_TAG_NAME_SIZE) + sizeof(struct sadb_x_tag);
+ if (sa->tdb_tap)
+ i+= sizeof(struct sadb_x_tap);
#endif
if (lenp)
@@ -701,6 +703,12 @@ pfkeyv2_get(struct tdb *sa, void **headers, void **buffer, int *lenp)
headers[SADB_X_EXT_TAG] = p;
export_tag(&p, sa);
}
+
+ /* Export tap enc(4) device information, if present */
+ if (sa->tdb_tap) {
+ headers[SADB_X_EXT_TAP] = p;
+ export_tap(&p, sa);
+ }
#endif
rval = 0;
@@ -1053,6 +1061,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
import_udpencap(newsa, headers[SADB_X_EXT_UDPENCAP]);
#if NPF > 0
import_tag(newsa, headers[SADB_X_EXT_TAG]);
+ import_tap(newsa, headers[SADB_X_EXT_TAP]);
#endif
headers[SADB_EXT_KEY_AUTH] = NULL;
@@ -1102,6 +1111,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
import_udpencap(sa2, headers[SADB_X_EXT_UDPENCAP]);
#if NPF > 0
import_tag(sa2, headers[SADB_X_EXT_TAG]);
+ import_tap(sa2, headers[SADB_X_EXT_TAP]);
#endif
}
@@ -1219,6 +1229,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
import_udpencap(newsa, headers[SADB_X_EXT_UDPENCAP]);
#if NPF > 0
import_tag(newsa, headers[SADB_X_EXT_TAG]);
+ import_tap(newsa, headers[SADB_X_EXT_TAP]);
#endif
headers[SADB_EXT_KEY_AUTH] = NULL;
diff --git a/sys/net/pfkeyv2.h b/sys/net/pfkeyv2.h
index 64b28b5daa7..6e4d146b374 100644
--- a/sys/net/pfkeyv2.h
+++ b/sys/net/pfkeyv2.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkeyv2.h,v 1.56 2006/11/24 13:52:14 reyk Exp $ */
+/* $OpenBSD: pfkeyv2.h,v 1.57 2010/07/01 02:09:45 reyk Exp $ */
/*
* @(#)COPYRIGHT 1.1 (NRL) January 1998
*
@@ -219,6 +219,12 @@ struct sadb_x_tag {
u_int32_t sadb_x_tag_taglen;
};
+struct sadb_x_tap {
+ uint16_t sadb_x_tap_len;
+ uint16_t sadb_x_tap_exttype;
+ u_int32_t sadb_x_tap_unit;
+};
+
#ifdef _KERNEL
#define SADB_X_GETSPROTO(x) \
( (x) == SADB_SATYPE_AH ? IPPROTO_AH :\
@@ -261,7 +267,8 @@ struct sadb_x_tag {
#define SADB_X_EXT_UDPENCAP 31
#define SADB_X_EXT_LIFETIME_LASTUSE 32
#define SADB_X_EXT_TAG 33
-#define SADB_EXT_MAX 33
+#define SADB_X_EXT_TAP 34
+#define SADB_EXT_MAX 34
/* Fix pfkeyv2.c struct pfkeyv2_socket if SATYPE_MAX > 31 */
#define SADB_SATYPE_UNSPEC 0
@@ -453,6 +460,7 @@ void export_key(void **, struct tdb *, int);
void export_auth(void **, struct tdb *, int);
void export_udpencap(void **, struct tdb *);
void export_tag(void **, struct tdb *);
+void export_tap(void **, struct tdb *);
void import_auth(struct tdb *, struct sadb_x_cred *, int);
void import_address(struct sockaddr *, struct sadb_address *);
@@ -466,5 +474,6 @@ void import_flow(struct sockaddr_encap *, struct sockaddr_encap *,
struct sadb_address *, struct sadb_protocol *, struct sadb_protocol *);
void import_udpencap(struct tdb *, struct sadb_x_udpencap *);
void import_tag(struct tdb *, struct sadb_x_tag *);
+void import_tap(struct tdb *, struct sadb_x_tap *);
#endif /* _KERNEL */
#endif /* _NET_PFKEY_V2_H_ */
diff --git a/sys/net/pfkeyv2_convert.c b/sys/net/pfkeyv2_convert.c
index 67dc4fe6f34..e247d8ab5c0 100644
--- a/sys/net/pfkeyv2_convert.c
+++ b/sys/net/pfkeyv2_convert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkeyv2_convert.c,v 1.31 2008/10/22 23:04:45 mpf Exp $ */
+/* $OpenBSD: pfkeyv2_convert.c,v 1.32 2010/07/01 02:09:45 reyk Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@keromytis.org)
*
@@ -1004,4 +1004,23 @@ export_tag(void **p, struct tdb *tdb)
PADUP(stag->sadb_x_tag_taglen)) / sizeof(uint64_t);
*p += PADUP(stag->sadb_x_tag_taglen) + sizeof(struct sadb_x_tag);
}
+
+/* Import enc(4) tap device information for SA */
+void
+import_tap(struct tdb *tdb, struct sadb_x_tap *stap)
+{
+ if (stap)
+ tdb->tdb_tap = stap->sadb_x_tap_unit;
+}
+
+/* Export enc(4) tap device information for SA */
+void
+export_tap(void **p, struct tdb *tdb)
+{
+ struct sadb_x_tap *stag = (struct sadb_x_tap *)*p;
+
+ stag->sadb_x_tap_unit = tdb->tdb_tap;
+ stag->sadb_x_tap_len = sizeof(struct sadb_x_tap) / sizeof(uint64_t);
+ *p += sizeof(struct sadb_x_tap);
+}
#endif
diff --git a/sys/net/pfkeyv2_parsemessage.c b/sys/net/pfkeyv2_parsemessage.c
index ba37529a67d..68ac730b3fb 100644
--- a/sys/net/pfkeyv2_parsemessage.c
+++ b/sys/net/pfkeyv2_parsemessage.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkeyv2_parsemessage.c,v 1.43 2008/10/22 23:04:45 mpf Exp $ */
+/* $OpenBSD: pfkeyv2_parsemessage.c,v 1.44 2010/07/01 02:09:45 reyk Exp $ */
/*
* @(#)COPYRIGHT 1.1 (NRL) 17 January 1995
@@ -131,6 +131,7 @@ extern int encdebug;
#define BITMAP_X_UDPENCAP (1LL << SADB_X_EXT_UDPENCAP)
#define BITMAP_X_LIFETIME_LASTUSE (1LL << SADB_X_EXT_LIFETIME_LASTUSE)
#define BITMAP_X_TAG (1LL << SADB_X_EXT_TAG)
+#define BITMAP_X_TAP (1LL << SADB_X_EXT_TAP)
uint64_t sadb_exts_allowed_in[SADB_MAX+1] =
{
@@ -139,9 +140,9 @@ uint64_t sadb_exts_allowed_in[SADB_MAX+1] =
/* GETSPI */
BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_SPIRANGE,
/* UPDATE */
- BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG,
+ BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP,
/* ADD */
- BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_TAG,
+ BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_TAG | BITMAP_X_TAP,
/* DELETE */
BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
/* GET */
@@ -211,13 +212,13 @@ uint64_t sadb_exts_allowed_out[SADB_MAX+1] =
/* GETSPI */
BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
/* UPDATE */
- BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG,
+ BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP,
/* ADD */
- BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG,
+ BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP,
/* DELETE */
BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
/* GET */
- BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_FLOW_TYPE | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_TAG,
+ BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_FLOW_TYPE | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_TAG | BITMAP_X_TAP,
/* ACQUIRE */
BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_IDENTITY | BITMAP_PROPOSAL | BITMAP_X_CREDENTIALS,
/* REGISTER */
@@ -955,6 +956,18 @@ pfkeyv2_parsemessage(void *p, int len, void **headers)
return (EINVAL);
}
break;
+ case SADB_X_EXT_TAP:
+ if (i < sizeof(struct sadb_x_tap)) {
+ DPRINTF(("pfkeyv2_parsemessage: "
+ "TAP extension header too small"));
+ return (EINVAL);
+ }
+ if (i > sizeof(struct sadb_x_tap)) {
+ DPRINTF(("pfkeyv2_parsemessage: "
+ "TAP extension header too long"));
+ return (EINVAL);
+ }
+ break;
#endif
default:
DPRINTF(("pfkeyv2_parsemessage: unknown extension "
diff --git a/sys/net/route.c b/sys/net/route.c
index 85ca1fdfbb1..6af6b964da5 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.121 2010/06/29 21:28:37 reyk Exp $ */
+/* $OpenBSD: route.c,v 1.122 2010/07/01 02:09:45 reyk Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -170,7 +170,7 @@ encap_findgwifa(struct sockaddr *gw)
{
struct ifnet *encif;
- if ((encif = enc_getif(0)) == NULL)
+ if ((encif = enc_getif(0, 0)) == NULL)
return (NULL);
return (TAILQ_FIRST(&encif->if_addrlist));
diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c
index 9e30a8cd6ef..caa6d66ce5a 100644
--- a/sys/netinet/ip_ah.c
+++ b/sys/netinet/ip_ah.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ah.c,v 1.94 2010/06/29 21:28:37 reyk Exp $ */
+/* $OpenBSD: ip_ah.c,v 1.95 2010/07/01 02:09:45 reyk Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@@ -986,7 +986,7 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
#if NBPFILTER > 0
struct ifnet *encif;
- if ((encif = enc_getif(0)) != NULL) {
+ if ((encif = enc_getif(0, tdb->tdb_tap)) != NULL) {
encif->if_opackets++;
encif->if_obytes += m->m_pkthdr.len;
diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c
index c7799fdb631..21af051a513 100644
--- a/sys/netinet/ip_esp.c
+++ b/sys/netinet/ip_esp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_esp.c,v 1.107 2010/06/29 21:28:37 reyk Exp $ */
+/* $OpenBSD: ip_esp.c,v 1.108 2010/07/01 02:09:45 reyk Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@@ -733,7 +733,7 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
#if NBPFILTER > 0
struct ifnet *encif;
- if ((encif = enc_getif(0)) != NULL) {
+ if ((encif = enc_getif(0, tdb->tdb_tap)) != NULL) {
encif->if_opackets++;
encif->if_obytes += m->m_pkthdr.len;
diff --git a/sys/netinet/ip_ipcomp.c b/sys/netinet/ip_ipcomp.c
index 9ed501c1aca..0b98d6e28d7 100644
--- a/sys/netinet/ip_ipcomp.c
+++ b/sys/netinet/ip_ipcomp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipcomp.c,v 1.24 2010/06/29 21:28:37 reyk Exp $ */
+/* $OpenBSD: ip_ipcomp.c,v 1.25 2010/07/01 02:09:45 reyk Exp $ */
/*
* Copyright (c) 2001 Jean-Jacques Bernard-Gundol (jj@wabbitt.org)
@@ -384,7 +384,7 @@ ipcomp_output(m, tdb, mp, skip, protoff)
#if NBPFILTER > 0
struct ifnet *encif;
- if ((encif = enc_getif(0)) != NULL) {
+ if ((encif = enc_getif(0, tdb->tdb_tap)) != NULL) {
encif->if_opackets++;
encif->if_obytes += m->m_pkthdr.len;
diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h
index 8d8f14323d0..3bfad3ee55c 100644
--- a/sys/netinet/ip_ipsp.h
+++ b/sys/netinet/ip_ipsp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.h,v 1.142 2010/05/11 09:36:07 claudio Exp $ */
+/* $OpenBSD: ip_ipsp.h,v 1.143 2010/07/01 02:09:45 reyk Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
@@ -372,6 +372,7 @@ struct tdb { /* tunnel descriptor block */
u_int16_t tdb_udpencap_port; /* Peer UDP port */
u_int16_t tdb_tag; /* Packet filter tag */
+ u_int32_t tdb_tap; /* Alternate enc(4) interface */
struct sockaddr_encap tdb_filter; /* What traffic is acceptable */
struct sockaddr_encap tdb_filtermask; /* And the mask */
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 6081689e069..63fc01c870d 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_output.c,v 1.206 2010/06/29 21:28:38 reyk Exp $ */
+/* $OpenBSD: ip_output.c,v 1.207 2010/07/01 02:09:45 reyk Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
@@ -586,11 +586,20 @@ sendit:
if (sproto != 0) {
s = splnet();
+ tdb = gettdb(sspi, &sdst, sproto);
+ if (tdb == NULL) {
+ DPRINTF(("ip_output: unknown TDB"));
+ error = EHOSTUNREACH;
+ splx(s);
+ m_freem(m);
+ goto done;
+ }
+
/*
* Packet filter
*/
#if NPF > 0
- if ((encif = enc_getif(0)) == NULL ||
+ if ((encif = enc_getif(0, tdb->tdb_tap)) == NULL ||
pf_test(PF_OUT, encif, &m, NULL) != PF_PASS) {
error = EHOSTUNREACH;
splx(s);
@@ -612,15 +621,6 @@ sendit:
*/
#endif
- tdb = gettdb(sspi, &sdst, sproto);
- if (tdb == NULL) {
- DPRINTF(("ip_output: unknown TDB"));
- error = EHOSTUNREACH;
- splx(s);
- m_freem(m);
- goto done;
- }
-
/* Check if we are allowed to fragment */
if (ip_mtudisc && (ip->ip_off & htons(IP_DF)) && tdb->tdb_mtu &&
ntohs(ip->ip_len) > tdb->tdb_mtu &&
diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c
index 13a5295d3e0..f646902ad05 100644
--- a/sys/netinet/ipsec_input.c
+++ b/sys/netinet/ipsec_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsec_input.c,v 1.96 2010/06/29 21:28:38 reyk Exp $ */
+/* $OpenBSD: ipsec_input.c,v 1.97 2010/07/01 02:09:45 reyk Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@@ -119,6 +119,7 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto,
union sockaddr_union dst_address;
struct timeval tv;
struct tdb *tdbp;
+ struct ifnet *encif;
u_int32_t spi;
u_int16_t cpi;
int s, error;
@@ -239,8 +240,22 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto,
}
if (sproto != IPPROTO_IPCOMP) {
+ if ((encif = enc_getif(0, tdbp->tdb_tap)) == NULL) {
+ splx(s);
+ DPRINTF(("ipsec_common_input(): "
+ "no enc%u interface for SA %s/%08x/%u\n",
+ tdbp->tdb_tap, ipsp_address(dst_address),
+ ntohl(spi), tdbp->tdb_sproto));
+ m_freem(m);
+
+ IPSEC_ISTAT(espstat.esps_pdrops,
+ ahstat.ahs_pdrops,
+ ipcompstat.ipcomps_pdrops);
+ return EACCES;
+ }
+
/* XXX This conflicts with the scoped nature of IPv6 */
- m->m_pkthdr.rcvif = enc_getif(0);
+ m->m_pkthdr.rcvif = encif;
}
/* Register first use, setup expiration timer. */
@@ -565,7 +580,7 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff,
m->m_flags |= M_TUNNEL;
#if NBPFILTER > 0
- if ((encif = enc_getif(0)) != NULL) {
+ if ((encif = enc_getif(0, tdbp->tdb_tap)) != NULL) {
encif->if_ipackets++;
encif->if_ibytes += m->m_pkthdr.len;
diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c
index b3403ec249e..d08183d9e08 100644
--- a/sys/netinet6/ip6_forward.c
+++ b/sys/netinet6/ip6_forward.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_forward.c,v 1.47 2010/06/29 21:28:38 reyk Exp $ */
+/* $OpenBSD: ip6_forward.c,v 1.48 2010/07/01 02:09:45 reyk Exp $ */
/* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */
/*
@@ -337,8 +337,16 @@ reroute:
if (sproto != 0) {
s = splnet();
+ tdb = gettdb(sspi, &sdst, sproto);
+ if (tdb == NULL) {
+ splx(s);
+ error = EHOSTUNREACH;
+ m_freem(m);
+ goto senderr; /*XXX*/
+ }
+
#if NPF > 0
- if ((encif = enc_getif(0)) == NULL ||
+ if ((encif = enc_getif(0, tdb->tdb_tap)) == NULL ||
pf_test6(PF_OUT, encif, &m, NULL) != PF_PASS) {
splx(s);
error = EHOSTUNREACH;
@@ -358,13 +366,6 @@ reroute:
* What's the behaviour?
*/
#endif
- tdb = gettdb(sspi, &sdst, sproto);
- if (tdb == NULL) {
- splx(s);
- error = EHOSTUNREACH;
- m_freem(m);
- goto senderr; /*XXX*/
- }
m->m_flags &= ~(M_BCAST | M_MCAST); /* just in case */
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index cd5fbe44c21..fd1c1b1eca8 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_output.c,v 1.113 2010/06/29 21:28:38 reyk Exp $ */
+/* $OpenBSD: ip6_output.c,v 1.114 2010/07/01 02:09:45 reyk Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
@@ -504,8 +504,21 @@ reroute:
if (sproto != 0) {
s = splnet();
+ /*
+ * XXX what should we do if ip6_hlim == 0 and the
+ * packet gets tunneled?
+ */
+
+ tdb = gettdb(sspi, &sdst, sproto);
+ if (tdb == NULL) {
+ splx(s);
+ error = EHOSTUNREACH;
+ m_freem(m);
+ goto done;
+ }
+
#if NPF > 0
- if ((encif = enc_getif(0)) == NULL ||
+ if ((encif = enc_getif(0, tdb->tdb_tap)) == NULL ||
pf_test6(PF_OUT, encif, &m, NULL) != PF_PASS) {
splx(s);
error = EHOSTUNREACH;
@@ -525,18 +538,6 @@ reroute:
* What's the behaviour?
*/
#endif
- /*
- * XXX what should we do if ip6_hlim == 0 and the
- * packet gets tunneled?
- */
-
- tdb = gettdb(sspi, &sdst, sproto);
- if (tdb == NULL) {
- splx(s);
- error = EHOSTUNREACH;
- m_freem(m);
- goto done;
- }
m->m_flags &= ~(M_BCAST | M_MCAST); /* just in case */