From: bluhm Date: Wed, 1 Dec 2021 12:51:09 +0000 (+0000) Subject: Let ipsp_spd_lookup() return an error instead of a TDB. The TDB X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=e7111b640373b5a6d6c350a312c52251aa854d64;p=openbsd Let ipsp_spd_lookup() return an error instead of a TDB. The TDB is not always needed, but the error value is necessary for the caller. As TDB should be refcounted, it makes not sense to always return it. Pass an output pointer for the TDB which can be NULL. OK mvs@ tobhe@ --- diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index bfc4cd2f1b3..c7ebf80173a 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bridge.c,v 1.359 2021/11/25 13:46:02 bluhm Exp $ */ +/* $OpenBSD: if_bridge.c,v 1.360 2021/12/01 12:51:09 bluhm Exp $ */ /* * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) @@ -1594,9 +1594,9 @@ bridge_ipsec(struct ifnet *ifp, struct ether_header *eh, int hassnap, 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. diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h index 23edd0796ae..a810e382d46 100644 --- a/sys/netinet/ip_ipsp.h +++ b/sys/netinet/ip_ipsp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.h,v 1.224 2021/11/30 13:17:43 bluhm Exp $ */ +/* $OpenBSD: ip_ipsp.h,v 1.225 2021/12/01 12:51:09 bluhm Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr), @@ -632,8 +632,8 @@ int checkreplaywindow(struct tdb *, u_int64_t, u_int32_t, u_int32_t *, int); /* 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 *); diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 0d92e347fae..a27f69ac583 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.375 2021/11/24 18:48:33 bluhm Exp $ */ +/* $OpenBSD: ip_output.c,v 1.376 2021/12/01 12:51:09 bluhm Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -86,8 +86,8 @@ static __inline u_int16_t __attribute__((__unused__)) 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, int hlen, int *error, struct inpcb *inp, !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 diff --git a/sys/netinet/ip_spd.c b/sys/netinet/ip_spd.c index 6a80b8dd2ed..f8fad967149 100644 --- a/sys/netinet/ip_spd.c +++ b/sys/netinet/ip_spd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_spd.c,v 1.106 2021/11/30 13:17:43 bluhm Exp $ */ +/* $OpenBSD: ip_spd.c,v 1.107 2021/12/01 12:51:09 bluhm Exp $ */ /* * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) * @@ -41,8 +41,8 @@ #include #include -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, int hlen, int *error, int direction, 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, int hlen, int *error, int direction, * 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, int hlen, int *error, int direction, (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, int hlen, int *error, int direction, 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, int hlen, int *error, int direction, 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, int hlen, int *error, int direction, #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, int hlen, int *error, int direction, 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, int hlen, int *error, int direction, #endif /* INET6 */ default: - *error = EAFNOSUPPORT; - return NULL; + return EAFNOSUPPORT; } /* Actual SPD lookup. */ @@ -308,19 +304,16 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction, * 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, int hlen, int *error, int direction, 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, int hlen, int *error, int direction, /* 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, int hlen, int *error, int direction, 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, int hlen, int *error, int direction, 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, int hlen, int *error, int direction, 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, int hlen, int *error, int direction, /* 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, int hlen, int *error, int direction, 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, int hlen, int *error, int direction, 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, int hlen, int *error, int direction, 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, int hlen, int *error, int direction, /* 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, union sockaddr_union *gw, /* * 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, struct inpcb *inp, 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; } /* diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c index 9bc0d37d455..eeb287e2641 100644 --- a/sys/netinet/ipsec_input.c +++ b/sys/netinet/ipsec_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipsec_input.c,v 1.193 2021/11/25 13:46:02 bluhm Exp $ */ +/* $OpenBSD: ipsec_input.c,v 1.194 2021/12/01 12:51:09 bluhm Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -1077,7 +1077,8 @@ ipsec_forward_check(struct mbuf *m, int hlen, int af) 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 hlen, int proto, int af) 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; diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index e6744326243..5b8af422222 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_input.c,v 1.372 2021/11/25 23:03:05 deraadt Exp $ */ +/* $OpenBSD: tcp_input.c,v 1.373 2021/12/01 12:51:09 bluhm Exp $ */ /* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */ /* @@ -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); diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index f3d50ae83b9..575075f2dde 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udp_usrreq.c,v 1.265 2021/11/25 13:46:02 bluhm Exp $ */ +/* $OpenBSD: udp_usrreq.c,v 1.266 2021/12/01 12:51:09 bluhm Exp $ */ /* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */ /* @@ -510,8 +510,8 @@ udp_input(struct mbuf **mp, int *offp, int proto, int af) &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); diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c index ba9c25e16d1..c838aeeed9f 100644 --- a/sys/netinet6/ip6_forward.c +++ b/sys/netinet6/ip6_forward.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_forward.c,v 1.102 2021/11/22 13:47:10 bluhm Exp $ */ +/* $OpenBSD: ip6_forward.c,v 1.103 2021/12/01 12:51:09 bluhm Exp $ */ /* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */ /* @@ -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 diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 974147b0e57..fc7aee1f0c1 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_output.c,v 1.261 2021/11/24 18:48:33 bluhm Exp $ */ +/* $OpenBSD: ip6_output.c,v 1.262 2021/12/01 12:51:09 bluhm Exp $ */ /* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */ /* @@ -221,8 +221,8 @@ ip6_output(struct mbuf *m, struct ip6_pktopts *opt, struct route_in6 *ro, #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, struct ifnet *ifp) } #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, int *error, struct inpcb *inp) */ /* 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, int *error, struct inpcb *inp) !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 diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index cbb81efb872..4b99f9e9f10 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_var.h,v 1.88 2021/03/01 11:05:43 bluhm Exp $ */ +/* $OpenBSD: ip6_var.h,v 1.89 2021/12/01 12:51:09 bluhm Exp $ */ /* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */ /* @@ -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 */