From: mpi Date: Wed, 11 Jul 2018 09:07:59 +0000 (+0000) Subject: Convert AH & IPcomp to ipsec_input_cb() and count drops on input. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=e534e17823dfe6b522b2271f74a546ec1251dcce;p=openbsd Convert AH & IPcomp to ipsec_input_cb() and count drops on input. ok markus@ --- diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c index ae005ef3f03..72fab716f0d 100644 --- a/sys/netinet/ip_ah.c +++ b/sys/netinet/ip_ah.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ah.c,v 1.140 2018/05/09 12:48:59 bluhm Exp $ */ +/* $OpenBSD: ip_ah.c,v 1.141 2018/07/11 09:07:59 mpi Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -77,7 +77,6 @@ #endif void ah_output_cb(struct cryptop *); -void ah_input_cb(struct cryptop *); int ah_massage_headers(struct mbuf **, int, int, int, int); const unsigned char ipseczeroes[IPSEC_ZEROES_SIZE]; /* zeroes! */ @@ -686,7 +685,7 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ crp->crp_flags = CRYPTO_F_IMBUF; crp->crp_buf = (caddr_t)m; - crp->crp_callback = ah_input_cb; + crp->crp_callback = ipsec_input_cb; crp->crp_sid = tdb->tdb_cryptoid; crp->crp_opaque = (caddr_t)tc; @@ -707,62 +706,24 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) return error; } -/* - * AH input callback, called directly by the crypto driver. - */ -void -ah_input_cb(struct cryptop *crp) +int +ah_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf *m, int clen) { + struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform; int roff, rplen, skip, protoff; - unsigned char calc[AH_ALEN_MAX]; - struct mbuf *m1, *m0, *m; - struct auth_hash *ahx; - struct tdb_crypto *tc = NULL; - struct tdb *tdb; u_int32_t btsx, esn; caddr_t ptr; + unsigned char calc[AH_ALEN_MAX]; + struct mbuf *m1, *m0; #ifdef ENCDEBUG char buf[INET6_ADDRSTRLEN]; #endif - tc = (struct tdb_crypto *) crp->crp_opaque; + NET_ASSERT_LOCKED(); + skip = tc->tc_skip; protoff = tc->tc_protoff; - m = (struct mbuf *) crp->crp_buf; - if (m == NULL) { - /* Shouldn't happen... */ - DPRINTF(("%s: bogus returned buffer from crypto\n", __func__)); - ahstat_inc(ahs_crypto); - goto droponly; - } - - NET_LOCK(); - - tdb = gettdb(tc->tc_rdomain, tc->tc_spi, &tc->tc_dst, tc->tc_proto); - if (tdb == NULL) { - DPRINTF(("%s: TDB is expired while in crypto", __func__)); - ahstat_inc(ahs_notdb); - goto baddone; - } - - ahx = (struct auth_hash *) tdb->tdb_authalgxform; - - /* Check for crypto errors. */ - if (crp->crp_etype) { - if (crp->crp_etype == EAGAIN) { - /* Reset the session ID */ - if (tdb->tdb_cryptoid != 0) - tdb->tdb_cryptoid = crp->crp_sid; - NET_UNLOCK(); - crypto_dispatch(crp); - return; - } - DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype)); - ahstat_inc(ahs_noxform); - goto baddone; - } - rplen = AH_FLENGTH + sizeof(u_int32_t); /* Copy authenticator off the packet. */ @@ -906,19 +867,14 @@ ah_input_cb(struct cryptop *crp) m->m_pkthdr.len -= rplen + ahx->authsize; } - crypto_freereq(crp); /* No longer needed. */ free(tc, M_XDATA, 0); - ipsec_common_input_cb(m, tdb, skip, protoff); - NET_UNLOCK(); - return; + return ipsec_common_input_cb(m, tdb, skip, protoff); baddone: - NET_UNLOCK(); - droponly: m_freem(m); - crypto_freereq(crp); free(tc, M_XDATA, 0); + return -1; } /* diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c index ac80fa4b359..657e39ab887 100644 --- a/sys/netinet/ip_esp.c +++ b/sys/netinet/ip_esp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_esp.c,v 1.155 2018/07/10 11:34:12 mpi Exp $ */ +/* $OpenBSD: ip_esp.c,v 1.156 2018/07/11 09:07:59 mpi Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -531,7 +531,7 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) * ESP input callback, called directly by the crypto driver. */ int -esp_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf *m) +esp_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf *m, int clen) { u_int8_t lastthree[3], aalg[AH_HMAC_MAX_HASHLEN]; int hlen, roff, skip, protoff; diff --git a/sys/netinet/ip_ipcomp.c b/sys/netinet/ip_ipcomp.c index e472bcce9d8..f7f6a78c636 100644 --- a/sys/netinet/ip_ipcomp.c +++ b/sys/netinet/ip_ipcomp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipcomp.c,v 1.61 2018/05/12 09:38:33 bluhm Exp $ */ +/* $OpenBSD: ip_ipcomp.c,v 1.62 2018/07/11 09:07:59 mpi Exp $ */ /* * Copyright (c) 2001 Jean-Jacques Bernard-Gundol (jj@wabbitt.org) @@ -57,7 +57,6 @@ #include "bpfilter.h" void ipcomp_output_cb(struct cryptop *); -void ipcomp_input_cb(struct cryptop *); #ifdef ENCDEBUG #define DPRINTF(x) if (encdebug) printf x @@ -169,7 +168,7 @@ ipcomp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) crp->crp_ilen = m->m_pkthdr.len - (skip + hlen); crp->crp_flags = CRYPTO_F_IMBUF; crp->crp_buf = (caddr_t)m; - crp->crp_callback = ipcomp_input_cb; + crp->crp_callback = ipsec_input_cb; crp->crp_sid = tdb->tdb_cryptoid; crp->crp_opaque = (caddr_t)tc; @@ -184,43 +183,19 @@ ipcomp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) return crypto_dispatch(crp); } -/* - * IPComp input callback, called directly by the crypto driver - */ -void -ipcomp_input_cb(struct cryptop *crp) +int +ipcomp_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf *m, int clen) { - int skip, protoff, roff, hlen = IPCOMP_HLENGTH, clen; + int skip, protoff, roff, hlen = IPCOMP_HLENGTH; u_int8_t nproto; - struct mbuf *m, *m1, *mo; - struct tdb_crypto *tc; - struct tdb *tdb; + struct mbuf *m1, *mo; struct ipcomp *ipcomp; caddr_t addr; #ifdef ENCDEBUG char buf[INET6_ADDRSTRLEN]; #endif - tc = (struct tdb_crypto *) crp->crp_opaque; - skip = tc->tc_skip; - protoff = tc->tc_protoff; - - m = (struct mbuf *) crp->crp_buf; - if (m == NULL) { - /* Shouldn't happen... */ - DPRINTF(("%s: bogus returned buffer from crypto\n", __func__)); - ipcompstat_inc(ipcomps_crypto); - goto droponly; - } - - NET_LOCK(); - - tdb = gettdb(tc->tc_rdomain, tc->tc_spi, &tc->tc_dst, tc->tc_proto); - if (tdb == NULL) { - DPRINTF(("%s: TDB expired while in crypto", __func__)); - ipcompstat_inc(ipcomps_notdb); - goto baddone; - } + NET_ASSERT_LOCKED(); /* update the counters */ tdb->tdb_cur_bytes += m->m_pkthdr.len - (skip + hlen); @@ -240,24 +215,8 @@ ipcomp_input_cb(struct cryptop *crp) tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking */ } - /* Check for crypto errors */ - if (crp->crp_etype) { - if (crp->crp_etype == EAGAIN) { - /* Reset the session ID */ - if (tdb->tdb_cryptoid != 0) - tdb->tdb_cryptoid = crp->crp_sid; - NET_UNLOCK(); - crypto_dispatch(crp); - return; - } - DPRINTF(("%s: crypto error %d\n", __func__, - crp->crp_etype)); - ipcompstat_inc(ipcomps_noxform); - goto baddone; - } - - /* Length of data after processing */ - clen = crp->crp_olen; + skip = tc->tc_skip; + protoff = tc->tc_protoff; /* In case it's not done already, adjust the size of the mbuf chain */ m->m_pkthdr.len = clen + hlen + skip; @@ -331,23 +290,18 @@ ipcomp_input_cb(struct cryptop *crp) } /* Release the crypto descriptors */ - crypto_freereq(crp); free(tc, M_XDATA, 0); /* Restore the Next Protocol field */ m_copyback(m, protoff, sizeof(u_int8_t), &nproto, M_NOWAIT); /* Back to generic IPsec input processing */ - ipsec_common_input_cb(m, tdb, skip, protoff); - NET_UNLOCK(); - return; + return ipsec_common_input_cb(m, tdb, skip, protoff); baddone: - NET_UNLOCK(); - droponly: m_freem(m); - crypto_freereq(crp); free(tc, M_XDATA, 0); + return -1; } /* diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h index a3944c1e2c8..f1685adfc34 100644 --- a/sys/netinet/ip_ipsp.h +++ b/sys/netinet/ip_ipsp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.h,v 1.190 2018/07/10 11:34:12 mpi Exp $ */ +/* $OpenBSD: ip_ipsp.h,v 1.191 2018/07/11 09:07:59 mpi Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr), @@ -572,6 +572,7 @@ int ah_attach(void); int ah_init(struct tdb *, struct xformsw *, struct ipsecinit *); int ah_zeroize(struct tdb *); int ah_input(struct mbuf *, struct tdb *, int, int); +int ah_input_cb(struct tdb *, struct tdb_crypto *, struct mbuf *, int); int ah_output(struct mbuf *, struct tdb *, struct mbuf **, int, int); int ah_sysctl(int *, u_int, void *, size_t *, void *, size_t); @@ -588,7 +589,7 @@ int esp_attach(void); int esp_init(struct tdb *, struct xformsw *, struct ipsecinit *); int esp_zeroize(struct tdb *); int esp_input(struct mbuf *, struct tdb *, int, int); -int esp_input_cb(struct tdb *, struct tdb_crypto *, struct mbuf *); +int esp_input_cb(struct tdb *, struct tdb_crypto *, struct mbuf *, int); int esp_output(struct mbuf *, struct tdb *, struct mbuf **, int, int); int esp_sysctl(int *, u_int, void *, size_t *, void *, size_t); @@ -604,6 +605,7 @@ int ipcomp_attach(void); int ipcomp_init(struct tdb *, struct xformsw *, struct ipsecinit *); int ipcomp_zeroize(struct tdb *); int ipcomp_input(struct mbuf *, struct tdb *, int, int); +int ipcomp_input_cb(struct tdb *, struct tdb_crypto *, struct mbuf *, int); int ipcomp_output(struct mbuf *, struct tdb *, struct mbuf **, int, int); int ipcomp_sysctl(int *, u_int, void *, size_t *, void *, size_t); int ipcomp4_input(struct mbuf **, int *, int, int); diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c index 50bba534b00..fb69adc07d2 100644 --- a/sys/netinet/ipsec_input.c +++ b/sys/netinet/ipsec_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipsec_input.c,v 1.164 2018/07/10 11:34:12 mpi Exp $ */ +/* $OpenBSD: ipsec_input.c,v 1.165 2018/07/11 09:07:59 mpi Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -335,6 +335,7 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto, return error; drop: + ipsecstat_inc(ipsec_idrops); m_freem(m); return error; } @@ -345,7 +346,7 @@ ipsec_input_cb(struct cryptop *crp) struct tdb_crypto *tc = (struct tdb_crypto *) crp->crp_opaque; struct mbuf *m = (struct mbuf *) crp->crp_buf; struct tdb *tdb; - int error; + int clen, error; if (m == NULL) { DPRINTF(("%s: bogus returned buffer from crypto\n", __func__)); @@ -377,16 +378,21 @@ ipsec_input_cb(struct cryptop *crp) goto baddone; } + /* Length of data after processing */ + clen = crp->crp_olen; + /* Release the crypto descriptors */ crypto_freereq(crp); switch (tdb->tdb_sproto) { case IPPROTO_ESP: - error = esp_input_cb(tdb, tc, m); + error = esp_input_cb(tdb, tc, m, clen); break; case IPPROTO_AH: + error = ah_input_cb(tdb, tc, m, clen); break; case IPPROTO_IPCOMP: + error = ipcomp_input_cb(tdb, tc, m, clen); break; default: panic("%s: unknown/unsupported security protocol %d",