Download raw body.
bgpd: fixup shutdown reason handling in notification
On Fri, Mar 22, 2024 at 11:23:34AM +0100, Claudio Jeker wrote:
> 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.
Oh. Right.
>
> 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.
ok tb one tiny nit inline
> --
> :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,
The previous line needs 4 additional spaces indentation
> + 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