summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2010-07-01 02:09:46 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2010-07-01 02:09:46 +0000
commit654205592319e75563e57a6262ca44fece0d13c6 (patch)
tree60a3dbc2a339f69c731d72eac8a12e6bc7ab823a /sys/netinet
parent9576d045e781cdcc481fbb45d927829e4ab553d3 (diff)
Allow to specify an alternative enc(4) interface for an SA. All
traffic for this SA will appear on the specified enc interface instead of enc0 and can be filtered and monitored separately. This will allow to group individual ipsec policies to virtual interfaces and simplifies monitoring and pf filtering with many ipsec policies a lot. This diff includes the following changes: - Store the enc interface unit (default 0) in the TDB of an SA and pass it to the enc_getif() lookup when running the bpf or pf_test() handlers. - Add the pfkey SADB_X_EXT_TAP extension to communicate the encX interface unit for a specified SA between userland and kernel. - Update enc(4) again to use an allocate array instead of the TAILQ to lookup the matching enc interface in enc_getif() quickly. Discussed with many, tested by a few, will need more testing & review. ok deraadt@
Diffstat (limited to 'sys/netinet')
-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
6 files changed, 37 insertions, 21 deletions
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;