On Wed, Dec 01, 2021 at 12:18:30AM +0100, Alexander Bluhm wrote:
> 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?
>
The diff looks ok by me.
> 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 */
>