From 3a8c7ba1ec02bd2560ebcf4b961a13d2b3e611bd Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Tue, 15 Sep 2015 19:14:06 -0700 Subject: [PATCH] BGP: Display the right reason code for session reset Ticket: CM-7439 Reviewed By: Donald Sharp Testing Done: If a session was reset due to a NOTIFICATION the "show ip bgp neighbor" output would not display details on what the notification actually was. This patch changes that. Example: superm-redxp-05# show ip bgp neighbors 20.1.2.2 BGP neighbor is 20.1.2.2, remote AS 21, local AS 10, external link [snip] Last reset 01:05:07, due to NOTIFICATION sent (OPEN Message Error/Bad Peer AS) --- .gitignore | 1 + bgpd/bgp_debug.c | 68 ++++++++++++++++++++++++++--------------------- bgpd/bgp_debug.h | 2 ++ bgpd/bgp_fsm.c | 7 ----- bgpd/bgp_packet.c | 10 ++++--- bgpd/bgp_vty.c | 22 ++++++++++++--- 6 files changed, 67 insertions(+), 43 deletions(-) diff --git a/.gitignore b/.gitignore index bcd60a6e82..5650dff5ed 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,4 @@ debian/quagga.prerm.debhelper debian/quagga.substvars debian/quagga/ debian/tmp/ +*.swp diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index fee86d0fcf..48b4ba30d9 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -451,52 +451,60 @@ bgp_dump_attr (struct peer *peer, struct attr *attr, char *buf, size_t size) return 0; } -/* dump notify packet */ -void -bgp_notify_print(struct peer *peer, struct bgp_notify *bgp_notify, - const char *direct) +const char * +bgp_notify_code_str (char code) { - const char *subcode_str; - const char *code_str; + return LOOKUP_DEF (bgp_notify_msg, code, "Unrecognized Error Code"); +} - subcode_str = ""; - code_str = LOOKUP_DEF (bgp_notify_msg, bgp_notify->code, - "Unrecognized Error Code"); +const char * +bgp_notify_subcode_str (char code, char subcode) +{ - switch (bgp_notify->code) + switch (code) { case BGP_NOTIFY_HEADER_ERR: - subcode_str = LOOKUP_DEF (bgp_notify_head_msg, bgp_notify->subcode, - "Unrecognized Error Subcode"); - break; + return LOOKUP_DEF (bgp_notify_head_msg, subcode, + "Unrecognized Error Subcode"); case BGP_NOTIFY_OPEN_ERR: - subcode_str = LOOKUP_DEF (bgp_notify_open_msg, bgp_notify->subcode, - "Unrecognized Error Subcode"); - break; + return LOOKUP_DEF (bgp_notify_open_msg, subcode, + "Unrecognized Error Subcode"); case BGP_NOTIFY_UPDATE_ERR: - subcode_str = LOOKUP_DEF (bgp_notify_update_msg, bgp_notify->subcode, - "Unrecognized Error Subcode"); - break; + return LOOKUP_DEF (bgp_notify_update_msg, subcode, + "Unrecognized Error Subcode"); case BGP_NOTIFY_HOLD_ERR: break; case BGP_NOTIFY_FSM_ERR: break; case BGP_NOTIFY_CEASE: - subcode_str = LOOKUP_DEF (bgp_notify_cease_msg, bgp_notify->subcode, - "Unrecognized Error Subcode"); - break; + return LOOKUP_DEF (bgp_notify_cease_msg, subcode, + "Unrecognized Error Subcode"); case BGP_NOTIFY_CAPABILITY_ERR: - subcode_str = LOOKUP_DEF (bgp_notify_capability_msg, bgp_notify->subcode, - "Unrecognized Error Subcode"); - break; + return LOOKUP_DEF (bgp_notify_capability_msg, subcode, + "Unrecognized Error Subcode"); } + return ""; +} + +/* dump notify packet */ +void +bgp_notify_print(struct peer *peer, struct bgp_notify *bgp_notify, + const char *direct) +{ + const char *subcode_str; + const char *code_str; if (BGP_DEBUG (neighbor_events, NEIGHBOR_EVENTS) || bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) - zlog_info ("%%NOTIFICATION: %s neighbor %s %d/%d (%s%s) %d bytes %s", - strcmp (direct, "received") == 0 ? "received from" : "sent to", - peer->host, bgp_notify->code, bgp_notify->subcode, - code_str, subcode_str, bgp_notify->length, - bgp_notify->data ? bgp_notify->data : ""); + { + code_str = bgp_notify_code_str(bgp_notify->code); + subcode_str = bgp_notify_subcode_str(bgp_notify->code, bgp_notify->subcode); + + zlog_info ("%%NOTIFICATION: %s neighbor %s %d/%d (%s%s) %d bytes %s", + strcmp (direct, "received") == 0 ? "received from" : "sent to", + peer->host, bgp_notify->code, bgp_notify->subcode, + code_str, subcode_str, bgp_notify->length, + bgp_notify->data ? bgp_notify->data : ""); + } } static void diff --git a/bgpd/bgp_debug.h b/bgpd/bgp_debug.h index 9b6b00b9f3..8372c7e3f5 100644 --- a/bgpd/bgp_debug.h +++ b/bgpd/bgp_debug.h @@ -134,6 +134,8 @@ extern const char *bgp_type_str[]; extern int bgp_dump_attr (struct peer *, struct attr *, char *, size_t); extern int bgp_debug_peer_updout_enabled(char *host); +extern const char *bgp_notify_code_str(char); +extern const char *bgp_notify_subcode_str(char, char); extern void bgp_notify_print (struct peer *, struct bgp_notify *, const char *); extern const struct message bgp_status_msg[]; diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index f39b172734..f85bf059d5 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -1412,7 +1412,6 @@ bgp_fsm_holdtime_expire (struct peer *peer) static int bgp_establish (struct peer *peer) { - struct bgp_notify *notify; afi_t afi; safi_t safi; int nsf_af_count = 0; @@ -1434,12 +1433,6 @@ bgp_establish (struct peer *peer) if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN)) SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN); - /* Clear last notification data. */ - notify = &peer->notify; - if (notify->data) - XFREE (MTYPE_TMP, notify->data); - memset (notify, 0, sizeof (struct bgp_notify)); - /* Clear start timer value to default. */ peer->v_start = BGP_INIT_START_TIMER; diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 8531f37d78..6aec5e6334 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -621,6 +621,9 @@ bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code, bgp_notify.subcode = sub_code; bgp_notify.data = NULL; bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE; + + peer->notify.code = bgp_notify.code; + peer->notify.subcode = bgp_notify.subcode; if (bgp_notify.length) { @@ -644,7 +647,7 @@ bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code, } /* peer reset cause */ - if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE) + if (code == BGP_NOTIFY_CEASE) { if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET) peer->last_reset = PEER_DOWN_USER_RESET; @@ -653,6 +656,8 @@ bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code, else peer->last_reset = PEER_DOWN_NOTIFY_SEND; } + else + peer->last_reset = PEER_DOWN_NOTIFY_SEND; /* Call immediately. */ BGP_WRITE_OFF (peer->t_write); @@ -1735,8 +1740,7 @@ bgp_notify_receive (struct peer *peer, bgp_size_t size) /* peer count update */ peer->notify_in++; - if (peer->status == Established) - peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED; + peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED; /* We have to check for Notify with Unsupported Optional Parameter. in that case we fallback to open without the capability option. diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 5c64268250..f1397f6561 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -9500,6 +9500,8 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js char buf1[BUFSIZ], buf[SU_ADDRSTRLEN]; char timebuf[BGP_UPTIME_LEN]; char dn_flag[2]; + const char *subcode_str; + const char *code_str; afi_t afi; safi_t safi; u_int16_t i; @@ -10387,9 +10389,23 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js } else { - vty_out (vty, " Last reset %s, due to %s%s", - peer_uptime (p->resettime, timebuf, BGP_UPTIME_LEN, 0, NULL), - peer_down_str[(int) p->last_reset], VTY_NEWLINE); + vty_out (vty, " Last reset %s, ", + peer_uptime (p->resettime, timebuf, BGP_UPTIME_LEN, 0, NULL)); + + if (p->last_reset == PEER_DOWN_NOTIFY_SEND || + p->last_reset == PEER_DOWN_NOTIFY_RECEIVED) + { + code_str = bgp_notify_code_str(p->notify.code); + subcode_str = bgp_notify_subcode_str(p->notify.code, p->notify.subcode); + vty_out (vty, "due to NOTIFICATION %s (%s%s)%s", + p->last_reset == PEER_DOWN_NOTIFY_SEND ? "sent" : "received", + code_str, subcode_str, VTY_NEWLINE); + } + else + { + vty_out (vty, "due to %s%s", + peer_down_str[(int) p->last_reset], VTY_NEWLINE); + } if (p->last_reset_cause_size) { -- 2.39.5