Convert AH & IPcomp to ipsec_input_cb() and count drops on input.
authormpi <mpi@openbsd.org>
Wed, 11 Jul 2018 09:07:59 +0000 (09:07 +0000)
committermpi <mpi@openbsd.org>
Wed, 11 Jul 2018 09:07:59 +0000 (09:07 +0000)
ok markus@

sys/netinet/ip_ah.c
sys/netinet/ip_esp.c
sys/netinet/ip_ipcomp.c
sys/netinet/ip_ipsp.h
sys/netinet/ipsec_input.c

index ae005ef..72fab71 100644 (file)
@@ -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;
 }
 
 /*
index ac80fa4..657e39a 100644 (file)
@@ -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;
index e472bcc..f7f6a78 100644 (file)
@@ -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;
 }
 
 /*
index a3944c1..f1685ad 100644 (file)
@@ -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);
index 50bba53..fb69adc 100644 (file)
@@ -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",