Download raw body.
bgpd: fixup shutdown reason handling in notification
Just after commit I realized that the previous change to
log_notification() was not quite right since the code is called both for
received and sent notifications but the reason always points at the
received one.
It is better to peak at the ibuf passed to log_notification() so both
cases work reliably. For this to work I moved the ibuf_get_string()
function from rtr_proto.c to util.c and moved the log_notification() call
back up in parse_notification() since the code there to process the reason
consumes the data from the ibuf.
Tested both with sent and received shutdown reasons.
--
:wq Claudio
Index: bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
diff -u -p -r1.488 bgpd.h
--- bgpd.h 22 Mar 2024 07:19:28 -0000 1.488
+++ bgpd.h 22 Mar 2024 09:38:12 -0000
@@ -1545,6 +1545,7 @@ int trie_equal(struct trie_head *, struc
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);
Index: logmsg.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/logmsg.c,v
diff -u -p -r1.12 logmsg.c
--- logmsg.c 22 Mar 2024 07:19:28 -0000 1.12
+++ logmsg.c 22 Mar 2024 09:41:04 -0000
@@ -189,13 +189,19 @@ log_notification(const struct peer *peer
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;
Index: rtr_proto.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rtr_proto.c,v
diff -u -p -r1.33 rtr_proto.c
--- rtr_proto.c 23 Jan 2024 15:59:56 -0000 1.33
+++ rtr_proto.c 22 Mar 2024 09:37:42 -0000
@@ -915,22 +915,6 @@ rtr_parse_cache_reset(struct rtr_session
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
Index: session.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/session.c,v
diff -u -p -r1.465 session.c
--- session.c 22 Mar 2024 07:19:28 -0000 1.465
+++ session.c 22 Mar 2024 09:40:23 -0000
@@ -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 &&
@@ -2518,8 +2520,6 @@ parse_notification(struct peer *peer)
"received truncated shutdown reason");
}
}
-
- log_notification(peer, errcode, subcode, &ibuf, "received");
if (errcode == ERR_OPEN && subcode == ERR_OPEN_OPT) {
session_capa_ann_none(peer);
Index: util.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/util.c,v
diff -u -p -r1.84 util.c
--- util.c 22 Mar 2024 07:19:28 -0000 1.84
+++ util.c 22 Mar 2024 09:37:49 -0000
@@ -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)
{
bgpd: fixup shutdown reason handling in notification