From: dlg Date: Mon, 7 Aug 2023 03:43:57 +0000 (+0000) Subject: add the glue between ipsec security associations and sec(4) interfaces. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=358357352a57f9954f463fc4aff350014c9bc857;p=openbsd add the glue between ipsec security associations and sec(4) interfaces. if TDBF_IFACE is set on a tdb, the ipsec stack will pass it to the sec(4) driver to keep track of instead of wiring it up for security associations to use. when sec(4) transmits a packet, it will look up it's list of tdbs to find the right SA to encrypt and send the packet out with. if an incoming ipsec packet arrives with TDBF_IFACE set, it's passed to sec(4) to be injected back into the network stack as if it was received on the sec interface, instead of being reinjected into the IP stack like normal SA/SPD processing does. note that this means you do not have to configure tunnel endpoints on sec(4) interfaces, instead you line the interface unit number in the ipsec config up with the minor number of the sec(4) interfaces. the peer IPs used on the SAs are what's used as the traffic endpoints. support from many including markus@ tobhe@ claudio@ sthen@ patrick@ now is a good time deraadt@ --- diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c index b76314b69f5..90179f0f8f3 100644 --- a/sys/netinet/ip_ipsp.c +++ b/sys/netinet/ip_ipsp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.c,v 1.275 2022/11/11 18:09:58 cheloha Exp $ */ +/* $OpenBSD: ip_ipsp.c,v 1.276 2023/08/07 03:43:57 dlg Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr), @@ -39,6 +39,7 @@ #include "pf.h" #include "pfsync.h" +#include "sec.h" #include #include @@ -67,6 +68,10 @@ #include #endif +#if NSEC > 0 +#include +#endif + #include #include @@ -852,14 +857,6 @@ puttdb_locked(struct tdb *tdbp) tdbp->tdb_hnext = tdbh[hashval]; tdbh[hashval] = tdbp; - hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto); - tdbp->tdb_dnext = tdbdst[hashval]; - tdbdst[hashval] = tdbp; - - hashval = tdb_hash(0, &tdbp->tdb_src, tdbp->tdb_sproto); - tdbp->tdb_snext = tdbsrc[hashval]; - tdbsrc[hashval] = tdbp; - tdb_count++; #ifdef IPSEC if ((tdbp->tdb_flags & (TDBF_INVALID|TDBF_TUNNELING)) == TDBF_TUNNELING) @@ -867,6 +864,21 @@ puttdb_locked(struct tdb *tdbp) #endif /* IPSEC */ ipsec_last_added = getuptime(); + + if (ISSET(tdbp->tdb_flags, TDBF_IFACE)) { +#if NSEC > 0 + sec_tdb_insert(tdbp); +#endif + return; + } + + hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto); + tdbp->tdb_dnext = tdbdst[hashval]; + tdbdst[hashval] = tdbp; + + hashval = tdb_hash(0, &tdbp->tdb_src, tdbp->tdb_sproto); + tdbp->tdb_snext = tdbsrc[hashval]; + tdbsrc[hashval] = tdbp; } void @@ -901,6 +913,22 @@ tdb_unlink_locked(struct tdb *tdbp) tdbp->tdb_hnext = NULL; + tdb_count--; +#ifdef IPSEC + if ((tdbp->tdb_flags & (TDBF_INVALID|TDBF_TUNNELING)) == + TDBF_TUNNELING) { + ipsecstat_dec(ipsec_tunnels); + ipsecstat_inc(ipsec_prevtunnels); + } +#endif /* IPSEC */ + + if (ISSET(tdbp->tdb_flags, TDBF_IFACE)) { +#if NSEC > 0 + sec_tdb_remove(tdbp); +#endif + return; + } + hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto); if (tdbdst[hashval] == tdbp) { @@ -932,14 +960,6 @@ tdb_unlink_locked(struct tdb *tdbp) } tdbp->tdb_snext = NULL; - tdb_count--; -#ifdef IPSEC - if ((tdbp->tdb_flags & (TDBF_INVALID|TDBF_TUNNELING)) == - TDBF_TUNNELING) { - ipsecstat_dec(ipsec_tunnels); - ipsecstat_inc(ipsec_prevtunnels); - } -#endif /* IPSEC */ } void diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c index 5df9a4f9634..9e3f4dee18f 100644 --- a/sys/netinet/ipsec_input.c +++ b/sys/netinet/ipsec_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipsec_input.c,v 1.204 2023/05/13 13:35:17 bluhm Exp $ */ +/* $OpenBSD: ipsec_input.c,v 1.205 2023/08/07 03:43:57 dlg Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -36,6 +36,7 @@ */ #include "pf.h" +#include "sec.h" #include #include @@ -63,6 +64,10 @@ #include #endif +#if NSEC > 0 +#include +#endif + #ifdef INET6 #include #include @@ -545,6 +550,22 @@ ipsec_common_input_cb(struct mbuf **mp, struct tdb *tdbp, int skip, int protoff) } #endif + if (ISSET(tdbp->tdb_flags, TDBF_IFACE)) { +#if NSEC > 0 + if (ISSET(tdbp->tdb_flags, TDBF_TUNNELING) && + tdbp->tdb_iface_dir == IPSP_DIRECTION_IN) { + struct sec_softc *sc = sec_get(tdbp->tdb_iface); + if (sc == NULL) + goto baddone; + + sec_input(sc, af, prot, m); + sec_put(sc); + return IPPROTO_DONE; + } +#endif /* NSEC > 0 */ + goto baddone; + } + #if NPF > 0 /* * The ip_deliver() shortcut avoids running through ip_input() with the