From caf62be22cef78e7b0b6cf58140aea280f180378 Mon Sep 17 00:00:00 2001 From: purplerain Date: Thu, 11 Jan 2024 02:33:10 +0000 Subject: [PATCH] sync with OpenBSD -current --- lib/libcrypto/err/err_prn.c | 14 +- lib/libcrypto/rsa/rsa_ameth.c | 20 +-- lib/libcrypto/x509/x509_trs.c | 127 +++++++------- lib/libcrypto/x509/x509_vfy.c | 71 ++++---- sys/kern/kern_sysctl.c | 8 +- sys/net/pf.c | 4 +- sys/netinet/udp_usrreq.c | 76 +++++--- sys/netinet/udp_var.h | 4 +- usr.bin/ssh/ssh_config.5 | 6 +- usr.bin/ssh/sshd_config.5 | 6 +- usr.sbin/bgpctl/output.c | 6 +- usr.sbin/bgpd/bgpd.h | 4 +- usr.sbin/bgpd/control.c | 158 ++++++++--------- usr.sbin/bgpd/printconf.c | 23 +-- usr.sbin/bgpd/rtr_proto.c | 315 ++++++++++++++++------------------ usr.sbin/bgpd/session.c | 23 ++- usr.sbin/bgpd/session.h | 7 +- usr.sbin/bgpd/util.c | 72 +++++++- 18 files changed, 499 insertions(+), 445 deletions(-) diff --git a/lib/libcrypto/err/err_prn.c b/lib/libcrypto/err/err_prn.c index d60cfdcb9..61f4dad57 100644 --- a/lib/libcrypto/err/err_prn.c +++ b/lib/libcrypto/err/err_prn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: err_prn.c,v 1.20 2023/07/07 13:54:45 beck Exp $ */ +/* $OpenBSD: err_prn.c,v 1.22 2024/01/10 14:23:37 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -56,6 +56,7 @@ * [including the GNU Public Licence.] */ +#include #include #include @@ -93,12 +94,9 @@ LCRYPTO_ALIAS(ERR_print_errors_cb); static int print_fp(const char *str, size_t len, void *fp) { - BIO bio; - - BIO_set(&bio, BIO_s_file()); - BIO_set_fp(&bio, fp, BIO_NOCLOSE); - - return BIO_printf(&bio, "%s", str); + if (len > INT_MAX) + return -1; + return fprintf(fp, "%.*s", (int)len, str); } void @@ -111,7 +109,7 @@ LCRYPTO_ALIAS(ERR_print_errors_fp); static int print_bio(const char *str, size_t len, void *bp) { - return BIO_write((BIO *)bp, str, len); + return BIO_write(bp, str, len); } void diff --git a/lib/libcrypto/rsa/rsa_ameth.c b/lib/libcrypto/rsa/rsa_ameth.c index b8957c0d1..0c351f49e 100644 --- a/lib/libcrypto/rsa/rsa_ameth.c +++ b/lib/libcrypto/rsa/rsa_ameth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rsa_ameth.c,v 1.56 2024/01/04 17:01:26 tb Exp $ */ +/* $OpenBSD: rsa_ameth.c,v 1.57 2024/01/10 14:59:19 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -74,10 +74,6 @@ #include "rsa_local.h" #include "x509_local.h" -/* Macros to test if a pkey or ctx is for a PSS key */ -#define pkey_is_pss(pkey) (pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS) -#define pkey_ctx_is_pss(ctx) (ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS) - #ifndef OPENSSL_NO_CMS static int rsa_cms_sign(CMS_SignerInfo *si); static int rsa_cms_verify(CMS_SignerInfo *si); @@ -453,7 +449,8 @@ pkey_rsa_print(BIO *bp, const EVP_PKEY *pkey, int off, int priv) if (!BIO_indent(bp, off, 128)) goto err; - if (BIO_printf(bp, "%s ", pkey_is_pss(pkey) ? "RSA-PSS" : "RSA") <= 0) + if (BIO_printf(bp, "%s ", + pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS ? "RSA-PSS" : "RSA") <= 0) goto err; if (priv && x->d != NULL) { @@ -485,7 +482,8 @@ pkey_rsa_print(BIO *bp, const EVP_PKEY *pkey, int off, int priv) if (!bn_printf(bp, x->iqmp, off, "coefficient:")) goto err; } - if (pkey_is_pss(pkey) && !rsa_pss_param_print(bp, 1, x->pss, off)) + if (pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS && + !rsa_pss_param_print(bp, 1, x->pss, off)) goto err; ret = 1; err: @@ -539,7 +537,7 @@ rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) break; case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: - if (pkey_is_pss(pkey)) + if (pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS) return -2; if (arg1 == 0) PKCS7_RECIP_INFO_get0_alg(arg2, &alg); @@ -553,7 +551,7 @@ rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) break; case ASN1_PKEY_CTRL_CMS_ENVELOPE: - if (pkey_is_pss(pkey)) + if (pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS) return -2; if (arg1 == 0) return rsa_cms_encrypt(arg2); @@ -562,7 +560,7 @@ rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) break; case ASN1_PKEY_CTRL_CMS_RI_TYPE: - if (pkey_is_pss(pkey)) + if (pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS) return -2; *(int *)arg2 = CMS_RECIPINFO_TRANS; return 1; @@ -852,7 +850,7 @@ rsa_cms_verify(CMS_SignerInfo *si) if (nid == EVP_PKEY_RSA_PSS) return rsa_pss_to_ctx(NULL, pkey_ctx, alg, NULL); /* Only PSS allowed for PSS keys */ - if (pkey_ctx_is_pss(pkey_ctx)) { + if (pkey_ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS) { RSAerror(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); return 0; } diff --git a/lib/libcrypto/x509/x509_trs.c b/lib/libcrypto/x509/x509_trs.c index db5056dfd..efa648c9e 100644 --- a/lib/libcrypto/x509/x509_trs.c +++ b/lib/libcrypto/x509/x509_trs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x509_trs.c,v 1.35 2024/01/08 03:32:01 tb Exp $ */ +/* $OpenBSD: x509_trs.c,v 1.39 2024/01/10 21:34:53 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 1999. */ @@ -57,19 +57,72 @@ */ #include -#include +#include #include +#include +#include #include #include "x509_local.h" -static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags); -static int trust_1oid(X509_TRUST *trust, X509 *x, int flags); -static int trust_compat(X509_TRUST *trust, X509 *x, int flags); +static int +obj_trust(int id, X509 *x, int flags) +{ + ASN1_OBJECT *obj; + int i, nid; + X509_CERT_AUX *ax; -static int obj_trust(int id, X509 *x, int flags); -static int (*default_trust)(int id, X509 *x, int flags) = obj_trust; + ax = x->aux; + if (!ax) + return X509_TRUST_UNTRUSTED; + if (ax->reject) { + for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) { + obj = sk_ASN1_OBJECT_value(ax->reject, i); + nid = OBJ_obj2nid(obj); + if (nid == id || nid == NID_anyExtendedKeyUsage) + return X509_TRUST_REJECTED; + } + } + if (ax->trust) { + for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) { + obj = sk_ASN1_OBJECT_value(ax->trust, i); + nid = OBJ_obj2nid(obj); + if (nid == id || nid == NID_anyExtendedKeyUsage) + return X509_TRUST_TRUSTED; + } + } + return X509_TRUST_UNTRUSTED; +} + +static int +trust_compat(X509_TRUST *trust, X509 *x, int flags) +{ + X509_check_purpose(x, -1, 0); + if (x->ex_flags & EXFLAG_SS) + return X509_TRUST_TRUSTED; + else + return X509_TRUST_UNTRUSTED; +} + +static int +trust_1oidany(X509_TRUST *trust, X509 *x, int flags) +{ + if (x->aux && (x->aux->trust || x->aux->reject)) + return obj_trust(trust->arg1, x, flags); + /* we don't have any trust settings: for compatibility + * we return trusted if it is self signed + */ + return trust_compat(trust, x, flags); +} + +static int +trust_1oid(X509_TRUST *trust, X509 *x, int flags) +{ + if (x->aux) + return obj_trust(trust->arg1, x, flags); + return X509_TRUST_UNTRUSTED; +} /* WARNING: the following table should be kept in order of trust * and without any gaps so we can just subtract the minimum trust @@ -128,6 +181,8 @@ static X509_TRUST trstandard[] = { #define X509_TRUST_COUNT (sizeof(trstandard) / sizeof(trstandard[0])) +static int (*default_trust)(int id, X509 *x, int flags) = obj_trust; + int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int) { @@ -249,61 +304,3 @@ X509_TRUST_get_trust(const X509_TRUST *xp) return xp->trust; } LCRYPTO_ALIAS(X509_TRUST_get_trust); - -static int -trust_1oidany(X509_TRUST *trust, X509 *x, int flags) -{ - if (x->aux && (x->aux->trust || x->aux->reject)) - return obj_trust(trust->arg1, x, flags); - /* we don't have any trust settings: for compatibility - * we return trusted if it is self signed - */ - return trust_compat(trust, x, flags); -} - -static int -trust_1oid(X509_TRUST *trust, X509 *x, int flags) -{ - if (x->aux) - return obj_trust(trust->arg1, x, flags); - return X509_TRUST_UNTRUSTED; -} - -static int -trust_compat(X509_TRUST *trust, X509 *x, int flags) -{ - X509_check_purpose(x, -1, 0); - if (x->ex_flags & EXFLAG_SS) - return X509_TRUST_TRUSTED; - else - return X509_TRUST_UNTRUSTED; -} - -static int -obj_trust(int id, X509 *x, int flags) -{ - ASN1_OBJECT *obj; - int i, nid; - X509_CERT_AUX *ax; - - ax = x->aux; - if (!ax) - return X509_TRUST_UNTRUSTED; - if (ax->reject) { - for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) { - obj = sk_ASN1_OBJECT_value(ax->reject, i); - nid = OBJ_obj2nid(obj); - if (nid == id || nid == NID_anyExtendedKeyUsage) - return X509_TRUST_REJECTED; - } - } - if (ax->trust) { - for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) { - obj = sk_ASN1_OBJECT_value(ax->trust, i); - nid = OBJ_obj2nid(obj); - if (nid == id || nid == NID_anyExtendedKeyUsage) - return X509_TRUST_TRUSTED; - } - } - return X509_TRUST_UNTRUSTED; -} diff --git a/lib/libcrypto/x509/x509_vfy.c b/lib/libcrypto/x509/x509_vfy.c index ada8ec124..60a37229b 100644 --- a/lib/libcrypto/x509/x509_vfy.c +++ b/lib/libcrypto/x509/x509_vfy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x509_vfy.c,v 1.138 2024/01/09 07:25:57 tb Exp $ */ +/* $OpenBSD: x509_vfy.c,v 1.139 2024/01/10 17:31:28 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -2182,54 +2182,53 @@ X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, } LCRYPTO_ALIAS(X509_STORE_CTX_purpose_inherit); -static int -x509_vfy_purpose_inherit(X509_STORE_CTX *ctx, int purpose, int trust) +int +X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose_id) { - /* If we have a purpose then check it is valid */ - if (purpose != 0) { - const X509_PURPOSE *purp; - int purpose_idx; + const X509_PURPOSE *purpose; + int idx; - if (purpose < X509_PURPOSE_MIN || purpose > X509_PURPOSE_MAX) { - X509error(X509_R_UNKNOWN_PURPOSE_ID); - return 0; - } - purpose_idx = purpose - X509_PURPOSE_MIN; - if ((purp = X509_PURPOSE_get0(purpose_idx)) == NULL) { - X509error(X509_R_UNKNOWN_PURPOSE_ID); - return 0; - } + /* XXX - Match wacky/documented behavior. Do we need to keep this? */ + if (purpose_id == 0) + return 1; - /* If trust is unset, use the purpose's trust. */ - if (trust == 0) - trust = purp->trust; + if (purpose_id < X509_PURPOSE_MIN || purpose_id > X509_PURPOSE_MAX) { + X509error(X509_R_UNKNOWN_PURPOSE_ID); + return 0; } - if (trust != 0) { - if (trust < X509_TRUST_MIN || trust > X509_TRUST_MAX) { - X509error(X509_R_UNKNOWN_TRUST_ID); - return 0; - } + idx = purpose_id - X509_PURPOSE_MIN; + if ((purpose = X509_PURPOSE_get0(idx)) == NULL) { + X509error(X509_R_UNKNOWN_PURPOSE_ID); + return 0; } - if (purpose != 0 && ctx->param->purpose == 0) - ctx->param->purpose = purpose; - if (trust != 0 && ctx->param->trust == 0) - ctx->param->trust = trust; + /* XXX - Succeeding while ignoring purpose_id and trust is awful. */ + if (ctx->param->purpose == 0) + ctx->param->purpose = purpose_id; + if (ctx->param->trust == 0) + ctx->param->trust = purpose->trust; return 1; } - -int -X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) -{ - return x509_vfy_purpose_inherit(ctx, purpose, 0); -} LCRYPTO_ALIAS(X509_STORE_CTX_set_purpose); int -X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) +X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust_id) { - return x509_vfy_purpose_inherit(ctx, 0, trust); + /* XXX - Match wacky/documented behavior. Do we need to keep this? */ + if (trust_id == 0) + return 1; + + if (trust_id < X509_TRUST_MIN || trust_id > X509_TRUST_MAX) { + X509error(X509_R_UNKNOWN_TRUST_ID); + return 0; + } + + /* XXX - Succeeding while ignoring the trust_id is awful. */ + if (ctx->param->trust == 0) + ctx->param->trust = trust_id; + + return 1; } LCRYPTO_ALIAS(X509_STORE_CTX_set_trust); diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index ee4149412..bcabee27f 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sysctl.c,v 1.420 2023/10/01 15:58:12 krw Exp $ */ +/* $OpenBSD: kern_sysctl.c,v 1.421 2024/01/10 16:44:30 bluhm Exp $ */ /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ /*- @@ -1493,6 +1493,12 @@ sysctl_file(int *name, u_int namelen, char *where, size_t *sizep, TAILQ_FOREACH(inp, &udbtable.inpt_queue, inp_queue) FILLSO(inp->inp_socket); mtx_leave(&udbtable.inpt_mtx); +#ifdef INET6 + mtx_enter(&udb6table.inpt_mtx); + TAILQ_FOREACH(inp, &udb6table.inpt_queue, inp_queue) + FILLSO(inp->inp_socket); + mtx_leave(&udb6table.inpt_mtx); +#endif mtx_enter(&rawcbtable.inpt_mtx); TAILQ_FOREACH(inp, &rawcbtable.inpt_queue, inp_queue) FILLSO(inp->inp_socket); diff --git a/sys/net/pf.c b/sys/net/pf.c index d1ce9f369..f8e6f20bf 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.1192 2024/01/01 22:16:51 bluhm Exp $ */ +/* $OpenBSD: pf.c,v 1.1193 2024/01/10 16:44:30 bluhm Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -3841,6 +3841,8 @@ pf_socket_lookup(struct pf_pdesc *pd) break; #ifdef INET6 case AF_INET6: + if (pd->virtual_proto == IPPROTO_UDP) + tb = &udb6table; inp = in6_pcblookup(tb, &saddr->v6, sport, &daddr->v6, dport, pd->rdomain); if (inp == NULL) { diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 7ad852405..61d38578a 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udp_usrreq.c,v 1.312 2023/12/01 15:30:47 bluhm Exp $ */ +/* $OpenBSD: udp_usrreq.c,v 1.313 2024/01/10 16:44:30 bluhm Exp $ */ /* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */ /* @@ -161,6 +161,9 @@ const struct sysctl_bounded_args udpctl_vars[] = { }; struct inpcbtable udbtable; +#ifdef INET6 +struct inpcbtable udb6table; +#endif struct cpumem *udpcounters; void udp_sbappend(struct inpcb *, struct mbuf *, struct ip *, @@ -179,6 +182,9 @@ udp_init(void) { udpcounters = counters_alloc(udps_ncounters); in_pcbinit(&udbtable, UDB_INITIAL_HASH_SIZE); +#ifdef INET6 + in_pcbinit(&udb6table, UDB_INITIAL_HASH_SIZE); +#endif } int @@ -375,6 +381,7 @@ udp_input(struct mbuf **mp, int *offp, int proto, int af) if (m->m_flags & (M_BCAST|M_MCAST)) { SIMPLEQ_HEAD(, inpcb) inpcblist; + struct inpcbtable *tb; /* * Deliver a multicast or broadcast datagram to *all* sockets @@ -397,17 +404,24 @@ udp_input(struct mbuf **mp, int *offp, int proto, int af) * (Algorithm copied from raw_intr().) */ SIMPLEQ_INIT(&inpcblist); - rw_enter_write(&udbtable.inpt_notify); - mtx_enter(&udbtable.inpt_mtx); - TAILQ_FOREACH(inp, &udbtable.inpt_queue, inp_queue) { +#ifdef INET6 + if (ip6) + tb = &udb6table; + else +#endif + tb = &udbtable; + + rw_enter_write(&tb->inpt_notify); + mtx_enter(&tb->inpt_mtx); + TAILQ_FOREACH(inp, &tb->inpt_queue, inp_queue) { if (inp->inp_socket->so_rcv.sb_state & SS_CANTRCVMORE) continue; #ifdef INET6 - /* don't accept it if AF does not match */ - if (ip6 && !(inp->inp_flags & INP_IPV6)) - continue; - if (!ip6 && (inp->inp_flags & INP_IPV6)) - continue; + /* table is per AF, panic if it does not match */ + if (ip6) + KASSERT(ISSET(inp->inp_flags, INP_IPV6)); + else + KASSERT(!ISSET(inp->inp_flags, INP_IPV6)); #endif if (rtable_l2(inp->inp_rtableid) != rtable_l2(m->m_pkthdr.ph_rtableid)) @@ -467,10 +481,10 @@ udp_input(struct mbuf **mp, int *offp, int proto, int af) SO_REUSEADDR)) == 0) break; } - mtx_leave(&udbtable.inpt_mtx); + mtx_leave(&tb->inpt_mtx); if (SIMPLEQ_EMPTY(&inpcblist)) { - rw_exit_write(&udbtable.inpt_notify); + rw_exit_write(&tb->inpt_notify); /* * No matching pcb found; discard datagram. @@ -495,7 +509,7 @@ udp_input(struct mbuf **mp, int *offp, int proto, int af) } in_pcbunref(inp); } - rw_exit_write(&udbtable.inpt_notify); + rw_exit_write(&tb->inpt_notify); return IPPROTO_DONE; } @@ -507,25 +521,30 @@ udp_input(struct mbuf **mp, int *offp, int proto, int af) #endif if (inp == NULL) { #ifdef INET6 - if (ip6) - inp = in6_pcblookup(&udbtable, &ip6->ip6_src, + if (ip6) { + inp = in6_pcblookup(&udb6table, &ip6->ip6_src, uh->uh_sport, &ip6->ip6_dst, uh->uh_dport, m->m_pkthdr.ph_rtableid); - else + } else #endif /* INET6 */ - inp = in_pcblookup(&udbtable, ip->ip_src, uh->uh_sport, - ip->ip_dst, uh->uh_dport, m->m_pkthdr.ph_rtableid); + { + inp = in_pcblookup(&udbtable, ip->ip_src, + uh->uh_sport, ip->ip_dst, uh->uh_dport, + m->m_pkthdr.ph_rtableid); + } } if (inp == NULL) { udpstat_inc(udps_pcbhashmiss); #ifdef INET6 if (ip6) { - inp = in6_pcblookup_listen(&udbtable, &ip6->ip6_dst, + inp = in6_pcblookup_listen(&udb6table, &ip6->ip6_dst, uh->uh_dport, m, m->m_pkthdr.ph_rtableid); } else #endif /* INET6 */ - inp = in_pcblookup_listen(&udbtable, ip->ip_dst, - uh->uh_dport, m, m->m_pkthdr.ph_rtableid); + { + inp = in_pcblookup_listen(&udbtable, ip->ip_dst, + uh->uh_dport, m, m->m_pkthdr.ph_rtableid); + } } #ifdef IPSEC @@ -809,7 +828,7 @@ udp6_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *d) * corresponding to the address in the ICMPv6 message * payload. */ - inp = in6_pcblookup(&udbtable, &sa6.sin6_addr, + inp = in6_pcblookup(&udb6table, &sa6.sin6_addr, uh.uh_dport, &sa6_src.sin6_addr, uh.uh_sport, rdomain); #if 0 @@ -821,7 +840,7 @@ udp6_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *d) * is really ours. */ if (inp == NULL) { - inp = in6_pcblookup_listen(&udbtable, + inp = in6_pcblookup_listen(&udb6table, &sa6_src.sin6_addr, uh.uh_sport, NULL, rdomain)) } @@ -847,10 +866,10 @@ udp6_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *d) */ } - in6_pcbnotify(&udbtable, &sa6, uh.uh_dport, + in6_pcbnotify(&udb6table, &sa6, uh.uh_dport, &sa6_src, uh.uh_sport, rdomain, cmd, cmdarg, notify); } else { - in6_pcbnotify(&udbtable, &sa6, 0, + in6_pcbnotify(&udb6table, &sa6, 0, &sa6_any, 0, rdomain, cmd, cmdarg, notify); } } @@ -1079,6 +1098,7 @@ release: int udp_attach(struct socket *so, int proto, int wait) { + struct inpcbtable *tb; int error; if (so->so_pcb != NULL) @@ -1088,7 +1108,13 @@ udp_attach(struct socket *so, int proto, int wait) return error; NET_ASSERT_LOCKED(); - if ((error = in_pcballoc(so, &udbtable, wait))) +#ifdef INET6 + if (so->so_proto->pr_domain->dom_family == PF_INET6) + tb = &udb6table; + else +#endif + tb = &udbtable; + if ((error = in_pcballoc(so, tb, wait))) return error; #ifdef INET6 if (sotoinpcb(so)->inp_flags & INP_IPV6) diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h index cd4dafbbd..80df3318f 100644 --- a/sys/netinet/udp_var.h +++ b/sys/netinet/udp_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: udp_var.h,v 1.49 2022/10/17 14:49:02 mvs Exp $ */ +/* $OpenBSD: udp_var.h,v 1.50 2024/01/10 16:44:30 bluhm Exp $ */ /* $NetBSD: udp_var.h,v 1.12 1996/02/13 23:44:41 christos Exp $ */ /* @@ -123,7 +123,7 @@ udpstat_inc(enum udpstat_counters c) counters_inc(udpcounters, c); } -extern struct inpcbtable udbtable; +extern struct inpcbtable udbtable, udb6table; extern struct udpstat udpstat; extern const struct pr_usrreqs udp_usrreqs; diff --git a/usr.bin/ssh/ssh_config.5 b/usr.bin/ssh/ssh_config.5 index 56f871f47..19a2402dc 100644 --- a/usr.bin/ssh/ssh_config.5 +++ b/usr.bin/ssh/ssh_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.392 2024/01/09 22:19:00 djm Exp $ -.Dd $Mdocdate: January 9 2024 $ +.\" $OpenBSD: ssh_config.5,v 1.393 2024/01/10 06:33:13 jmc Exp $ +.Dd $Mdocdate: January 10 2024 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -481,7 +481,7 @@ Specifying a zero value disables the inactivity timeout. .Pp The special timeout .Dq global -Applies to all active channels, taken together. +applies to all active channels, taken together. Traffic on any active channel will reset the timeout, but when the timeout expires then all open channels will be closed. Note that this global timeout is not matched by wildcards and must be diff --git a/usr.bin/ssh/sshd_config.5 b/usr.bin/ssh/sshd_config.5 index 0f859de14..0cc1fd719 100644 --- a/usr.bin/ssh/sshd_config.5 +++ b/usr.bin/ssh/sshd_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.351 2024/01/09 22:19:00 djm Exp $ -.Dd $Mdocdate: January 9 2024 $ +.\" $OpenBSD: sshd_config.5,v 1.352 2024/01/10 06:33:13 jmc Exp $ +.Dd $Mdocdate: January 10 2024 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -428,7 +428,7 @@ Specifying a zero value disables the inactivity timeout. .Pp The special timeout .Dq global -Applies to all active channels, taken together. +applies to all active channels, taken together. Traffic on any active channel will reset the timeout, but when the timeout expires then all open channels will be closed. Note that this global timeout is not matched by wildcards and must be diff --git a/usr.sbin/bgpctl/output.c b/usr.sbin/bgpctl/output.c index 9c8ba257d..f68b73d60 100644 --- a/usr.sbin/bgpctl/output.c +++ b/usr.sbin/bgpctl/output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: output.c,v 1.43 2023/12/19 10:32:20 claudio Exp $ */ +/* $OpenBSD: output.c,v 1.44 2024/01/10 14:59:41 claudio Exp $ */ /* * Copyright (c) 2003 Henning Brauer @@ -1185,14 +1185,14 @@ show_rtr(struct ctl_show_rtr *rtr) printf(" Last sent error: %s\n", log_rtr_error(rtr->last_sent_error)); if (rtr->last_sent_msg[0]) - printf(" with reason \"%s\"", + printf(" with reason \"%s\"\n", log_reason(rtr->last_sent_msg)); } if (rtr->last_recv_error != NO_ERROR) { printf(" Last received error: %s\n", log_rtr_error(rtr->last_recv_error)); if (rtr->last_recv_msg[0]) - printf(" with reason \"%s\"", + printf(" with reason \"%s\"\n", log_reason(rtr->last_recv_msg)); } diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index d65f329b7..0c05c8310 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.479 2024/01/08 15:08:34 claudio Exp $ */ +/* $OpenBSD: bgpd.h,v 1.480 2024/01/10 13:31:09 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -1541,6 +1541,8 @@ const char *log_as(uint32_t); const char *log_rd(uint64_t); const char *log_ext_subtype(int, uint8_t); const char *log_reason(const char *); +const char *log_roa(struct roa *); +const char *log_aspa(struct aspa_set *); const char *log_rtr_error(enum rtr_error); const char *log_policy(enum role); int aspath_snprint(char *, size_t, void *, uint16_t); diff --git a/usr.sbin/bgpd/control.c b/usr.sbin/bgpd/control.c index 79c548e48..300822ae7 100644 --- a/usr.sbin/bgpd/control.c +++ b/usr.sbin/bgpd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.114 2023/11/07 11:18:35 claudio Exp $ */ +/* $OpenBSD: control.c,v 1.115 2024/01/10 11:08:04 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -219,7 +219,7 @@ int control_close(struct ctl_conn *c) { if (c->terminate && c->ibuf.pid) - imsg_ctl_rde(IMSG_CTL_TERMINATE, 0, c->ibuf.pid, NULL, 0); + imsg_ctl_rde_msg(IMSG_CTL_TERMINATE, 0, c->ibuf.pid); msgbuf_clear(&c->ibuf.w); TAILQ_REMOVE(&ctl_conns, c, entry); @@ -234,12 +234,14 @@ int control_dispatch_msg(struct pollfd *pfd, struct peer_head *peers) { struct imsg imsg; + struct ctl_neighbor neighbor; + struct ctl_show_rib_request ribreq; struct ctl_conn *c; - ssize_t n; - int verbose, matched; struct peer *p; - struct ctl_neighbor *neighbor; - struct ctl_show_rib_request *ribreq; + ssize_t n; + uint32_t type; + pid_t pid; + int verbose, matched; if ((c = control_connbyfd(pfd->fd)) == NULL) { log_warn("control_dispatch_msg: fd %d: not found", pfd->fd); @@ -250,8 +252,7 @@ control_dispatch_msg(struct pollfd *pfd, struct peer_head *peers) if (msgbuf_write(&c->ibuf.w) <= 0 && errno != EAGAIN) return control_close(c); if (c->throttled && c->ibuf.w.queued < CTL_MSG_LOW_MARK) { - if (imsg_ctl_rde(IMSG_XON, 0, c->ibuf.pid, NULL, 0) != - -1) + if (imsg_ctl_rde_msg(IMSG_XON, 0, c->ibuf.pid) != -1) c->throttled = 0; } } @@ -270,8 +271,10 @@ control_dispatch_msg(struct pollfd *pfd, struct peer_head *peers) if (n == 0) break; + type = imsg_get_type(&imsg); + pid = imsg_get_pid(&imsg); if (c->restricted) { - switch (imsg.hdr.type) { + switch (type) { case IMSG_CTL_SHOW_NEIGHBOR: case IMSG_CTL_SHOW_NEXTHOP: case IMSG_CTL_SHOW_INTERFACE: @@ -287,20 +290,25 @@ control_dispatch_msg(struct pollfd *pfd, struct peer_head *peers) break; default: /* clear imsg type to prevent processing */ - imsg.hdr.type = IMSG_NONE; + type = IMSG_NONE; control_result(c, CTL_RES_DENIED); break; } } - switch (imsg.hdr.type) { + /* + * TODO: this is wrong and shoud work the other way around. + * The imsg.hdr.pid is from the remote end and should not + * be trusted. + */ + c->ibuf.pid = pid; + switch (type) { case IMSG_NONE: /* message was filtered out, nothing to do */ break; case IMSG_CTL_FIB_COUPLE: case IMSG_CTL_FIB_DECOUPLE: - imsg_ctl_parent(imsg.hdr.type, imsg.hdr.peerid, - 0, NULL, 0); + imsg_ctl_parent(&imsg); break; case IMSG_CTL_SHOW_TERSE: RB_FOREACH(p, peer_head, peers) @@ -309,23 +317,19 @@ control_dispatch_msg(struct pollfd *pfd, struct peer_head *peers) imsg_compose(&c->ibuf, IMSG_CTL_END, 0, 0, -1, NULL, 0); break; case IMSG_CTL_SHOW_NEIGHBOR: - c->ibuf.pid = imsg.hdr.pid; + if (imsg_get_data(&imsg, &neighbor, + sizeof(neighbor)) == -1) + memset(&neighbor, 0, sizeof(neighbor)); - if (imsg.hdr.len == IMSG_HEADER_SIZE + - sizeof(struct ctl_neighbor)) { - neighbor = imsg.data; - } else { - neighbor = NULL; - } matched = 0; RB_FOREACH(p, peer_head, peers) { - if (!peer_matched(p, neighbor)) + if (!peer_matched(p, &neighbor)) continue; matched = 1; - if (!neighbor || !neighbor->show_timers) { - imsg_ctl_rde(imsg.hdr.type, p->conf.id, - imsg.hdr.pid, NULL, 0); + if (!neighbor.show_timers) { + imsg_ctl_rde_msg(type, + p->conf.id, pid); } else { u_int i; time_t d; @@ -348,9 +352,8 @@ control_dispatch_msg(struct pollfd *pfd, struct peer_head *peers) } if (!matched && RB_EMPTY(peers)) { control_result(c, CTL_RES_NOSUCHPEER); - } else if (!neighbor || !neighbor->show_timers) { - imsg_ctl_rde(IMSG_CTL_END, 0, imsg.hdr.pid, - NULL, 0); + } else if (!neighbor.show_timers) { + imsg_ctl_rde_msg(IMSG_CTL_END, 0, pid); } else { imsg_compose(&c->ibuf, IMSG_CTL_END, 0, 0, -1, NULL, 0); @@ -361,23 +364,21 @@ control_dispatch_msg(struct pollfd *pfd, struct peer_head *peers) case IMSG_CTL_NEIGHBOR_CLEAR: case IMSG_CTL_NEIGHBOR_RREFRESH: case IMSG_CTL_NEIGHBOR_DESTROY: - if (imsg.hdr.len != IMSG_HEADER_SIZE + - sizeof(struct ctl_neighbor)) { + if (imsg_get_data(&imsg, &neighbor, + sizeof(neighbor)) == -1) { log_warnx("got IMSG_CTL_NEIGHBOR_ with " "wrong length"); break; } - neighbor = imsg.data; - matched = 0; RB_FOREACH(p, peer_head, peers) { - if (!peer_matched(p, neighbor)) + if (!peer_matched(p, &neighbor)) continue; matched = 1; - switch (imsg.hdr.type) { + switch (type) { case IMSG_CTL_NEIGHBOR_UP: bgp_fsm(p, EVNT_START); p->conf.down = 0; @@ -388,22 +389,20 @@ control_dispatch_msg(struct pollfd *pfd, struct peer_head *peers) control_result(c, CTL_RES_OK); break; case IMSG_CTL_NEIGHBOR_DOWN: - neighbor->reason[ - sizeof(neighbor->reason) - 1] = - '\0'; + neighbor.reason[ + sizeof(neighbor.reason) - 1] = '\0'; strlcpy(p->conf.reason, - neighbor->reason, + neighbor.reason, sizeof(p->conf.reason)); p->conf.down = 1; session_stop(p, ERR_CEASE_ADMIN_DOWN); control_result(c, CTL_RES_OK); break; case IMSG_CTL_NEIGHBOR_CLEAR: - neighbor->reason[ - sizeof(neighbor->reason) - 1] = - '\0'; + neighbor.reason[ + sizeof(neighbor.reason) - 1] = '\0'; strlcpy(p->conf.reason, - neighbor->reason, + neighbor.reason, sizeof(p->conf.reason)); p->IdleHoldTime = INTERVAL_IDLE_HOLD_INITIAL; @@ -455,51 +454,40 @@ control_dispatch_msg(struct pollfd *pfd, struct peer_head *peers) case IMSG_CTL_SHOW_INTERFACE: case IMSG_CTL_SHOW_FIB_TABLES: case IMSG_CTL_SHOW_RTR: - c->ibuf.pid = imsg.hdr.pid; - imsg_ctl_parent(imsg.hdr.type, 0, imsg.hdr.pid, - imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); + imsg_ctl_parent(&imsg); break; case IMSG_CTL_KROUTE: case IMSG_CTL_KROUTE_ADDR: case IMSG_CTL_SHOW_NEXTHOP: - c->ibuf.pid = imsg.hdr.pid; - imsg_ctl_parent(imsg.hdr.type, imsg.hdr.peerid, - imsg.hdr.pid, imsg.data, imsg.hdr.len - - IMSG_HEADER_SIZE); + imsg_ctl_parent(&imsg); break; case IMSG_CTL_SHOW_RIB: case IMSG_CTL_SHOW_RIB_PREFIX: - if (imsg.hdr.len != IMSG_HEADER_SIZE + - sizeof(struct ctl_show_rib_request)) { + if (imsg_get_data(&imsg, &ribreq, sizeof(ribreq)) == + -1) { log_warnx("got IMSG_CTL_SHOW_RIB with " "wrong length"); break; } - ribreq = imsg.data; - neighbor = &ribreq->neighbor; - /* check if at least one neighbor exists */ RB_FOREACH(p, peer_head, peers) - if (peer_matched(p, neighbor)) + if (peer_matched(p, &ribreq.neighbor)) break; if (p == NULL && RB_EMPTY(peers)) { control_result(c, CTL_RES_NOSUCHPEER); break; } - if ((imsg.hdr.type == IMSG_CTL_SHOW_RIB_PREFIX) - && (ribreq->prefix.aid == AID_UNSPEC)) { + if (type == IMSG_CTL_SHOW_RIB_PREFIX && + ribreq.prefix.aid == AID_UNSPEC) { /* malformed request, must specify af */ control_result(c, CTL_RES_PARSE_ERROR); break; } - c->ibuf.pid = imsg.hdr.pid; c->terminate = 1; - - imsg_ctl_rde(imsg.hdr.type, 0, imsg.hdr.pid, - imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); + imsg_ctl_rde(&imsg); break; case IMSG_CTL_SHOW_NETWORK: case IMSG_CTL_SHOW_FLOWSPEC: @@ -507,9 +495,7 @@ control_dispatch_msg(struct pollfd *pfd, struct peer_head *peers) /* FALLTHROUGH */ case IMSG_CTL_SHOW_RIB_MEM: case IMSG_CTL_SHOW_SET: - c->ibuf.pid = imsg.hdr.pid; - imsg_ctl_rde(imsg.hdr.type, 0, imsg.hdr.pid, - imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); + imsg_ctl_rde(&imsg); break; case IMSG_NETWORK_ADD: case IMSG_NETWORK_ASPATH: @@ -522,21 +508,16 @@ control_dispatch_msg(struct pollfd *pfd, struct peer_head *peers) case IMSG_FLOWSPEC_DONE: case IMSG_FLOWSPEC_FLUSH: case IMSG_FILTER_SET: - imsg_ctl_rde(imsg.hdr.type, 0, 0, - imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); + imsg_ctl_rde(&imsg); break; case IMSG_CTL_LOG_VERBOSE: - if (imsg.hdr.len != IMSG_HEADER_SIZE + - sizeof(verbose)) + if (imsg_get_data(&imsg, &verbose, sizeof(verbose)) == + -1) break; /* forward to other processes */ - imsg_ctl_parent(imsg.hdr.type, 0, imsg.hdr.pid, - imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); - imsg_ctl_rde(imsg.hdr.type, 0, imsg.hdr.pid, - imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); - - memcpy(&verbose, imsg.data, sizeof(verbose)); + imsg_ctl_parent(&imsg); + imsg_ctl_rde(&imsg); log_setverbose(verbose); break; default: @@ -552,23 +533,28 @@ int control_imsg_relay(struct imsg *imsg, struct peer *p) { struct ctl_conn *c; + uint32_t type; + pid_t pid; - if ((c = control_connbypid(imsg->hdr.pid)) == NULL) + type = imsg_get_type(imsg); + pid = imsg_get_pid(imsg); + + if ((c = control_connbypid(pid)) == NULL) return (0); /* special handling for peers since only the stats are sent from RDE */ - if (imsg->hdr.type == IMSG_CTL_SHOW_NEIGHBOR) { + if (type == IMSG_CTL_SHOW_NEIGHBOR) { struct rde_peer_stats stats; - if (imsg->hdr.len > IMSG_HEADER_SIZE + sizeof(stats)) { - log_warnx("wrong imsg len"); - return (0); - } if (p == NULL) { - log_warnx("no such peer: id=%u", imsg->hdr.peerid); + log_warnx("%s: no such peer: id=%u", __func__, + imsg_get_id(imsg)); + return (0); + } + if (imsg_get_data(imsg, &stats, sizeof(stats)) == -1) { + log_warnx("%s: imsg_get_data", __func__); return (0); } - memcpy(&stats, imsg->data, sizeof(stats)); p->stats.prefix_cnt = stats.prefix_cnt; p->stats.prefix_out_cnt = stats.prefix_out_cnt; p->stats.prefix_rcvd_update = stats.prefix_rcvd_update; @@ -580,21 +566,19 @@ control_imsg_relay(struct imsg *imsg, struct peer *p) p->stats.pending_update = stats.pending_update; p->stats.pending_withdraw = stats.pending_withdraw; - return (imsg_compose(&c->ibuf, imsg->hdr.type, 0, - imsg->hdr.pid, -1, p, sizeof(*p))); + return imsg_compose(&c->ibuf, type, 0, pid, -1, p, sizeof(*p)); } /* if command finished no need to send exit message */ - if (imsg->hdr.type == IMSG_CTL_END || imsg->hdr.type == IMSG_CTL_RESULT) + if (type == IMSG_CTL_END || type == IMSG_CTL_RESULT) c->terminate = 0; if (!c->throttled && c->ibuf.w.queued > CTL_MSG_HIGH_MARK) { - if (imsg_ctl_rde(IMSG_XOFF, 0, imsg->hdr.pid, NULL, 0) != -1) + if (imsg_ctl_rde_msg(IMSG_XOFF, 0, pid) != -1) c->throttled = 1; } - return (imsg_compose(&c->ibuf, imsg->hdr.type, 0, imsg->hdr.pid, -1, - imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE)); + return (imsg_forward(&c->ibuf, imsg)); } void diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c index 57dc8aeb0..5f39b696c 100644 --- a/usr.sbin/bgpd/printconf.c +++ b/usr.sbin/bgpd/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.168 2023/08/16 08:26:35 claudio Exp $ */ +/* $OpenBSD: printconf.c,v 1.169 2024/01/10 13:31:09 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -687,22 +687,13 @@ void print_roa(struct roa_tree *r) { struct roa *roa; - struct bgpd_addr addr; if (RB_EMPTY(r)) return; printf("roa-set {"); RB_FOREACH(roa, roa_tree, r) { - printf("\n\t"); - addr.aid = roa->aid; - addr.v6 = roa->prefix.inet6; - printf("%s/%u", log_addr(&addr), roa->prefixlen); - if (roa->prefixlen != roa->maxlen) - printf(" maxlen %u", roa->maxlen); - printf(" source-as %u", roa->asnum); - if (roa->expires != 0) - printf(" expires %lld", (long long)roa->expires); + printf("\n\t%s", log_roa(roa)); } printf("\n}\n\n"); } @@ -711,21 +702,13 @@ void print_aspa(struct aspa_tree *a) { struct aspa_set *aspa; - uint32_t i; if (RB_EMPTY(a)) return; printf("aspa-set {"); RB_FOREACH(aspa, aspa_tree, a) { - printf("\n\t"); - printf("customer-as %s", log_as(aspa->as)); - if (aspa->expires != 0) - printf(" expires %lld", (long long)aspa->expires); - printf(" provider-as { "); - for (i = 0; i < aspa->num; i++) - printf("%s ", log_as(aspa->tas[i])); - printf("}"); + printf("\n\t%s", log_aspa(aspa)); } printf("\n}\n\n"); } diff --git a/usr.sbin/bgpd/rtr_proto.c b/usr.sbin/bgpd/rtr_proto.c index 5b65b167d..a3e5d9654 100644 --- a/usr.sbin/bgpd/rtr_proto.c +++ b/usr.sbin/bgpd/rtr_proto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtr_proto.c,v 1.27 2024/01/09 15:13:49 claudio Exp $ */ +/* $OpenBSD: rtr_proto.c,v 1.28 2024/01/10 16:08:36 claudio Exp $ */ /* * Copyright (c) 2020 Claudio Jeker @@ -246,7 +246,7 @@ log_rtr_type(enum rtr_pdu_type type) case ERROR_REPORT: return "error report"; case ASPA: - return "aspa pdu"; + return "aspa"; default: snprintf(buf, sizeof(buf), "unknown %u", type); return buf; @@ -296,23 +296,33 @@ rtr_newmsg(struct rtr_session *rs, enum rtr_pdu_type type, uint32_t len, return NULL; } +static void rtr_send_error(struct rtr_session *, struct ibuf *, enum rtr_error, + const char *, ...) __attribute__((__format__ (printf, 4, 5))); + /* * Try to send an error PDU to cache, put connection into error * state. */ static void -rtr_send_error(struct rtr_session *rs, enum rtr_error err, char *msg, - struct ibuf *pdu) +rtr_send_error(struct rtr_session *rs, struct ibuf *pdu, enum rtr_error err, + const char *fmt, ...) { struct ibuf *buf; + va_list ap; size_t len = 0, mlen = 0; rs->last_sent_error = err; - if (msg != NULL) { - mlen = strlen(msg); - strlcpy(rs->last_sent_msg, msg, sizeof(rs->last_sent_msg)); - } else - memset(rs->last_sent_msg, 0, sizeof(rs->last_sent_msg)); + memset(rs->last_sent_msg, 0, sizeof(rs->last_sent_msg)); + if (fmt != NULL) { + va_start(ap, fmt); + vsnprintf(rs->last_sent_msg, sizeof(rs->last_sent_msg), + fmt, ap); + mlen = strlen(rs->last_sent_msg); + va_end(ap); + } + + log_warnx("rtr %s: sending error: %s%s%s", log_rtr(rs), + log_rtr_error(err), mlen > 0 ? ": " : "", rs->last_sent_msg); if (pdu != NULL) { ibuf_rewind(pdu); @@ -331,13 +341,10 @@ rtr_send_error(struct rtr_session *rs, enum rtr_error err, char *msg, } if (ibuf_add_n32(buf, mlen) == -1) goto fail; - if (ibuf_add(buf, msg, mlen) == -1) + if (ibuf_add(buf, rs->last_sent_msg, mlen) == -1) goto fail; ibuf_close(&rs->w, buf); - log_warnx("rtr %s: sending error: %s%s%s", log_rtr(rs), - log_rtr_error(err), msg ? ": " : "", msg ? msg : ""); - rtr_fsm(rs, RTR_EVNT_SEND_ERROR); return; @@ -352,12 +359,15 @@ rtr_send_reset_query(struct rtr_session *rs) struct ibuf *buf; buf = rtr_newmsg(rs, RESET_QUERY, 0, 0); - if (buf == NULL) { - log_warn("rtr %s: send reset query", log_rtr(rs)); - rtr_send_error(rs, INTERNAL_ERROR, "out of memory", NULL); - return; - } + if (buf == NULL) + goto fail; ibuf_close(&rs->w, buf); + return; + + fail: + rtr_send_error(rs, NULL, INTERNAL_ERROR, + "send %s: %s", log_rtr_type(RESET_QUERY), strerror(errno)); + ibuf_free(buf); } static void @@ -374,9 +384,9 @@ rtr_send_serial_query(struct rtr_session *rs) return; fail: - log_warn("rtr %s: send serial query", log_rtr(rs)); + rtr_send_error(rs, NULL, INTERNAL_ERROR, + "send %s: %s", log_rtr_type(SERIAL_QUERY), strerror(errno)); ibuf_free(buf); - rtr_send_error(rs, INTERNAL_ERROR, "out of memory", NULL); } /* @@ -388,10 +398,9 @@ rtr_check_session_id(struct rtr_session *rs, uint16_t session_id, struct rtr_header *rh, struct ibuf *pdu) { if (session_id != ntohs(rh->session_id)) { - log_warnx("rtr %s: received %s: bad session_id: %d != %d", - log_rtr(rs), log_rtr_type(rh->type), ntohs(rh->session_id), - session_id); - rtr_send_error(rs, CORRUPT_DATA, "bad session_id", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, + "%s: bad session_id %d (expected %d)", + log_rtr_type(rh->type), ntohs(rh->session_id), session_id); return -1; } return 0; @@ -416,9 +425,8 @@ rtr_parse_header(struct rtr_session *rs, struct ibuf *hdr, len = ntohl(rh.length); if (len > RTR_MAX_LEN) { - log_warnx("rtr %s: received %s: pdu too big: %zu byte", - log_rtr(rs), log_rtr_type(rh.type), len); - rtr_send_error(rs, CORRUPT_DATA, "pdu too big", hdr); + rtr_send_error(rs, hdr, CORRUPT_DATA, "%s: too big: %zu bytes", + log_rtr_type(rh.type), len); return -1; } @@ -435,9 +443,8 @@ rtr_parse_header(struct rtr_session *rs, struct ibuf *hdr, /* ignore SERIAL_NOTIFY */ break; default: - log_warnx("rtr %s: received %s: out of context", - log_rtr(rs), log_rtr_type(rh.type)); - rtr_send_error(rs, CORRUPT_DATA, "out of context", hdr); + rtr_send_error(rs, hdr, CORRUPT_DATA, + "%s: out of context", log_rtr_type(rh.type)); return -1; } } else if (rh.version != rs->version && rh.type != ERROR_REPORT) { @@ -491,9 +498,8 @@ rtr_parse_header(struct rtr_session *rs, struct ibuf *hdr, goto badlen; break; default: - log_warnx("rtr %s: received unsupported pdu: type %s", - log_rtr(rs), log_rtr_type(rh.type)); - rtr_send_error(rs, UNSUPP_PDU_TYPE, NULL, hdr); + rtr_send_error(rs, hdr, UNSUPP_PDU_TYPE, "type %s", + log_rtr_type(rh.type)); return -1; } @@ -503,15 +509,13 @@ rtr_parse_header(struct rtr_session *rs, struct ibuf *hdr, return 0; badlen: - log_warnx("rtr %s: received %s: bad pdu length: %zu bytes", - log_rtr(rs), log_rtr_type(rh.type), len); - rtr_send_error(rs, CORRUPT_DATA, "bad length", hdr); + rtr_send_error(rs, hdr, CORRUPT_DATA, "%s: bad length: %zu bytes", + log_rtr_type(rh.type), len); return -1; badversion: - log_warnx("rtr %s: received %s message: unexpected version %d", - log_rtr(rs), log_rtr_type(rh.type), rh.version); - rtr_send_error(rs, UNEXP_PROTOCOL_VERS, NULL, hdr); + rtr_send_error(rs, hdr, UNEXP_PROTOCOL_VERS, "%s: version %d", + log_rtr_type(rh.type), rh.version); return -1; } @@ -524,12 +528,8 @@ rtr_parse_notify(struct rtr_session *rs, struct ibuf *pdu) if (rs->state == RTR_STATE_NEGOTIATION) return 0; - if (ibuf_get(pdu, ¬ify, sizeof(notify)) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(SERIAL_NOTIFY)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_get(pdu, ¬ify, sizeof(notify)) == -1) + goto badlen; if (rtr_check_session_id(rs, rs->session_id, ¬ify.hdr, pdu) == -1) return -1; @@ -543,6 +543,11 @@ rtr_parse_notify(struct rtr_session *rs, struct ibuf *pdu) rtr_fsm(rs, RTR_EVNT_SERIAL_NOTIFY); return 0; + + badlen: + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length", + log_rtr_type(SERIAL_NOTIFY)); + return -1; } static int @@ -550,12 +555,8 @@ rtr_parse_cache_response(struct rtr_session *rs, struct ibuf *pdu) { struct rtr_response resp; - if (ibuf_get(pdu, &resp, sizeof(resp)) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(CACHE_RESPONSE)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_get(pdu, &resp, sizeof(resp)) == -1) + goto badlen; /* set session_id if not yet happened */ if (rs->session_id == -1) @@ -565,14 +566,18 @@ rtr_parse_cache_response(struct rtr_session *rs, struct ibuf *pdu) return -1; if (rs->state != RTR_STATE_ESTABLISHED) { - log_warnx("rtr %s: received %s: out of context", - log_rtr(rs), log_rtr_type(CACHE_RESPONSE)); - rtr_send_error(rs, CORRUPT_DATA, "out of context", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context", + log_rtr_type(CACHE_RESPONSE)); return -1; } rtr_fsm(rs, RTR_EVNT_CACHE_RESPONSE); return 0; + + badlen: + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length", + log_rtr_type(CACHE_RESPONSE)); + return -1; } static int @@ -581,35 +586,27 @@ rtr_parse_ipv4_prefix(struct rtr_session *rs, struct ibuf *pdu) struct rtr_ipv4 ip4; struct roa *roa; - if (ibuf_get(pdu, &ip4, sizeof(ip4)) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(IPV4_PREFIX)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_get(pdu, &ip4, sizeof(ip4)) == -1) + goto badlen; if (rtr_check_session_id(rs, 0, &ip4.hdr, pdu) == -1) return -1; if (rs->state != RTR_STATE_EXCHANGE) { - log_warnx("rtr %s: received %s: out of context", - log_rtr(rs), log_rtr_type(IPV4_PREFIX)); - rtr_send_error(rs, CORRUPT_DATA, "out of context", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context", + log_rtr_type(IPV4_PREFIX)); return -1; } if (ip4.prefixlen > 32 || ip4.maxlen > 32 || ip4.prefixlen > ip4.maxlen) { - log_warnx("rtr: %s: received %s: bad prefixlen / maxlen", - log_rtr(rs), log_rtr_type(IPV4_PREFIX)); - rtr_send_error(rs, CORRUPT_DATA, "bad prefixlen / maxlen", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, + "%s: bad prefixlen / maxlen", log_rtr_type(IPV4_PREFIX)); return -1; } if ((roa = calloc(1, sizeof(*roa))) == NULL) { - log_warn("rtr %s: received %s", - log_rtr(rs), log_rtr_type(IPV4_PREFIX)); - rtr_send_error(rs, INTERNAL_ERROR, "out of memory", NULL); + rtr_send_error(rs, NULL, INTERNAL_ERROR, "out of memory"); return -1; } roa->aid = AID_INET; @@ -620,9 +617,8 @@ rtr_parse_ipv4_prefix(struct rtr_session *rs, struct ibuf *pdu) if (ip4.flags & FLAG_ANNOUNCE) { if (RB_INSERT(roa_tree, &rs->roa_set, roa) != NULL) { - log_warnx("rtr %s: received %s: duplicate announcement", - log_rtr(rs), log_rtr_type(IPV4_PREFIX)); - rtr_send_error(rs, DUP_REC_RECV, NULL, pdu); + rtr_send_error(rs, pdu, DUP_REC_RECV, "%s %s", + log_rtr_type(IPV4_PREFIX), log_roa(roa)); free(roa); return -1; } @@ -631,9 +627,8 @@ rtr_parse_ipv4_prefix(struct rtr_session *rs, struct ibuf *pdu) r = RB_FIND(roa_tree, &rs->roa_set, roa); if (r == NULL) { - log_warnx("rtr %s: received %s: unknown withdrawal", - log_rtr(rs), log_rtr_type(IPV4_PREFIX)); - rtr_send_error(rs, UNK_REC_WDRAWL, NULL, pdu); + rtr_send_error(rs, pdu, UNK_REC_WDRAWL, "%s %s", + log_rtr_type(IPV4_PREFIX), log_roa(roa)); free(roa); return -1; } @@ -643,6 +638,11 @@ rtr_parse_ipv4_prefix(struct rtr_session *rs, struct ibuf *pdu) } return 0; + + badlen: + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length", + log_rtr_type(IPV4_PREFIX)); + return -1; } static int @@ -651,35 +651,27 @@ rtr_parse_ipv6_prefix(struct rtr_session *rs, struct ibuf *pdu) struct rtr_ipv6 ip6; struct roa *roa; - if (ibuf_get(pdu, &ip6, sizeof(ip6)) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(IPV6_PREFIX)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_get(pdu, &ip6, sizeof(ip6)) == -1) + goto badlen; if (rtr_check_session_id(rs, 0, &ip6.hdr, pdu) == -1) return -1; if (rs->state != RTR_STATE_EXCHANGE) { - log_warnx("rtr %s: received %s: out of context", - log_rtr(rs), log_rtr_type(IPV6_PREFIX)); - rtr_send_error(rs, CORRUPT_DATA, "out of context", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context", + log_rtr_type(IPV6_PREFIX)); return -1; } if (ip6.prefixlen > 128 || ip6.maxlen > 128 || ip6.prefixlen > ip6.maxlen) { - log_warnx("rtr: %s: received %s: bad prefixlen / maxlen", - log_rtr(rs), log_rtr_type(IPV6_PREFIX)); - rtr_send_error(rs, CORRUPT_DATA, "bad prefixlen / maxlen", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, + "%s: bad prefixlen / maxlen", log_rtr_type(IPV6_PREFIX)); return -1; } if ((roa = calloc(1, sizeof(*roa))) == NULL) { - log_warn("rtr %s: received %s", - log_rtr(rs), log_rtr_type(IPV6_PREFIX)); - rtr_send_error(rs, INTERNAL_ERROR, "out of memory", NULL); + rtr_send_error(rs, NULL, INTERNAL_ERROR, "out of memory"); return -1; } roa->aid = AID_INET6; @@ -690,9 +682,8 @@ rtr_parse_ipv6_prefix(struct rtr_session *rs, struct ibuf *pdu) if (ip6.flags & FLAG_ANNOUNCE) { if (RB_INSERT(roa_tree, &rs->roa_set, roa) != NULL) { - log_warnx("rtr %s: received %s: duplicate announcement", - log_rtr(rs), log_rtr_type(IPV6_PREFIX)); - rtr_send_error(rs, DUP_REC_RECV, NULL, pdu); + rtr_send_error(rs, pdu, DUP_REC_RECV, "%s %s", + log_rtr_type(IPV6_PREFIX), log_roa(roa)); free(roa); return -1; } @@ -701,9 +692,8 @@ rtr_parse_ipv6_prefix(struct rtr_session *rs, struct ibuf *pdu) r = RB_FIND(roa_tree, &rs->roa_set, roa); if (r == NULL) { - log_warnx("rtr %s: received %s: unknown withdrawal", - log_rtr(rs), log_rtr_type(IPV6_PREFIX)); - rtr_send_error(rs, UNK_REC_WDRAWL, NULL, pdu); + rtr_send_error(rs, pdu, UNK_REC_WDRAWL, "%s %s", + log_rtr_type(IPV6_PREFIX), log_roa(roa)); free(roa); return -1; } @@ -712,6 +702,11 @@ rtr_parse_ipv6_prefix(struct rtr_session *rs, struct ibuf *pdu) free(roa); } return 0; + + badlen: + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length", + log_rtr_type(IPV6_PREFIX)); + return -1; } static int @@ -722,24 +717,16 @@ rtr_parse_aspa(struct rtr_session *rs, struct ibuf *pdu) struct aspa_set *aspa, *a; uint16_t cnt, i; - if (ibuf_get(pdu, &rtr_aspa, sizeof(rtr_aspa)) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(ASPA)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_get(pdu, &rtr_aspa, sizeof(rtr_aspa)) == -1) + goto badlen; + cnt = ntohs(rtr_aspa.cnt); - if (ibuf_size(pdu) != cnt * sizeof(uint32_t)) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(ASPA)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_size(pdu) != cnt * sizeof(uint32_t)) + goto badlen; if (rs->state != RTR_STATE_EXCHANGE) { - log_warnx("rtr %s: received %s: out of context", - log_rtr(rs), log_rtr_type(ASPA)); - rtr_send_error(rs, CORRUPT_DATA, "out of context", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context", + log_rtr_type(ASPA)); return -1; } @@ -751,9 +738,7 @@ rtr_parse_aspa(struct rtr_session *rs, struct ibuf *pdu) /* create aspa_set entry from the rtr aspa pdu */ if ((aspa = calloc(1, sizeof(*aspa))) == NULL) { - log_warn("rtr %s: received %s", - log_rtr(rs), log_rtr_type(ASPA)); - rtr_send_error(rs, INTERNAL_ERROR, "out of memory", NULL); + rtr_send_error(rs, NULL, INTERNAL_ERROR, "out of memory"); return -1; } aspa->as = ntohl(rtr_aspa.cas); @@ -761,20 +746,13 @@ rtr_parse_aspa(struct rtr_session *rs, struct ibuf *pdu) if (cnt > 0) { if ((aspa->tas = calloc(cnt, sizeof(uint32_t))) == NULL) { free_aspa(aspa); - log_warn("rtr %s: received %s", - log_rtr(rs), log_rtr_type(ASPA)); - rtr_send_error(rs, INTERNAL_ERROR, "out of memory", - NULL); + rtr_send_error(rs, NULL, INTERNAL_ERROR, + "out of memory"); return -1; } for (i = 0; i < cnt; i++) { - if (ibuf_get_n32(pdu, &aspa->tas[i]) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(ASPA)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", - pdu); - return -1; - } + if (ibuf_get_n32(pdu, &aspa->tas[i]) == -1) + goto badlen; } } @@ -785,10 +763,8 @@ rtr_parse_aspa(struct rtr_session *rs, struct ibuf *pdu) free_aspa(a); if (RB_INSERT(aspa_tree, aspatree, aspa) != NULL) { - log_warnx("rtr %s: received %s: corrupt tree", - log_rtr(rs), log_rtr_type(ASPA)); - rtr_send_error(rs, INTERNAL_ERROR, - "corrupt aspa tree", NULL); + rtr_send_error(rs, NULL, INTERNAL_ERROR, + "corrupt aspa tree"); free_aspa(aspa); return -1; } @@ -796,9 +772,8 @@ rtr_parse_aspa(struct rtr_session *rs, struct ibuf *pdu) } else { a = RB_FIND(aspa_tree, aspatree, aspa); if (a == NULL) { - log_warnx("rtr %s: received %s: unknown withdrawal", - log_rtr(rs), log_rtr_type(ASPA)); - rtr_send_error(rs, UNK_REC_WDRAWL, NULL, pdu); + rtr_send_error(rs, pdu, UNK_REC_WDRAWL, "%s %s", + log_rtr_type(ASPA), log_aspa(aspa)); free_aspa(aspa); return -1; } @@ -808,6 +783,11 @@ rtr_parse_aspa(struct rtr_session *rs, struct ibuf *pdu) } return 0; + + badlen: + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length", + log_rtr_type(ASPA)); + return -1; } static int @@ -815,20 +795,15 @@ rtr_parse_end_of_data_v0(struct rtr_session *rs, struct ibuf *pdu) { struct rtr_endofdata_v0 eod; - if (ibuf_get(pdu, &eod, sizeof(eod)) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(END_OF_DATA)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_get(pdu, &eod, sizeof(eod)) == -1) + goto badlen; if (rtr_check_session_id(rs, rs->session_id, &eod.hdr, pdu) == -1) return -1; if (rs->state != RTR_STATE_EXCHANGE) { - log_warnx("rtr %s: received %s: out of context", - log_rtr(rs), log_rtr_type(END_OF_DATA)); - rtr_send_error(rs, CORRUPT_DATA, "out of context", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context", + log_rtr_type(END_OF_DATA)); return -1; } @@ -836,6 +811,11 @@ rtr_parse_end_of_data_v0(struct rtr_session *rs, struct ibuf *pdu) rtr_fsm(rs, RTR_EVNT_END_OF_DATA); return 0; + + badlen: + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length", + log_rtr_type(END_OF_DATA)); + return -1; } static int @@ -848,20 +828,15 @@ rtr_parse_end_of_data(struct rtr_session *rs, struct ibuf *pdu) if (rs->version == 0) return rtr_parse_end_of_data_v0(rs, pdu); - if (ibuf_get(pdu, &eod, sizeof(eod)) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(END_OF_DATA)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_get(pdu, &eod, sizeof(eod)) == -1) + goto badlen; if (rtr_check_session_id(rs, rs->session_id, &eod.hdr, pdu) == -1) return -1; if (rs->state != RTR_STATE_EXCHANGE) { - log_warnx("rtr %s: received %s: out of context", - log_rtr(rs), log_rtr_type(END_OF_DATA)); - rtr_send_error(rs, CORRUPT_DATA, "out of context", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context", + log_rtr_type(END_OF_DATA)); return -1; } @@ -886,9 +861,13 @@ rtr_parse_end_of_data(struct rtr_session *rs, struct ibuf *pdu) return 0; bad: - log_warnx("rtr %s: received %s: bad timeout values", - log_rtr(rs), log_rtr_type(END_OF_DATA)); - rtr_send_error(rs, CORRUPT_DATA, "bad timeout values", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad timeout values", + log_rtr_type(END_OF_DATA)); + return -1; + +badlen: + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length", + log_rtr_type(END_OF_DATA)); return -1; } @@ -897,25 +876,25 @@ rtr_parse_cache_reset(struct rtr_session *rs, struct ibuf *pdu) { struct rtr_reset reset; - if (ibuf_get(pdu, &reset, sizeof(reset)) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(CACHE_RESET)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_get(pdu, &reset, sizeof(reset)) == -1) + goto badlen; if (rtr_check_session_id(rs, 0, &reset.hdr, pdu) == -1) return -1; if (rs->state != RTR_STATE_ESTABLISHED) { - log_warnx("rtr %s: received %s: out of context", - log_rtr(rs), log_rtr_type(CACHE_RESET)); - rtr_send_error(rs, CORRUPT_DATA, "out of context", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context", + log_rtr_type(CACHE_RESET)); return -1; } rtr_fsm(rs, RTR_EVNT_CACHE_RESET); return 0; + + badlen: + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length", + log_rtr_type(CACHE_RESET)); + return -1; } static char * @@ -1062,9 +1041,9 @@ rtr_process_msg(struct rtr_session *rs) return; break; default: - log_warnx("rtr %s: received %s: unsupported pdu type", - log_rtr(rs), log_rtr_type(msgtype)); - rtr_send_error(rs, UNSUPP_PDU_TYPE, NULL, &msg); + /* unreachable, checked in rtr_parse_header() */ + rtr_send_error(rs, &msg, UNSUPP_PDU_TYPE, "type %s", + log_rtr_type(msgtype)); return; } } @@ -1093,10 +1072,8 @@ rtr_fsm(struct rtr_session *rs, enum rtr_event event) * highest version number. */ rs->version = RTR_MAX_VERSION; - log_warnx("rtr %s: version negotiation failed", - log_rtr(rs)); - rtr_send_error(rs, UNSUPP_PROTOCOL_VERS, - NULL, NULL); + rtr_send_error(rs, NULL, UNSUPP_PROTOCOL_VERS, + "negotiation failed"); return; } diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c index c3029ac7f..8e77c4f02 100644 --- a/usr.sbin/bgpd/session.c +++ b/usr.sbin/bgpd/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.456 2023/12/14 13:52:38 claudio Exp $ */ +/* $OpenBSD: session.c,v 1.457 2024/01/10 11:08:04 claudio Exp $ */ /* * Copyright (c) 2003, 2004, 2005 Henning Brauer @@ -3576,14 +3576,25 @@ session_up(struct peer *p) } int -imsg_ctl_parent(int type, uint32_t peerid, pid_t pid, void *data, - uint16_t datalen) +imsg_ctl_parent(struct imsg *imsg) { - return imsg_compose(ibuf_main, type, peerid, pid, -1, data, datalen); + return imsg_forward(ibuf_main, imsg); } int -imsg_ctl_rde(int type, uint32_t peerid, pid_t pid, void *data, uint16_t datalen) +imsg_ctl_rde(struct imsg *imsg) +{ + if (ibuf_rde_ctl == NULL) + return (0); + /* + * Use control socket to talk to RDE to bypass the queue of the + * regular imsg socket. + */ + return imsg_forward(ibuf_rde_ctl, imsg); +} + +int +imsg_ctl_rde_msg(int type, uint32_t peerid, pid_t pid) { if (ibuf_rde_ctl == NULL) return (0); @@ -3592,7 +3603,7 @@ imsg_ctl_rde(int type, uint32_t peerid, pid_t pid, void *data, uint16_t datalen) * Use control socket to talk to RDE to bypass the queue of the * regular imsg socket. */ - return imsg_compose(ibuf_rde_ctl, type, peerid, pid, -1, data, datalen); + return imsg_compose(ibuf_rde_ctl, type, peerid, pid, -1, NULL, 0); } int diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h index b5aa040ce..dfe90943b 100644 --- a/usr.sbin/bgpd/session.h +++ b/usr.sbin/bgpd/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.164 2023/10/19 07:02:46 claudio Exp $ */ +/* $OpenBSD: session.h,v 1.165 2024/01/10 11:08:04 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -339,8 +339,9 @@ struct peer *getpeerbydesc(struct bgpd_config *, const char *); struct peer *getpeerbyip(struct bgpd_config *, struct sockaddr *); struct peer *getpeerbyid(struct bgpd_config *, uint32_t); int peer_matched(struct peer *, struct ctl_neighbor *); -int imsg_ctl_parent(int, uint32_t, pid_t, void *, uint16_t); -int imsg_ctl_rde(int, uint32_t, pid_t, void *, uint16_t); +int imsg_ctl_parent(struct imsg *); +int imsg_ctl_rde(struct imsg *); +int imsg_ctl_rde_msg(int, uint32_t, pid_t); void session_stop(struct peer *, uint8_t); /* timer.c */ diff --git a/usr.sbin/bgpd/util.c b/usr.sbin/bgpd/util.c index a7ac90a3b..b28ff4e9a 100644 --- a/usr.sbin/bgpd/util.c +++ b/usr.sbin/bgpd/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.77 2023/04/17 08:02:21 claudio Exp $ */ +/* $OpenBSD: util.c,v 1.78 2024/01/10 13:31:09 claudio Exp $ */ /* * Copyright (c) 2006 Claudio Jeker @@ -165,6 +165,76 @@ log_reason(const char *communication) { return buf; } +static const char * +log_expires(time_t expires) +{ + static char buf[32]; + + buf[0] = '\0'; + if (expires != 0) + snprintf(buf, sizeof(buf), " expires %lld", (long long)expires); + return buf; +} + +const char * +log_roa(struct roa *roa) +{ + static char buf[256]; + struct bgpd_addr addr = { .aid = roa->aid, .v6 = roa->prefix.inet6 }; + char maxbuf[32]; + + maxbuf[0] = '\0'; + if (roa->prefixlen != roa->maxlen) + snprintf(maxbuf, sizeof(maxbuf), " maxlen %u", roa->maxlen); + snprintf(buf, sizeof(buf), "%s/%u%s source-as %u%s", log_addr(&addr), + roa->prefixlen, maxbuf, roa->asnum, log_expires(roa->expires)); + return buf; +} + +const char * +log_aspa(struct aspa_set *aspa) +{ + static char errbuf[256]; + static char *buf; + static size_t len; + char asbuf[16]; + size_t needed; + uint32_t i; + + /* include enough space for header and trailer */ + if ((uint64_t)aspa->num > (SIZE_MAX / sizeof(asbuf) - 72)) + goto fail; + needed = aspa->num * sizeof(asbuf) + 72; + if (needed > len) { + char *nbuf; + + if ((nbuf = realloc(buf, needed)) == NULL) + goto fail; + len = needed; + buf = nbuf; + } + + snprintf(buf, len, "customer-as %s%s provider-as { ", + log_as(aspa->as), log_expires(aspa->expires)); + + for (i = 0; i < aspa->num; i++) { + snprintf(asbuf, sizeof(asbuf), "%s ", log_as(aspa->tas[i])); + if (strlcat(buf, asbuf, len) >= len) + goto fail; + } + if (strlcat(buf, "}", len) >= len) + goto fail; + return buf; + + fail: + free(buf); + buf = NULL; + len = 0; + snprintf(errbuf, sizeof(errbuf), "customer-as %s%s provider-as { ... }", + log_as(aspa->as), log_expires(aspa->expires)); + return errbuf; +} + const char * log_rtr_error(enum rtr_error err) {