Hi,

I want to ref count the TDB that is returned by ipsp_spd_lookup().

Sometimes the TDB returned by ipsp_spd_lookup() is not used.  So
refcounting that, does not make sense.  As a first step I want to
convert ipsp_spd_lookup() to return an error.

- tdb = ipsp_spd_lookup(&error)
+ error = ipsp_spd_lookup(&tdb)

If we don't need the TDB, this call will avoid ref counting.
  error = ipsp_spd_lookup(NULL)

The following diff only changes the parameter and error checking.
No refcountig yet.

ok?

bluhm

Index: net/if_bridge.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/if_bridge.c,v
retrieving revision 1.359
diff -u -p -r1.359 if_bridge.c
--- net/if_bridge.c     25 Nov 2021 13:46:02 -0000      1.359
+++ net/if_bridge.c     30 Nov 2021 21:29:39 -0000
@@ -1594,9 +1594,9 @@ bridge_ipsec(struct ifnet *ifp, struct e
                        return (0);
                }
        } else { /* Outgoing from the bridge. */
-               tdb = ipsp_spd_lookup(m, af, hlen, &error,
-                   IPSP_DIRECTION_OUT, NULL, NULL, 0);
-               if (tdb != NULL) {
+               error = ipsp_spd_lookup(m, af, hlen, IPSP_DIRECTION_OUT,
+                   NULL, NULL, &tdb, 0);
+               if (error == 0 && tdb != NULL) {
                        /*
                         * We don't need to do loop detection, the
                         * bridge will do that for us.
Index: netinet/ip_ipsp.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_ipsp.h,v
retrieving revision 1.224
diff -u -p -r1.224 ip_ipsp.h
--- netinet/ip_ipsp.h   30 Nov 2021 13:17:43 -0000      1.224
+++ netinet/ip_ipsp.h   30 Nov 2021 15:14:46 -0000
@@ -632,8 +632,8 @@ int checkreplaywindow(struct tdb *, u_in
 /* Packet processing */
 int    ipsp_process_packet(struct mbuf *, struct tdb *, int, int);
 int    ipsp_process_done(struct mbuf *, struct tdb *);
-struct tdb *ipsp_spd_lookup(struct mbuf *, int, int, int *, int,
-           struct tdb *, struct inpcb *, u_int32_t);
+int    ipsp_spd_lookup(struct mbuf *, int, int, int, struct tdb *,
+           struct inpcb *, struct tdb **, u_int32_t);
 int    ipsp_is_unspecified(union sockaddr_union);
 int    ipsp_aux_match(struct tdb *, struct ipsec_ids *,
            struct sockaddr_encap *, struct sockaddr_encap *);
Index: netinet/ip_output.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.375
diff -u -p -r1.375 ip_output.c
--- netinet/ip_output.c 24 Nov 2021 18:48:33 -0000      1.375
+++ netinet/ip_output.c 30 Nov 2021 21:41:01 -0000
@@ -86,8 +86,8 @@ static __inline u_int16_t __attribute__(
 void in_delayed_cksum(struct mbuf *);
 int in_ifcap_cksum(struct mbuf *, struct ifnet *, int);
 
-struct tdb *ip_output_ipsec_lookup(struct mbuf *m, int hlen, int *error,
-    struct inpcb *inp, int ipsecflowinfo);
+int ip_output_ipsec_lookup(struct mbuf *m, int hlen, struct inpcb *inp,
+    struct tdb **, int ipsecflowinfo);
 void ip_output_ipsec_pmtu_update(struct tdb *, struct route *, struct in_addr,
     int, int);
 int ip_output_ipsec_send(struct tdb *, struct mbuf *, struct route *, int);
@@ -244,9 +244,9 @@ reroute:
 #ifdef IPSEC
        if (ipsec_in_use || inp != NULL) {
                /* Do we have any pending SAs to apply ? */
-               tdb = ip_output_ipsec_lookup(m, hlen, &error, inp,
+               error = ip_output_ipsec_lookup(m, hlen, inp, &tdb,
                    ipsecflowinfo);
-               if (error != 0) {
+               if (error) {
                        /* Should silently drop packet */
                        if (error == -EINVAL)
                                error = 0;
@@ -531,19 +531,22 @@ bad:
 }
 
 #ifdef IPSEC
-struct tdb *
-ip_output_ipsec_lookup(struct mbuf *m, int hlen, int *error, struct inpcb *inp,
-    int ipsecflowinfo)
+int
+ip_output_ipsec_lookup(struct mbuf *m, int hlen, struct inpcb *inp,
+    struct tdb **tdbout, int ipsecflowinfo)
 {
        struct m_tag *mtag;
        struct tdb_ident *tdbi;
        struct tdb *tdb;
+       int error;
 
        /* Do we have any pending SAs to apply ? */
-       tdb = ipsp_spd_lookup(m, AF_INET, hlen, error, IPSP_DIRECTION_OUT,
-           NULL, inp, ipsecflowinfo);
-       if (tdb == NULL)
-               return NULL;
+       error = ipsp_spd_lookup(m, AF_INET, hlen, IPSP_DIRECTION_OUT,
+           NULL, inp, &tdb, ipsecflowinfo);
+       if (error || tdb == NULL) {
+               *tdbout = NULL;
+               return error;
+       }
        /* Loop detection */
        for (mtag = m_tag_first(m); mtag != NULL; mtag = m_tag_next(m, mtag)) {
                if (mtag->m_tag_id != PACKET_TAG_IPSEC_OUT_DONE)
@@ -555,10 +558,12 @@ ip_output_ipsec_lookup(struct mbuf *m, i
                    !memcmp(&tdbi->dst, &tdb->tdb_dst,
                    sizeof(union sockaddr_union))) {
                        /* no IPsec needed */
-                       return NULL;
+                       *tdbout = NULL;
+                       return 0;
                }
        }
-       return tdb;
+       *tdbout = tdb;
+       return 0;
 }
 
 void
Index: netinet/ip_spd.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_spd.c,v
retrieving revision 1.106
diff -u -p -r1.106 ip_spd.c
--- netinet/ip_spd.c    30 Nov 2021 13:17:43 -0000      1.106
+++ netinet/ip_spd.c    30 Nov 2021 15:50:29 -0000
@@ -41,8 +41,8 @@
 #include <netinet/ip_ipsp.h>
 #include <net/pfkeyv2.h>
 
-struct tdb *ipsp_spd_inp(struct mbuf *, int *, struct inpcb *,
-           struct ipsec_policy *);
+int    ipsp_spd_inp(struct mbuf *, struct inpcb *, struct ipsec_policy *,
+           struct tdb **);
 int    ipsp_acquire_sa(struct ipsec_policy *, union sockaddr_union *,
            union sockaddr_union *, struct sockaddr_encap *, struct mbuf *);
 struct ipsec_acquire *ipsp_pending_acquire(struct ipsec_policy *,
@@ -135,18 +135,19 @@ spd_table_walk(unsigned int rtableid,
  * the mbuf is. hlen is the offset of the transport protocol header
  * in the mbuf.
  *
- * Return combinations (of return value and in *error):
- * - NULL/0 -> no IPsec required on packet
- * - NULL/-EINVAL -> silently drop the packet
- * - NULL/errno -> drop packet and return error
- * or a pointer to a TDB (and 0 in *error).
+ * Return combinations (of return value and *tdbout):
+ * - -EINVAL -> silently drop the packet
+ * - errno   -> drop packet and return error
+ * - 0/NULL  -> no IPsec required on packet
+ * - 0/TDB   -> do IPsec
  *
  * In the case of incoming flows, only the first three combinations are
  * returned.
  */
-struct tdb *
-ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction,
-    struct tdb *tdbp, struct inpcb *inp, u_int32_t ipsecflowinfo)
+int
+ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int direction,
+    struct tdb *tdbp, struct inpcb *inp, struct tdb **tdbout,
+    u_int32_t ipsecflowinfo)
 {
        struct radix_node_head *rnh;
        struct radix_node *rn;
@@ -154,7 +155,7 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
        struct sockaddr_encap *ddst, dst;
        struct ipsec_policy *ipo;
        struct ipsec_ids *ids = NULL;
-       int signore = 0, dignore = 0;
+       int error, signore = 0, dignore = 0;
        u_int rdomain = rtable_l2(m->m_pkthdr.ph_rtableid);
 
        NET_ASSERT_LOCKED();
@@ -164,8 +165,9 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
         * continuing with the SPD lookup.
         */
        if (!ipsec_in_use && inp == NULL) {
-               *error = 0;
-               return NULL;
+               if (tdbout != NULL)
+                       *tdbout = NULL;
+               return 0;
        }
 
        /*
@@ -175,8 +177,9 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
            (inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS) &&
            (inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_BYPASS) &&
            (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS)) {
-               *error = 0;
-               return NULL;
+               if (tdbout != NULL)
+                       *tdbout = NULL;
+               return 0;
        }
 
        memset(&dst, 0, sizeof(dst));
@@ -188,10 +191,9 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
 
        switch (af) {
        case AF_INET:
-               if (hlen < sizeof (struct ip) || m->m_pkthdr.len < hlen) {
-                       *error = EINVAL;
-                       return NULL;
-               }
+               if (hlen < sizeof (struct ip) || m->m_pkthdr.len < hlen)
+                       return EINVAL;
+
                ddst->sen_direction = direction;
                ddst->sen_type = SENT_IP4;
 
@@ -215,10 +217,8 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
                case IPPROTO_UDP:
                case IPPROTO_TCP:
                        /* Make sure there's enough data in the packet. */
-                       if (m->m_pkthdr.len < hlen + 2 * sizeof(u_int16_t)) {
-                               *error = EINVAL;
-                               return NULL;
-                       }
+                       if (m->m_pkthdr.len < hlen + 2 * sizeof(u_int16_t))
+                               return EINVAL;
 
                        /*
                         * Luckily, the offset of the src/dst ports in
@@ -241,10 +241,9 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
 
 #ifdef INET6
        case AF_INET6:
-               if (hlen < sizeof (struct ip6_hdr) || m->m_pkthdr.len < hlen) {
-                       *error = EINVAL;
-                       return NULL;
-               }
+               if (hlen < sizeof (struct ip6_hdr) || m->m_pkthdr.len < hlen)
+                       return EINVAL;
+
                ddst->sen_type = SENT_IP6;
                ddst->sen_ip6_direction = direction;
 
@@ -271,10 +270,8 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
                case IPPROTO_UDP:
                case IPPROTO_TCP:
                        /* Make sure there's enough data in the packet. */
-                       if (m->m_pkthdr.len < hlen + 2 * sizeof(u_int16_t)) {
-                               *error = EINVAL;
-                               return NULL;
-                       }
+                       if (m->m_pkthdr.len < hlen + 2 * sizeof(u_int16_t))
+                               return EINVAL;
 
                        /*
                         * Luckily, the offset of the src/dst ports in
@@ -297,8 +294,7 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
 #endif /* INET6 */
 
        default:
-               *error = EAFNOSUPPORT;
-               return NULL;
+               return EAFNOSUPPORT;
        }
 
        /* Actual SPD lookup. */
@@ -308,19 +304,16 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
                 * Return whatever the socket requirements are, there are no
                 * system-wide policies.
                 */
-               *error = 0;
-               return ipsp_spd_inp(m, error, inp, NULL);
+               return ipsp_spd_inp(m, inp, NULL, tdbout);
        }
        ipo = (struct ipsec_policy *)rn;
 
        switch (ipo->ipo_type) {
        case IPSP_PERMIT:
-               *error = 0;
-               return ipsp_spd_inp(m, error, inp, ipo);
+               return ipsp_spd_inp(m, inp, ipo, tdbout);
 
        case IPSP_DENY:
-               *error = EHOSTUNREACH;
-               return NULL;
+               return EHOSTUNREACH;
 
        case IPSP_IPSEC_USE:
        case IPSP_IPSEC_ACQUIRE:
@@ -330,8 +323,7 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
                break;
 
        default:
-               *error = EINVAL;
-               return NULL;
+               return EINVAL;
        }
 
        /* Check for non-specific destination in the policy. */
@@ -391,8 +383,9 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
                        /* Direct match. */
                        if (dignore ||
                            !memcmp(&sdst, &ipo->ipo_dst, sdst.sa.sa_len)) {
-                               *error = 0;
-                               return NULL;
+                               if (tdbout != NULL)
+                                       *tdbout = NULL;
+                               return 0;
                        }
                }
 
@@ -414,8 +407,7 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
                                goto nomatchout;
 
                        /* Cached entry is good. */
-                       *error = 0;
-                       return ipsp_spd_inp(m, error, inp, ipo);
+                       return ipsp_spd_inp(m, inp, ipo, tdbout);
 
   nomatchout:
                        /* Cached TDB was not good. */
@@ -450,8 +442,7 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
                                TAILQ_INSERT_TAIL(
                                    &ipo->ipo_tdb->tdb_policy_head,
                                    ipo, ipo_tdb_next);
-                               *error = 0;
-                               return ipsp_spd_inp(m, error, inp, ipo);
+                               return ipsp_spd_inp(m, inp, ipo, tdbout);
                        }
                }
 
@@ -462,14 +453,12 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
                        if (ipsp_acquire_sa(ipo,
                            dignore ? &sdst : &ipo->ipo_dst,
                            signore ? NULL : &ipo->ipo_src, ddst, m) != 0) {
-                               *error = EACCES;
-                               return NULL;
+                               return EACCES;
                        }
 
                        /* FALLTHROUGH */
                case IPSP_IPSEC_DONTACQ:
-                       *error = -EINVAL; /* Silently drop packet. */
-                       return NULL;
+                       return -EINVAL;  /* Silently drop packet. */
 
                case IPSP_IPSEC_ACQUIRE:
                        /* Acquire SA through key management. */
@@ -478,8 +467,7 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
 
                        /* FALLTHROUGH */
                case IPSP_IPSEC_USE:
-                       *error = 0;
-                       return ipsp_spd_inp(m, error, inp, ipo);
+                       return ipsp_spd_inp(m, inp, ipo, tdbout);
                }
        } else { /* IPSP_DIRECTION_IN */
                if (tdbp != NULL) {
@@ -502,10 +490,8 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
                                tdbp = tdbp->tdb_inext;
 
                        /* Direct match in the cache. */
-                       if (ipo->ipo_tdb == tdbp) {
-                               *error = 0;
-                               return ipsp_spd_inp(m, error, inp, ipo);
-                       }
+                       if (ipo->ipo_tdb == tdbp)
+                               return ipsp_spd_inp(m, inp, ipo, tdbout);
 
                        if (memcmp(dignore ? &ssrc : &ipo->ipo_dst,
                            &tdbp->tdb_src, tdbp->tdb_src.sa.sa_len) ||
@@ -527,8 +513,7 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
                        ipo->ipo_tdb = tdb_ref(tdbp);
                        TAILQ_INSERT_TAIL(&tdbp->tdb_policy_head, ipo,
                            ipo_tdb_next);
-                       *error = 0;
-                       return ipsp_spd_inp(m, error, inp, ipo);
+                       return ipsp_spd_inp(m, inp, ipo, tdbout);
 
   nomatchin: /* Nothing needed here, falling through */
        ;
@@ -577,29 +562,23 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
                switch (ipo->ipo_type) {
                case IPSP_IPSEC_REQUIRE:
                        /* If appropriate SA exists, don't acquire another. */
-                       if (ipo->ipo_tdb) {
-                               *error = -EINVAL;
-                               return NULL;
-                       }
+                       if (ipo->ipo_tdb != NULL)
+                               return -EINVAL;  /* Silently drop packet. */
 
                        /* Acquire SA through key management. */
-                       if ((*error = ipsp_acquire_sa(ipo,
+                       if ((error = ipsp_acquire_sa(ipo,
                            dignore ? &ssrc : &ipo->ipo_dst,
                            signore ? NULL : &ipo->ipo_src, ddst, m)) != 0)
-                               return NULL;
+                               return error;
 
                        /* FALLTHROUGH */
                case IPSP_IPSEC_DONTACQ:
-                       /* Drop packet. */
-                       *error = -EINVAL;
-                       return NULL;
+                       return -EINVAL;  /* Silently drop packet. */
 
                case IPSP_IPSEC_ACQUIRE:
                        /* If appropriate SA exists, don't acquire another. */
-                       if (ipo->ipo_tdb) {
-                               *error = 0;
-                               return ipsp_spd_inp(m, error, inp, ipo);
-                       }
+                       if (ipo->ipo_tdb != NULL)
+                               return ipsp_spd_inp(m, inp, ipo, tdbout);
 
                        /* Acquire SA through key management. */
                        ipsp_acquire_sa(ipo, dignore ? &ssrc : &ipo->ipo_dst,
@@ -607,14 +586,12 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
 
                        /* FALLTHROUGH */
                case IPSP_IPSEC_USE:
-                       *error = 0;
-                       return ipsp_spd_inp(m, error, inp, ipo);
+                       return ipsp_spd_inp(m, inp, ipo, tdbout);
                }
        }
 
        /* Shouldn't ever get this far. */
-       *error = EINVAL;
-       return NULL;
+       return EINVAL;
 }
 
 /*
@@ -824,9 +801,9 @@ ipsp_acquire_sa(struct ipsec_policy *ipo
 /*
  * Deal with PCB security requirements.
  */
-struct tdb *
-ipsp_spd_inp(struct mbuf *m, int *error, struct inpcb *inp,
-    struct ipsec_policy *ipo)
+int
+ipsp_spd_inp(struct mbuf *m, struct inpcb *inp, struct ipsec_policy *ipo,
+    struct tdb **tdbout)
 {
        /* Sanity check. */
        if (inp == NULL)
@@ -844,14 +821,16 @@ ipsp_spd_inp(struct mbuf *m, int *error,
            inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_AVAIL)
                goto justreturn;
 
-       *error = -EINVAL;
-       return NULL;
+       return -EINVAL;  /* Silently drop packet. */
 
  justreturn:
-       if (ipo != NULL)
-               return ipo->ipo_tdb;
-       else
-               return NULL;
+       if (tdbout != NULL) {
+               if (ipo != NULL)
+                       *tdbout = ipo->ipo_tdb;
+               else
+                       *tdbout = NULL;
+       }
+       return 0;
 }
 
 /*
Index: netinet/ipsec_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ipsec_input.c,v
retrieving revision 1.193
diff -u -p -r1.193 ipsec_input.c
--- netinet/ipsec_input.c       25 Nov 2021 13:46:02 -0000      1.193
+++ netinet/ipsec_input.c       30 Nov 2021 21:17:24 -0000
@@ -1077,7 +1077,8 @@ ipsec_forward_check(struct mbuf *m, int 
                tdb = gettdb(tdbi->rdomain, tdbi->spi, &tdbi->dst, tdbi->proto);
        } else
                tdb = NULL;
-       ipsp_spd_lookup(m, af, hlen, &error, IPSP_DIRECTION_IN, tdb, NULL, 0);
+       error = ipsp_spd_lookup(m, af, hlen, IPSP_DIRECTION_IN,
+           tdb, NULL, NULL, 0);
        tdb_unref(tdb);
 
        return error;
@@ -1149,8 +1150,8 @@ ipsec_local_check(struct mbuf *m, int hl
                    tdbi->proto);
        } else
                tdb = NULL;
-       ipsp_spd_lookup(m, af, hlen, &error, IPSP_DIRECTION_IN,
-           tdb, NULL, 0);
+       error = ipsp_spd_lookup(m, af, hlen, IPSP_DIRECTION_IN,
+           tdb, NULL, NULL, 0);
        tdb_unref(tdb);
 
        return error;
Index: netinet/tcp_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_input.c,v
retrieving revision 1.372
diff -u -p -r1.372 tcp_input.c
--- netinet/tcp_input.c 25 Nov 2021 23:03:05 -0000      1.372
+++ netinet/tcp_input.c 30 Nov 2021 15:28:15 -0000
@@ -578,8 +578,8 @@ findpcb:
                        tdb = gettdb(tdbi->rdomain, tdbi->spi,
                            &tdbi->dst, tdbi->proto);
                }
-               ipsp_spd_lookup(m, af, iphlen, &error, IPSP_DIRECTION_IN,
-                   tdb, inp, 0);
+               error = ipsp_spd_lookup(m, af, iphlen, IPSP_DIRECTION_IN,
+                   tdb, inp, NULL, 0);
                tdb_unref(tdb);
                if (error) {
                        tcpstat_inc(tcps_rcvnosec);
Index: netinet/udp_usrreq.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.265
diff -u -p -r1.265 udp_usrreq.c
--- netinet/udp_usrreq.c        25 Nov 2021 13:46:02 -0000      1.265
+++ netinet/udp_usrreq.c        30 Nov 2021 15:29:35 -0000
@@ -510,8 +510,8 @@ udp_input(struct mbuf **mp, int *offp, i
                            &tdbi->dst, tdbi->proto);
                } else
                        tdb = NULL;
-               ipsp_spd_lookup(m, af, iphlen, &error,
-                   IPSP_DIRECTION_IN, tdb, inp, 0);
+               error = ipsp_spd_lookup(m, af, iphlen, IPSP_DIRECTION_IN,
+                   tdb, inp, NULL, 0);
                if (error) {
                        udpstat_inc(udps_nosec);
                        tdb_unref(tdb);
Index: netinet6/ip6_forward.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_forward.c,v
retrieving revision 1.102
diff -u -p -r1.102 ip6_forward.c
--- netinet6/ip6_forward.c      22 Nov 2021 13:47:10 -0000      1.102
+++ netinet6/ip6_forward.c      30 Nov 2021 15:36:19 -0000
@@ -145,8 +145,8 @@ reroute:
 
 #ifdef IPSEC
        if (ipsec_in_use) {
-               tdb = ip6_output_ipsec_lookup(m, &error, NULL);
-               if (error != 0) {
+               error = ip6_output_ipsec_lookup(m, NULL, &tdb);
+               if (error) {
                        /*
                         * -EINVAL is used to indicate that the packet should
                         * be silently dropped, typically because we've asked
Index: netinet6/ip6_output.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_output.c,v
retrieving revision 1.261
diff -u -p -r1.261 ip6_output.c
--- netinet6/ip6_output.c       24 Nov 2021 18:48:33 -0000      1.261
+++ netinet6/ip6_output.c       30 Nov 2021 21:41:03 -0000
@@ -221,8 +221,8 @@ ip6_output(struct mbuf *m, struct ip6_pk
 
 #ifdef IPSEC
        if (ipsec_in_use || inp) {
-               tdb = ip6_output_ipsec_lookup(m, &error, inp);
-               if (error != 0) {
+               error = ip6_output_ipsec_lookup(m, inp, &tdb);
+               if (error) {
                        /*
                         * -EINVAL is used to indicate that the packet should
                         * be silently dropped, typically because we've asked
@@ -2739,12 +2739,13 @@ in6_proto_cksum_out(struct mbuf *m, stru
 }
 
 #ifdef IPSEC
-struct tdb *
-ip6_output_ipsec_lookup(struct mbuf *m, int *error, struct inpcb *inp)
+int
+ip6_output_ipsec_lookup(struct mbuf *m, struct inpcb *inp, struct tdb **tdbout)
 {
        struct tdb *tdb;
        struct m_tag *mtag;
        struct tdb_ident *tdbi;
+       int error;
 
        /*
         * Check if there was an outgoing SA bound to the flow
@@ -2752,11 +2753,12 @@ ip6_output_ipsec_lookup(struct mbuf *m, 
         */
 
        /* Do we have any pending SAs to apply ? */
-       tdb = ipsp_spd_lookup(m, AF_INET6, sizeof(struct ip6_hdr),
-           error, IPSP_DIRECTION_OUT, NULL, inp, 0);
-
-       if (tdb == NULL)
-               return NULL;
+       error = ipsp_spd_lookup(m, AF_INET6, sizeof(struct ip6_hdr),
+           IPSP_DIRECTION_OUT, NULL, inp, &tdb, 0);
+       if (error || tdb == NULL) {
+               *tdbout = NULL;
+               return error;
+       }
        /* Loop detection */
        for (mtag = m_tag_first(m); mtag != NULL; mtag = m_tag_next(m, mtag)) {
                if (mtag->m_tag_id != PACKET_TAG_IPSEC_OUT_DONE)
@@ -2768,10 +2770,12 @@ ip6_output_ipsec_lookup(struct mbuf *m, 
                    !memcmp(&tdbi->dst, &tdb->tdb_dst,
                    sizeof(union sockaddr_union))) {
                        /* no IPsec needed */
-                       return NULL;
+                       *tdbout = NULL;
+                       return 0;
                }
        }
-       return tdb;
+       *tdbout = tdb;
+       return 0;
 }
 
 int
Index: netinet6/ip6_var.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_var.h,v
retrieving revision 1.88
diff -u -p -r1.88 ip6_var.h
--- netinet6/ip6_var.h  1 Mar 2021 11:05:43 -0000       1.88
+++ netinet6/ip6_var.h  30 Nov 2021 15:35:21 -0000
@@ -366,8 +366,7 @@ u_int32_t ip6_randomflowlabel(void);
 
 #ifdef IPSEC
 struct tdb;
-struct tdb *
-       ip6_output_ipsec_lookup(struct mbuf *, int *, struct inpcb *);
+int    ip6_output_ipsec_lookup(struct mbuf *, struct inpcb *, struct tdb **);
 int    ip6_output_ipsec_send(struct tdb *, struct mbuf *, struct route_in6 *,
            int, int);
 #endif /* IPSEC */

Reply via email to