From eff7ddaf5345d364fff16bd60943172a70fced85 Mon Sep 17 00:00:00 2001 From: claudio Date: Fri, 22 Mar 2024 15:41:34 +0000 Subject: [PATCH] Rework the cease shutdown reason to work in both directions by looking at the ibuf payload passed to log_notification(). Because of this move ibuf_get_string() and the log_notification() call in parse_notification(). OK tb@ --- usr.sbin/bgpd/bgpd.h | 3 ++- usr.sbin/bgpd/logmsg.c | 22 ++++++++++++++-------- usr.sbin/bgpd/rtr_proto.c | 18 +----------------- usr.sbin/bgpd/session.c | 6 +++--- usr.sbin/bgpd/util.c | 18 +++++++++++++++++- 5 files changed, 37 insertions(+), 30 deletions(-) diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index 212b10ff223..869d6539ea6 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.488 2024/03/22 07:19:28 claudio Exp $ */ +/* $OpenBSD: bgpd.h,v 1.489 2024/03/22 15:41:34 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -1545,6 +1545,7 @@ int trie_equal(struct trie_head *, struct trie_head *); time_t getmonotime(void); /* util.c */ +char *ibuf_get_string(struct ibuf *, size_t); const char *log_addr(const struct bgpd_addr *); const char *log_in6addr(const struct in6_addr *); const char *log_sockaddr(struct sockaddr *, socklen_t); diff --git a/usr.sbin/bgpd/logmsg.c b/usr.sbin/bgpd/logmsg.c index 359f94e7362..91b3eb71d96 100644 --- a/usr.sbin/bgpd/logmsg.c +++ b/usr.sbin/bgpd/logmsg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: logmsg.c,v 1.12 2024/03/22 07:19:28 claudio Exp $ */ +/* $OpenBSD: logmsg.c,v 1.13 2024/03/22 15:41:34 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -189,13 +189,19 @@ log_notification(const struct peer *peer, uint8_t errcode, uint8_t subcode, if (subcode == ERR_CEASE_ADMIN_DOWN || subcode == ERR_CEASE_ADMIN_RESET) { - if (peer->stats.last_reason[0] != '\0') { - logit(LOG_ERR, "%s: %s notification: %s, %s: " - "reason \"%s\"", p, dir, - errnames[errcode], suberrname, - log_reason(peer->stats.last_reason)); - free(p); - return; + uint8_t len; + /* check if shutdown reason is included */ + if (ibuf_get_n8(&ibuf, &len) != -1 && len != 0) { + char *s; + if ((s = ibuf_get_string(&ibuf, len)) != NULL) { + logit(LOG_ERR, "%s: %s notification: " + "%s, %s: reason \"%s\"", p, dir, + errnames[errcode], suberrname, + log_reason(s)); + free(s); + free(p); + return; + } } } break; diff --git a/usr.sbin/bgpd/rtr_proto.c b/usr.sbin/bgpd/rtr_proto.c index aec9ea31053..7ceda79704b 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.33 2024/01/23 15:59:56 claudio Exp $ */ +/* $OpenBSD: rtr_proto.c,v 1.34 2024/03/22 15:41:34 claudio Exp $ */ /* * Copyright (c) 2020 Claudio Jeker @@ -915,22 +915,6 @@ rtr_parse_cache_reset(struct rtr_session *rs, struct ibuf *pdu) return -1; } -static char * -ibuf_get_string(struct ibuf *buf, size_t len) -{ - char *str; - - if (ibuf_size(buf) < len) { - errno = EBADMSG; - return (NULL); - } - str = strndup(ibuf_data(buf), len); - if (str == NULL) - return (NULL); - ibuf_skip(buf, len); - return (str); -} - /* * Parse an Error Response message. This function behaves a bit different * from other parse functions since on error the connection needs to be diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c index 0d8ac4e15ed..da3d0311c2b 100644 --- a/usr.sbin/bgpd/session.c +++ b/usr.sbin/bgpd/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.465 2024/03/22 07:19:28 claudio Exp $ */ +/* $OpenBSD: session.c,v 1.466 2024/03/22 15:41:34 claudio Exp $ */ /* * Copyright (c) 2003, 2004, 2005 Henning Brauer @@ -2505,6 +2505,8 @@ parse_notification(struct peer *peer) peer->stats.last_rcvd_errcode = errcode; peer->stats.last_rcvd_suberr = subcode; + log_notification(peer, errcode, subcode, &ibuf, "received"); + CTASSERT(sizeof(peer->stats.last_reason) > UINT8_MAX); memset(peer->stats.last_reason, 0, sizeof(peer->stats.last_reason)); if (errcode == ERR_CEASE && @@ -2519,8 +2521,6 @@ parse_notification(struct peer *peer) } } - log_notification(peer, errcode, subcode, &ibuf, "received"); - if (errcode == ERR_OPEN && subcode == ERR_OPEN_OPT) { session_capa_ann_none(peer); return (1); diff --git a/usr.sbin/bgpd/util.c b/usr.sbin/bgpd/util.c index cdbcc576d2b..44513b92945 100644 --- a/usr.sbin/bgpd/util.c +++ b/usr.sbin/bgpd/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.84 2024/03/22 07:19:28 claudio Exp $ */ +/* $OpenBSD: util.c,v 1.85 2024/03/22 15:41:34 claudio Exp $ */ /* * Copyright (c) 2006 Claudio Jeker @@ -32,6 +32,22 @@ #include "rde.h" #include "log.h" +char * +ibuf_get_string(struct ibuf *buf, size_t len) +{ + char *str; + + if (ibuf_size(buf) < len) { + errno = EBADMSG; + return (NULL); + } + str = strndup(ibuf_data(buf), len); + if (str == NULL) + return (NULL); + ibuf_skip(buf, len); + return (str); +} + const char * log_addr(const struct bgpd_addr *addr) { -- 2.20.1