diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2017-12-07 21:54:47 +0100 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2017-12-07 21:54:47 +0100 |
commit | 830ba75e6dd369c3e64d122f0537cc85211e56e6 (patch) | |
tree | 23989d7955618540ab2bad467d6e376229ad922c /proto/bgp/packets.c | |
parent | 46434a3cad99260b5a659e5df874eab4615bcb36 (diff) | |
parent | 1e8721e2aeccfbc3f533e8b8abc07582cee77e9a (diff) |
Merge commit '1e8721e2aeccfbc3f533e8b8abc07582cee77e9a' into int-new
Diffstat (limited to 'proto/bgp/packets.c')
-rw-r--r-- | proto/bgp/packets.c | 58 |
1 files changed, 46 insertions, 12 deletions
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 0e974746..038e89f9 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -2678,38 +2678,72 @@ bgp_error_dsc(uint code, uint subcode) return buff; } +/* RFC 8203 - shutdown communication message */ +static int +bgp_handle_message(struct bgp_proto *p, byte *data, uint len, byte **bp) +{ + byte *msg = data + 1; + uint msg_len = data[0]; + uint i; + + /* Handle zero length message */ + if (msg_len == 0) + return 1; + + /* Handle proper message */ + if ((msg_len > 128) && (msg_len + 1 > len)) + return 0; + + /* Some elementary cleanup */ + for (i = 0; i < msg_len; i++) + if (msg[i] < ' ') + msg[i] = ' '; + + proto_set_message(&p->p, msg, msg_len); + *bp += bsprintf(*bp, ": \"%s\"", p->p.message); + return 1; +} + void bgp_log_error(struct bgp_proto *p, u8 class, char *msg, uint code, uint subcode, byte *data, uint len) { - const byte *name; - byte *t, argbuf[36]; + byte argbuf[256], *t = argbuf; uint i; /* Don't report Cease messages generated by myself */ if (code == 6 && class == BE_BGP_TX) return; - name = bgp_error_dsc(code, subcode); - t = argbuf; + /* Reset shutdown message */ + if ((code == 6) && ((subcode == 2) || (subcode == 4))) + proto_set_message(&p->p, NULL, 0); + if (len) { - *t++ = ':'; - *t++ = ' '; - + /* Bad peer AS - we would like to print the AS */ if ((code == 2) && (subcode == 2) && ((len == 2) || (len == 4))) { - /* Bad peer AS - we would like to print the AS */ - t += bsprintf(t, "%u", (len == 2) ? get_u16(data) : get_u32(data)); + t += bsprintf(t, ": %u", (len == 2) ? get_u16(data) : get_u32(data)); goto done; } + + /* RFC 8203 - shutdown communication */ + if (((code == 6) && ((subcode == 2) || (subcode == 4)))) + if (bgp_handle_message(p, data, len, &t)) + goto done; + + *t++ = ':'; + *t++ = ' '; if (len > 16) len = 16; for (i=0; i<len; i++) t += bsprintf(t, "%02x", data[i]); } - done: + +done: *t = 0; - log(L_REMOTE "%s: %s: %s%s", p->p.name, msg, name, argbuf); + const byte *dsc = bgp_error_dsc(code, subcode); + log(L_REMOTE "%s: %s: %s%s", p->p.name, msg, dsc, argbuf); } static void @@ -2733,7 +2767,7 @@ bgp_rx_notification(struct bgp_conn *conn, byte *pkt, uint len) if (err) { bgp_update_startup_delay(p); - bgp_stop(p, 0); + bgp_stop(p, 0, NULL, 0); } } |