Decode BGP Shutdown Communication messages (RFC 8203)
Job Snijders
job at ntt.net
Tue Sep 12 21:12:16 CEST 2017
bump? :-)
On Fri, Jul 28, 2017 at 12:26:59PM +0200, Job Snijders wrote:
> Spin #2
>
> ---
> proto/bgp/bgp.c | 12 +++++++++
> proto/bgp/bgp.h | 2 ++
> proto/bgp/packets.c | 73 ++++++++++++++++++++++++++++++++++-------------------
> 3 files changed, 61 insertions(+), 26 deletions(-)
>
> diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
> index f706e76..2a89c00 100644
> --- a/proto/bgp/bgp.c
> +++ b/proto/bgp/bgp.c
> @@ -1487,6 +1487,15 @@ bgp_last_errmsg(struct bgp_proto *p)
> }
>
> static const char *
> +bgp_last_shutmsg(struct bgp_proto *p)
> +{
> + if (p->last_received_shutmsg)
> + return(p->last_received_shutmsg);
> + else
> + return(NULL);
> +}
> +
> +static const char *
> bgp_state_dsc(struct bgp_proto *p)
> {
> if (p->p.proto_state == PS_DOWN)
> @@ -1580,7 +1589,10 @@ bgp_show_proto_info(struct proto *P)
> {
> const char *err1 = bgp_err_classes[p->last_error_class];
> const char *err2 = bgp_last_errmsg(p);
> + const char *msg = bgp_last_shutmsg(p);
> cli_msg(-1006, " Last error: %s%s", err1, err2);
> + if (msg)
> + cli_msg(-1006, " Message: \"%s\"", msg);
> }
> }
>
> diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
> index e47a0eb..d958716 100644
> --- a/proto/bgp/bgp.h
> +++ b/proto/bgp/bgp.h
> @@ -157,6 +157,8 @@ struct bgp_proto {
> u8 last_error_class; /* Error class of last error */
> u32 last_error_code; /* Error code of last error. BGP protocol errors
> are encoded as (bgp_err_code << 16 | bgp_err_subcode) */
> + byte last_received_shutmsg[129]; /* RFC 8203 */
> +
> #ifdef IPV6
> byte *mp_reach_start, *mp_unreach_start; /* Multiprotocol BGP attribute notes */
> unsigned mp_reach_len, mp_unreach_len;
> diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
> index ab87bdc..a44f264 100644
> --- a/proto/bgp/packets.c
> +++ b/proto/bgp/packets.c
> @@ -1460,9 +1460,9 @@ static struct {
> { 5, 3, "Unexpected message in Established state" },
> { 6, 0, "Cease" }, /* Subcodes are according to [RFC4486] */
> { 6, 1, "Maximum number of prefixes reached" },
> - { 6, 2, "Administrative shutdown" },
> + { 6, 2, "Administrative shutdown" }, /* RFC 8203 can follow */
> { 6, 3, "Peer de-configured" },
> - { 6, 4, "Administrative reset" },
> + { 6, 4, "Administrative reset" }, /* RFC 8203 can follow */
> { 6, 5, "Connection rejected" },
> { 6, 6, "Other configuration change" },
> { 6, 7, "Connection collision resolution" },
> @@ -1497,35 +1497,56 @@ bgp_error_dsc(unsigned code, unsigned subcode)
> void
> bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsigned subcode, byte *data, unsigned len)
> {
> - const byte *name;
> - byte *t, argbuf[36];
> - unsigned i;
> + const byte *name;
> + byte *t, argbuf[256];
> + unsigned i;
> + unsigned shutdown_comm_length;
>
> - /* Don't report Cease messages generated by myself */
> - if (code == 6 && class == BE_BGP_TX)
> - return;
> + /* Don't report Cease messages generated by myself */
> + if (code == 6 && class == BE_BGP_TX)
> + return;
> +
> + name = bgp_error_dsc(code, subcode);
> + t = argbuf;
> + memset(p->last_received_shutmsg, 0, 128 + 1); // clear old RFC 8203 messages
>
> - name = bgp_error_dsc(code, subcode);
> - t = argbuf;
> - if (len)
> + if (len)
> {
> - *t++ = ':';
> - *t++ = ' ';
> + *t++ = ':';
> + *t++ = ' ';
>
> - if ((code == 2) && (subcode == 2) && ((len == 2) || (len == 4)))
> - {
> - /* Bad peer AS - we would like to print the AS */
> - t += bsprintf(t, "%d", (len == 2) ? get_u16(data) : get_u32(data));
> - goto done;
> - }
> - if (len > 16)
> - len = 16;
> - for (i=0; i<len; i++)
> - t += bsprintf(t, "%02x", data[i]);
> + if ((code == 2) && (subcode == 2) && ((len == 2) || (len == 4)))
> + {
> + /* Bad peer AS - we would like to print the AS */
> + t += bsprintf(t, "%d", (len == 2) ? get_u16(data) : get_u32(data));
> + goto done;
> + }
> + /* RFC 8203 */
> + if ((code == 6) && ((subcode == 2 || subcode == 4)) && (len <= 129))
> + {
> + shutdown_comm_length = data[0];
> + if ((shutdown_comm_length <= 128) && (len == shutdown_comm_length + 1))
> + {
> + t += bsprintf(t, "\"");
> + for (i=1; i<len; i++)
> + t += bsprintf(t, "%c", data[i]);
> + t += bsprintf(t, "\"");
> + memcpy(p->last_received_shutmsg, data + 1, shutdown_comm_length);
> + goto done;
> + }
> + }
> + else
> + {
> + if (len > 16)
> + len = 16;
> + for (i=0; i<len; i++)
> + t += bsprintf(t, "%02x", data[i]);
> + }
> }
> - done:
> - *t = 0;
> - log(L_REMOTE "%s: %s: %s%s", p->p.name, msg, name, argbuf);
> +
> + done:
> + *t = 0;
> + log(L_REMOTE "%s: %s: %s%s", p->p.name, msg, name, argbuf);
> }
>
> static void
More information about the Bird-users
mailing list