diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2010-07-01 02:09:46 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2010-07-01 02:09:46 +0000 |
commit | 654205592319e75563e57a6262ca44fece0d13c6 (patch) | |
tree | 60a3dbc2a339f69c731d72eac8a12e6bc7ab823a /sys/netinet/ipsec_input.c | |
parent | 9576d045e781cdcc481fbb45d927829e4ab553d3 (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/ipsec_input.c')
-rw-r--r-- | sys/netinet/ipsec_input.c | 21 |
1 files changed, 18 insertions, 3 deletions
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; |