-/* $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)
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.
-/* $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),
/* 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 *);
-/* $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 $ */
/*
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);
#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;
}
#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)
!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
-/* $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)
*
#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 *,
* 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;
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();
* continuing with the SPD lookup.
*/
if (!ipsec_in_use && inp == NULL) {
- *error = 0;
- return NULL;
+ if (tdbout != NULL)
+ *tdbout = NULL;
+ return 0;
}
/*
(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));
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;
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
#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;
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
#endif /* INET6 */
default:
- *error = EAFNOSUPPORT;
- return NULL;
+ return EAFNOSUPPORT;
}
/* Actual SPD lookup. */
* 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:
break;
default:
- *error = EINVAL;
- return NULL;
+ return EINVAL;
}
/* Check for non-specific destination in the policy. */
/* Direct match. */
if (dignore ||
!memcmp(&sdst, &ipo->ipo_dst, sdst.sa.sa_len)) {
- *error = 0;
- return NULL;
+ if (tdbout != NULL)
+ *tdbout = NULL;
+ return 0;
}
}
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. */
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);
}
}
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. */
/* 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) {
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) ||
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 */
;
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,
/* 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;
}
/*
/*
* 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)
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;
}
/*
-/* $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
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;
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;
-/* $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 $ */
/*
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);
-/* $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 $ */
/*
&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);
-/* $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 $ */
/*
#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
-/* $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 $ */
/*
#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
}
#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
*/
/* 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)
!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
-/* $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 $ */
/*
#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 */