]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: Add a new command to only show failed peerings 4913/head
authorDinesh G Dutt <5016467+ddutt@users.noreply.github.com>
Sat, 31 Aug 2019 16:24:49 +0000 (16:24 +0000)
committerDinesh G Dutt <5016467+ddutt@users.noreply.github.com>
Mon, 2 Sep 2019 14:21:44 +0000 (14:21 +0000)
In a data center, having 32-128 peers is not uncommon. In such a situation, to find a
peer that has failed and why is several commands. This hinders both the automatability of
failure detection and the ease/speed with which the reason can be found. To simplify this
process of catching a failure and its cause quicker, this patch does the following:

1. Created a new function, bgp_show_failed_summary to display the
   failed summary output for JSON and vty
2. Created a new function to display the reset code/subcode. This is now used in the
   failed summary code and in the show neighbors code
3. Added a new variable failedPeers in all the JSON outputs, including the vanilla
   "show bgp summary" family. This lists the failed session count.
4. Display peer, dropped count, estd count, uptime and the reason for failure as the
   output of "show bgp summary failed" family of commands
5. Added three resset codes for the case where we're waiting for NHT, waiting for peer
   IPv6 addr, waiting for VRF to init.

This also counts the case where only one peer has advertised an AFI/SAFI.

The new command has the optional keyword "failed" added to the classical summary command.

The changes affect only one existing output, that of "show [ip] bgp neighbors <nbr>". As
we track the lack of NHT resolution for a peer or the lack of knowing a peer IPv6 addr,
the output of that command will show a "waiting for NHT" etc. as the last reset reason.

This patch includes update to the documentation too.

Signed-off-by: Dinesh G Dutt <5016467+ddutt@users.noreply.github.com>
bgpd/bgp_evpn_vty.c
bgpd/bgp_fsm.c
bgpd/bgp_vty.c
bgpd/bgp_vty.h
bgpd/bgpd.h
doc/user/bgp.rst

index e6d81e54c4c33e27e7c26252a94b491a394edbbe..30380f6add7610366796ee21657ef1d2c82e873e 100644 (file)
@@ -3696,7 +3696,7 @@ DEFUN(show_bgp_l2vpn_evpn_es,
  */
 DEFUN(show_bgp_l2vpn_evpn_summary,
       show_bgp_l2vpn_evpn_summary_cmd,
-      "show bgp [vrf VRFNAME] l2vpn evpn summary [json]",
+      "show bgp [vrf VRFNAME] l2vpn evpn summary [failed] [json]",
       SHOW_STR
       BGP_STR
       "bgp vrf\n"
@@ -3704,15 +3704,20 @@ DEFUN(show_bgp_l2vpn_evpn_summary,
       L2VPN_HELP_STR
       EVPN_HELP_STR
       "Summary of BGP neighbor status\n"
+      "Show only sessions not in Established state\n"
       JSON_STR)
 {
        int idx_vrf = 0;
        bool uj = use_json(argc, argv);
        char *vrf = NULL;
+       bool show_failed = false;
 
        if (argv_find(argv, argc, "vrf", &idx_vrf))
                vrf = argv[++idx_vrf]->arg;
-       return bgp_show_summary_vty(vty, vrf, AFI_L2VPN, SAFI_EVPN, uj);
+       if (argv_find(argv, argc, "failed", &idx_vrf))
+               show_failed = true;
+       return bgp_show_summary_vty(vty, vrf, AFI_L2VPN, SAFI_EVPN,
+                                   show_failed, uj);
 }
 
 /*
index c9c6fc157e63fdf6f6e353fc2b2e5e83c29c0514..4d395e3749e0fc82e63c76c5bec9228e7d561a99 100644 (file)
@@ -244,6 +244,7 @@ static struct peer *peer_xfer_conn(struct peer *from_peer)
        from_peer->last_event = last_evt;
        from_peer->last_major_event = last_maj_evt;
        peer->remote_id = from_peer->remote_id;
+       peer->last_reset = from_peer->last_reset;
 
        if (from_peer->hostname != NULL) {
                if (peer->hostname) {
@@ -551,7 +552,10 @@ const char *peer_down_str[] = {"",
                               "Intf peering v6only config change",
                               "BFD down received",
                               "Interface down",
-                              "Neighbor address lost"};
+                              "Neighbor address lost"
+                              "Waiting for NHT",
+                              "Waiting for Peer IPv6 Addr",
+                              "Waiting for VRF to be initialized"};
 
 static int bgp_graceful_restart_timer_expire(struct thread *thread)
 {
@@ -1410,6 +1414,7 @@ int bgp_start(struct peer *peer)
                        zlog_debug(
                                "%s [FSM] Unable to get neighbor's IP address, waiting...",
                                peer->host);
+               peer->last_reset = PEER_DOWN_NBR_ADDR;
                return -1;
        }
 
@@ -1455,6 +1460,7 @@ int bgp_start(struct peer *peer)
                                EC_BGP_FSM,
                                "%s [FSM] In a VRF that is not initialised yet",
                                peer->host);
+               peer->last_reset = PEER_DOWN_VRF_UNINIT;
                return -1;
        }
 
@@ -1466,7 +1472,7 @@ int bgp_start(struct peer *peer)
                        if (bgp_debug_neighbor_events(peer))
                                zlog_debug("%s [FSM] Waiting for NHT",
                                           peer->host);
-
+                       peer->last_reset = PEER_DOWN_WAITING_NHT;
                        BGP_EVENT_ADD(peer, TCP_connection_open_failed);
                        return 0;
                }
index f6aca6fbf50495b94904429c08bc58173c465bb3..9b801b3c94bbddee74a6b4253fa1f3444bab61b2 100644 (file)
@@ -7869,9 +7869,143 @@ static void bgp_show_bestpath_json(struct bgp *bgp, json_object *json)
        json_object_object_add(json, "bestPath", bestpath);
 }
 
+/* Print the error code/subcode for why the peer is down */
+static void bgp_show_peer_reset(struct vty * vty, struct peer *peer,
+                               json_object *json_peer, bool use_json)
+{
+       const char *code_str;
+       const char *subcode_str;
+
+       if (use_json) {
+               if (peer->last_reset == PEER_DOWN_NOTIFY_SEND
+                   || peer->last_reset == PEER_DOWN_NOTIFY_RECEIVED) {
+                       char errorcodesubcode_hexstr[5];
+                       char errorcodesubcode_str[256];
+
+                       code_str = bgp_notify_code_str(peer->notify.code);
+                       subcode_str = bgp_notify_subcode_str(
+                                        peer->notify.code,
+                                        peer->notify.subcode);
+
+                       sprintf(errorcodesubcode_hexstr, "%02X%02X",
+                               peer->notify.code, peer->notify.subcode);
+                       json_object_string_add(json_peer,
+                                              "lastErrorCodeSubcode",
+                                              errorcodesubcode_hexstr);
+                       snprintf(errorcodesubcode_str, 255, "%s%s",
+                                code_str, subcode_str);
+                       json_object_string_add(json_peer,
+                                              "lastNotificationReason",
+                                              errorcodesubcode_str);
+                       if (peer->last_reset == PEER_DOWN_NOTIFY_RECEIVED
+                           && peer->notify.code == BGP_NOTIFY_CEASE
+                           && (peer->notify.subcode
+                               == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
+                               || peer->notify.subcode
+                               == BGP_NOTIFY_CEASE_ADMIN_RESET)
+                           && peer->notify.length) {
+                               char msgbuf[1024];
+                               const char *msg_str;
+
+                               msg_str = bgp_notify_admin_message(
+                                            msgbuf, sizeof(msgbuf),
+                                            (uint8_t *)peer->notify.data,
+                                            peer->notify.length);
+                               if (msg_str)
+                                       json_object_string_add(
+                                          json_peer,
+                                          "lastShutdownDescription",
+                                          msg_str);
+                       }
+
+               } 
+               json_object_string_add(json_peer, "lastResetDueTo",
+                                      peer_down_str[(int)peer->last_reset]);
+       } else {
+               if (peer->last_reset == PEER_DOWN_NOTIFY_SEND
+                   || peer->last_reset == PEER_DOWN_NOTIFY_RECEIVED) {
+                       code_str = bgp_notify_code_str(peer->notify.code);
+                       subcode_str =
+                               bgp_notify_subcode_str(peer->notify.code,
+                                                      peer->notify.subcode);
+                       vty_out(vty, "  Notification %s (%s%s)\n",
+                               peer->last_reset == PEER_DOWN_NOTIFY_SEND
+                               ? "sent"
+                               : "received",
+                               code_str, subcode_str);
+               } else {
+                       vty_out(vty, "  %s\n",
+                               peer_down_str[(int)peer->last_reset]);
+               }
+       }
+}
+
+static inline bool bgp_has_peer_failed(struct peer *peer, afi_t afi,
+                                      safi_t safi)
+{
+       return ((peer->status != Established) ||
+               !peer->afc_recv[afi][safi]);
+}
+
+static void bgp_show_failed_summary(struct vty *vty, struct bgp *bgp,
+                                   struct peer *peer, json_object *json_peer,
+                                   int max_neighbor_width, bool use_json)
+{
+       char timebuf[BGP_UPTIME_LEN], dn_flag[2];
+       int len;
+
+       if (use_json) {
+               if (peer_dynamic_neighbor(peer))
+                       json_object_boolean_true_add(json_peer,
+                                                    "dynamicPeer");
+               if (peer->hostname)
+                       json_object_string_add(json_peer, "hostname",
+                                              peer->hostname);
+
+               if (peer->domainname)
+                       json_object_string_add(json_peer, "domainname",
+                                              peer->domainname);
+               json_object_int_add(json_peer, "connectionsEstablished",
+                                   peer->established);
+               json_object_int_add(json_peer, "connectionsDropped",
+                                   peer->dropped);
+               peer_uptime(peer->uptime, timebuf, BGP_UPTIME_LEN,
+                           use_json, json_peer);
+               if (peer->status == Established)
+                       json_object_string_add(json_peer, "lastResetDueTo",
+                                              "AFI/SAFI Not Negotiated");
+               else
+                       bgp_show_peer_reset(NULL, peer, json_peer, true);
+       } else {
+               dn_flag[1] = '\0';
+               dn_flag[0] = peer_dynamic_neighbor(peer) ? '*' : '\0';
+               if (peer->hostname
+                   && bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME))
+                       len = vty_out(vty, "%s%s(%s)", dn_flag,
+                                     peer->hostname, peer->host);
+               else
+                       len = vty_out(vty, "%s%s", dn_flag, peer->host);
+
+               /* pad the neighbor column with spaces */
+               if (len < max_neighbor_width)
+                       vty_out(vty, "%*s", max_neighbor_width - len,
+                               " ");
+               vty_out(vty, "%7d %7d %8s", peer->established,
+                       peer->dropped,
+                       peer_uptime(peer->uptime, timebuf,
+                                   BGP_UPTIME_LEN, 0, NULL));
+               if (peer->status == Established)
+                       vty_out(vty, "  AFI/SAFI Not Negotiated\n");
+               else
+                       bgp_show_peer_reset(vty, peer, NULL,
+                                           false);
+       }
+}
+                                
+
 /* Show BGP peer's summary information. */
 static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
-                           bool use_json)
+                           bool show_failed, bool use_json)
 {
        struct peer *peer;
        struct listnode *node, *nnode;
@@ -7879,7 +8013,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
        char timebuf[BGP_UPTIME_LEN], dn_flag[2];
        char neighbor_buf[VTY_BUFSIZ];
        int neighbor_col_default_width = 16;
-       int len;
+       int len, failed_count = 0;
        int max_neighbor_width = 0;
        int pfx_rcd_safi;
        json_object *json = NULL;
@@ -7891,6 +8025,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
         * to
         * display the correct PfxRcd value we must look at SAFI_UNICAST
         */
+
        if (safi == SAFI_LABELED_UNICAST)
                pfx_rcd_safi = SAFI_UNICAST;
        else
@@ -7899,6 +8034,20 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
        if (use_json) {
                json = json_object_new_object();
                json_peers = json_object_new_object();
+               for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+                       if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
+                               continue;
+
+                       if (peer->afc[afi][safi]) {
+                               /* See if we have at least a single failed peer */
+                               if (bgp_has_peer_failed(peer, afi, safi))
+                                       failed_count++;
+                               count++;
+                       }
+                       if (peer_dynamic_neighbor(peer))
+                               dn_count++;
+               }
+                               
        } else {
                /* Loop over all neighbors that will be displayed to determine
                 * how many
@@ -7927,6 +8076,11 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
 
                                if (len > max_neighbor_width)
                                        max_neighbor_width = len;
+                               
+                               /* See if we have at least a single failed peer */
+                               if (bgp_has_peer_failed(peer, afi, safi))
+                                       failed_count++;
+                               count++;
                        }
                }
 
@@ -7937,6 +8091,23 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
                        max_neighbor_width = neighbor_col_default_width;
        }
 
+       if (show_failed && !failed_count) {
+               if (use_json) {
+                       json_object_int_add(json, "failedPeersCount", 0);
+                       json_object_int_add(json, "dynamicPeers", dn_count);
+                       json_object_int_add(json, "totalPeers", count);                 
+
+                       vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                                            json, JSON_C_TO_STRING_PRETTY));
+                       json_object_free(json);
+               } else {
+                       vty_out(vty, "%% No failed BGP neighbors found\n");
+                       vty_out(vty, "\nTotal number of neighbors %d\n", count);
+               }
+               return CMD_SUCCESS;
+       }
+               
+       count = 0;              /* Reset the value as its used again */
        for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
                if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
                        continue;
@@ -8138,78 +8309,93 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
                                vty_out(vty, "Neighbor");
                                vty_out(vty, "%*s", max_neighbor_width - 8,
                                        " ");
-                               vty_out(vty,
+                               if (show_failed)
+                                       vty_out(vty, "EstdCnt DropCnt ResetTime Reason\n");
+                               else
+                                       vty_out(vty,
                                        "V         AS MsgRcvd MsgSent   TblVer  InQ OutQ  Up/Down State/PfxRcd\n");
                        }
                }
 
                count++;
+               /* Works for both failed & successful cases */
+               if (peer_dynamic_neighbor(peer))
+                       dn_count++;
 
                if (use_json) {
-                       json_peer = json_object_new_object();
+                       json_peer = NULL;
+
+                       if (show_failed &&
+                           bgp_has_peer_failed(peer, afi, safi)) {
+                               json_peer = json_object_new_object();
+                               bgp_show_failed_summary(vty, bgp, peer,
+                                                       json_peer, 0, use_json);
+                       } else if (!show_failed) {
+                               json_peer = json_object_new_object();
+                               if (peer_dynamic_neighbor(peer)) {
+                                       json_object_boolean_true_add(json_peer,
+                                                                    "dynamicPeer");
+                               }
 
-                       if (peer_dynamic_neighbor(peer)) {
-                               dn_count++;
-                               json_object_boolean_true_add(json_peer,
-                                                            "dynamicPeer");
+                               if (peer->hostname)
+                                       json_object_string_add(json_peer, "hostname",
+                                                              peer->hostname);
+
+                               if (peer->domainname)
+                                       json_object_string_add(json_peer, "domainname",
+                                                              peer->domainname);
+
+                               json_object_int_add(json_peer, "remoteAs", peer->as);
+                               json_object_int_add(json_peer, "version", 4);
+                               json_object_int_add(json_peer, "msgRcvd",
+                                                   PEER_TOTAL_RX(peer));
+                               json_object_int_add(json_peer, "msgSent",
+                                                   PEER_TOTAL_TX(peer));
+
+                               json_object_int_add(json_peer, "tableVersion",
+                                                   peer->version[afi][safi]);
+                               json_object_int_add(json_peer, "outq",
+                                                   peer->obuf->count);
+                               json_object_int_add(json_peer, "inq", 0);
+                               peer_uptime(peer->uptime, timebuf, BGP_UPTIME_LEN,
+                                           use_json, json_peer);
+
+                               /*
+                                * Adding "pfxRcd" field to match with the corresponding
+                                * CLI. "prefixReceivedCount" will be deprecated in
+                                * future.
+                                */
+                               json_object_int_add(json_peer, "prefixReceivedCount",
+                                                   peer->pcount[afi][pfx_rcd_safi]);
+                               json_object_int_add(json_peer, "pfxRcd",
+                                                   peer->pcount[afi][pfx_rcd_safi]);
+
+                               paf = peer_af_find(peer, afi, pfx_rcd_safi);
+                               if (paf && PAF_SUBGRP(paf))
+                                       json_object_int_add(json_peer,
+                                                           "pfxSnt",
+                                                           (PAF_SUBGRP(paf))->scount);
+                               if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN))
+                                       json_object_string_add(json_peer, "state",
+                                                              "Idle (Admin)");
+                               else if (peer->afc_recv[afi][safi])
+                                       json_object_string_add(
+                                                              json_peer, "state",
+                                                              lookup_msg(bgp_status_msg, peer->status,
+                                                                         NULL));
+                               else if (CHECK_FLAG(peer->sflags,
+                                                   PEER_STATUS_PREFIX_OVERFLOW))
+                                       json_object_string_add(json_peer, "state",
+                                                              "Idle (PfxCt)");
+                               else
+                                       json_object_string_add(
+                                                              json_peer, "state",
+                                                              lookup_msg(bgp_status_msg, peer->status,
+                                                                         NULL));
                        }
-
-                       if (peer->hostname)
-                               json_object_string_add(json_peer, "hostname",
-                                                      peer->hostname);
-
-                       if (peer->domainname)
-                               json_object_string_add(json_peer, "domainname",
-                                                      peer->domainname);
-
-                       json_object_int_add(json_peer, "remoteAs", peer->as);
-                       json_object_int_add(json_peer, "version", 4);
-                       json_object_int_add(json_peer, "msgRcvd",
-                                           PEER_TOTAL_RX(peer));
-                       json_object_int_add(json_peer, "msgSent",
-                                           PEER_TOTAL_TX(peer));
-
-                       json_object_int_add(json_peer, "tableVersion",
-                                           peer->version[afi][safi]);
-                       json_object_int_add(json_peer, "outq",
-                                           peer->obuf->count);
-                       json_object_int_add(json_peer, "inq", 0);
-                       peer_uptime(peer->uptime, timebuf, BGP_UPTIME_LEN,
-                                   use_json, json_peer);
-
-                       /*
-                        * Adding "pfxRcd" field to match with the corresponding
-                        * CLI. "prefixReceivedCount" will be deprecated in
-                        * future.
-                        */
-                       json_object_int_add(json_peer, "prefixReceivedCount",
-                                           peer->pcount[afi][pfx_rcd_safi]);
-                       json_object_int_add(json_peer, "pfxRcd",
-                                       peer->pcount[afi][pfx_rcd_safi]);
-
-                       paf = peer_af_find(peer, afi, pfx_rcd_safi);
-                       if (paf && PAF_SUBGRP(paf))
-                               json_object_int_add(json_peer,
-                                               "pfxSnt",
-                                               (PAF_SUBGRP(paf))->scount);
-
-                       if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN))
-                               json_object_string_add(json_peer, "state",
-                                                      "Idle (Admin)");
-                       else if (peer->afc_recv[afi][safi])
-                               json_object_string_add(
-                                       json_peer, "state",
-                                       lookup_msg(bgp_status_msg, peer->status,
-                                                  NULL));
-                       else if (CHECK_FLAG(peer->sflags,
-                                           PEER_STATUS_PREFIX_OVERFLOW))
-                               json_object_string_add(json_peer, "state",
-                                                      "Idle (PfxCt)");
-                       else
-                               json_object_string_add(
-                                       json_peer, "state",
-                                       lookup_msg(bgp_status_msg, peer->status,
-                                                  NULL));
+                       /* Avoid creating empty peer dicts in JSON */
+                       if (json_peer == NULL)
+                               continue;
 
                        if (peer->conf_if)
                                json_object_string_add(json_peer, "idType",
@@ -8220,65 +8406,72 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
                        else if (peer->su.sa.sa_family == AF_INET6)
                                json_object_string_add(json_peer, "idType",
                                                       "ipv6");
-
                        json_object_object_add(json_peers, peer->host,
                                               json_peer);
                } else {
-                       memset(dn_flag, '\0', sizeof(dn_flag));
-                       if (peer_dynamic_neighbor(peer)) {
-                               dn_count++;
-                               dn_flag[0] = '*';
-                       }
-
-                       if (peer->hostname
-                           && bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME))
-                               len = vty_out(vty, "%s%s(%s)", dn_flag,
-                                             peer->hostname, peer->host);
-                       else
-                               len = vty_out(vty, "%s%s", dn_flag, peer->host);
-
-                       /* pad the neighbor column with spaces */
-                       if (len < max_neighbor_width)
-                               vty_out(vty, "%*s", max_neighbor_width - len,
-                                       " ");
-
-                       vty_out(vty, "4 %10u %7u %7u %8" PRIu64 " %4d %4zd %8s",
-                               peer->as, PEER_TOTAL_RX(peer),
-                               PEER_TOTAL_TX(peer), peer->version[afi][safi],
-                               0, peer->obuf->count,
-                               peer_uptime(peer->uptime, timebuf,
-                                           BGP_UPTIME_LEN, 0, NULL));
+                       if (show_failed &&
+                           bgp_has_peer_failed(peer, afi, safi)) {
+                               bgp_show_failed_summary(vty, bgp, peer, NULL,
+                                                       max_neighbor_width,
+                                                       use_json);
+                       } else if (!show_failed) {
+                               memset(dn_flag, '\0', sizeof(dn_flag));
+                               if (peer_dynamic_neighbor(peer)) {
+                                       dn_flag[0] = '*';
+                               }
 
-                       if (peer->status == Established)
-                               if (peer->afc_recv[afi][safi])
-                                       vty_out(vty, " %12ld",
-                                               peer->pcount[afi]
-                                                           [pfx_rcd_safi]);
-                               else
-                                       vty_out(vty, " NoNeg");
-                       else {
-                               if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN))
-                                       vty_out(vty, " Idle (Admin)");
-                               else if (CHECK_FLAG(
-                                                peer->sflags,
-                                                PEER_STATUS_PREFIX_OVERFLOW))
-                                       vty_out(vty, " Idle (PfxCt)");
+                               if (peer->hostname
+                                   && bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME))
+                                       len = vty_out(vty, "%s%s(%s)", dn_flag,
+                                                     peer->hostname, peer->host);
                                else
-                                       vty_out(vty, " %12s",
-                                               lookup_msg(bgp_status_msg,
-                                                          peer->status, NULL));
+                                       len = vty_out(vty, "%s%s", dn_flag, peer->host);
+
+                               /* pad the neighbor column with spaces */
+                               if (len < max_neighbor_width)
+                                       vty_out(vty, "%*s", max_neighbor_width - len,
+                                               " ");
+
+                               vty_out(vty, "4 %10u %7u %7u %8" PRIu64 " %4d %4zd %8s",
+                                       peer->as, PEER_TOTAL_RX(peer),
+                                       PEER_TOTAL_TX(peer), peer->version[afi][safi],
+                                       0, peer->obuf->count,
+                                       peer_uptime(peer->uptime, timebuf,
+                                                   BGP_UPTIME_LEN, 0, NULL));
+
+                               if (peer->status == Established)
+                                       if (peer->afc_recv[afi][safi])
+                                               vty_out(vty, " %12ld",
+                                                       peer->pcount[afi]
+                                                       [pfx_rcd_safi]);
+                                       else
+                                               vty_out(vty, " NoNeg");
+                               else {
+                                       if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN))
+                                               vty_out(vty, " Idle (Admin)");
+                                       else if (CHECK_FLAG(
+                                                           peer->sflags,
+                                                           PEER_STATUS_PREFIX_OVERFLOW))
+                                               vty_out(vty, " Idle (PfxCt)");
+                                       else
+                                               vty_out(vty, " %12s",
+                                                       lookup_msg(bgp_status_msg,
+                                                                  peer->status, NULL));
+                               }
+                               vty_out(vty, "\n");
                        }
-                       vty_out(vty, "\n");
+
                }
        }
 
        if (use_json) {
                json_object_object_add(json, "peers", json_peers);
-
+               json_object_int_add(json, "failedPeers", failed_count);
                json_object_int_add(json, "totalPeers", count);
                json_object_int_add(json, "dynamicPeers", dn_count);
 
-               bgp_show_bestpath_json(bgp, json);
+               if (!show_failed)
+                       bgp_show_bestpath_json(bgp, json);
 
                vty_out(vty, "%s\n", json_object_to_json_string_ext(
                                             json, JSON_C_TO_STRING_PRETTY));
@@ -8302,7 +8495,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
 }
 
 static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
-                                     int safi, bool use_json)
+                                     int safi, bool show_failed, bool use_json)
 {
        int is_first = 1;
        int afi_wildcard = (afi == AFI_MAX);
@@ -8345,7 +8538,8 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
                                                                         false));
                                        }
                                }
-                               bgp_show_summary(vty, bgp, afi, safi, use_json);
+                               bgp_show_summary(vty, bgp, afi, safi, show_failed,
+                                                use_json);
                        }
                        safi++;
                        if (!safi_wildcard)
@@ -8367,7 +8561,8 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
 }
 
 static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
-                                              safi_t safi, bool use_json)
+                                              safi_t safi, bool show_failed,
+                                              bool use_json)
 {
        struct listnode *node, *nnode;
        struct bgp *bgp;
@@ -8395,7 +8590,8 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
                                        ? VRF_DEFAULT_NAME
                                        : bgp->name);
                }
-               bgp_show_summary_afi_safi(vty, bgp, afi, safi, use_json);
+               bgp_show_summary_afi_safi(vty, bgp, afi, safi, show_failed,
+                                         use_json);
        }
 
        if (use_json)
@@ -8405,13 +8601,14 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
 }
 
 int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
-                        safi_t safi, bool use_json)
+                        safi_t safi, bool show_failed, bool use_json)
 {
        struct bgp *bgp;
 
        if (name) {
                if (strmatch(name, "all")) {
                        bgp_show_all_instances_summary_vty(vty, afi, safi,
+                                                          show_failed,
                                                           use_json);
                        return CMD_SUCCESS;
                } else {
@@ -8427,7 +8624,7 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
                        }
 
                        bgp_show_summary_afi_safi(vty, bgp, afi, safi,
-                                                 use_json);
+                                                 show_failed, use_json);
                        return CMD_SUCCESS;
                }
        }
@@ -8435,7 +8632,8 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
        bgp = bgp_get_default();
 
        if (bgp)
-               bgp_show_summary_afi_safi(vty, bgp, afi, safi, use_json);
+               bgp_show_summary_afi_safi(vty, bgp, afi, safi, show_failed,
+                                         use_json);
        else {
                if (use_json)
                        vty_out(vty, "{}\n");
@@ -8450,7 +8648,7 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
 /* `show [ip] bgp summary' commands. */
 DEFUN (show_ip_bgp_summary,
        show_ip_bgp_summary_cmd,
-       "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] summary [json]",
+       "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] summary [failed] [json]",
        SHOW_STR
        IP_STR
        BGP_STR
@@ -8458,11 +8656,13 @@ DEFUN (show_ip_bgp_summary,
        BGP_AFI_HELP_STR
        BGP_SAFI_WITH_LABEL_HELP_STR
        "Summary of BGP neighbor status\n"
+       "Show only sessions not in Established state\n"
        JSON_STR)
 {
        char *vrf = NULL;
        afi_t afi = AFI_MAX;
        safi_t safi = SAFI_MAX;
+       bool show_failed = false;
 
        int idx = 0;
 
@@ -8482,9 +8682,12 @@ DEFUN (show_ip_bgp_summary,
                argv_find_and_parse_safi(argv, argc, &idx, &safi);
        }
 
+       if (argv_find(argv, argc, "failed", &idx))
+               show_failed = true;
+
        bool uj = use_json(argc, argv);
 
-       return bgp_show_summary_vty(vty, vrf, afi, safi, uj);
+       return bgp_show_summary_vty(vty, vrf, afi, safi, show_failed, uj);
 }
 
 const char *get_afi_safi_str(afi_t afi, safi_t safi, bool for_json)
@@ -9165,8 +9368,6 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
        char buf1[PREFIX2STR_BUFFER], 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;
        uint16_t i;
@@ -10602,88 +10803,13 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                                            (tm->tm_sec * 1000)
                                                    + (tm->tm_min * 60000)
                                                    + (tm->tm_hour * 3600000));
-                       json_object_string_add(
-                               json_neigh, "lastResetDueTo",
-                               peer_down_str[(int)p->last_reset]);
-                       if (p->last_reset == PEER_DOWN_NOTIFY_SEND
-                           || p->last_reset == PEER_DOWN_NOTIFY_RECEIVED) {
-                               char errorcodesubcode_hexstr[5];
-                               char errorcodesubcode_str[256];
-
-                               code_str = bgp_notify_code_str(p->notify.code);
-                               subcode_str = bgp_notify_subcode_str(
-                                       p->notify.code, p->notify.subcode);
-
-                               sprintf(errorcodesubcode_hexstr, "%02X%02X",
-                                       p->notify.code, p->notify.subcode);
-                               json_object_string_add(json_neigh,
-                                                      "lastErrorCodeSubcode",
-                                                      errorcodesubcode_hexstr);
-                               snprintf(errorcodesubcode_str, 255, "%s%s",
-                                        code_str, subcode_str);
-                               json_object_string_add(json_neigh,
-                                                      "lastNotificationReason",
-                                                      errorcodesubcode_str);
-                               if (p->last_reset == PEER_DOWN_NOTIFY_RECEIVED
-                                   && p->notify.code == BGP_NOTIFY_CEASE
-                                   && (p->notify.subcode
-                                               == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
-                                       || p->notify.subcode
-                                                  == BGP_NOTIFY_CEASE_ADMIN_RESET)
-                                   && p->notify.length) {
-                                       char msgbuf[1024];
-                                       const char *msg_str;
-
-                                       msg_str = bgp_notify_admin_message(
-                                               msgbuf, sizeof(msgbuf),
-                                               (uint8_t *)p->notify.data,
-                                               p->notify.length);
-                                       if (msg_str)
-                                               json_object_string_add(
-                                                       json_neigh,
-                                                       "lastShutdownDescription",
-                                                       msg_str);
-                               }
-                       }
+                       bgp_show_peer_reset(NULL, p, json_neigh, true);
                } else {
                        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)\n",
-                                       p->last_reset == PEER_DOWN_NOTIFY_SEND
-                                               ? "sent"
-                                               : "received",
-                                       code_str, subcode_str);
-                               if (p->last_reset == PEER_DOWN_NOTIFY_RECEIVED
-                                   && p->notify.code == BGP_NOTIFY_CEASE
-                                   && (p->notify.subcode
-                                               == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
-                                       || p->notify.subcode
-                                                  == BGP_NOTIFY_CEASE_ADMIN_RESET)
-                                   && p->notify.length) {
-                                       char msgbuf[1024];
-                                       const char *msg_str;
-
-                                       msg_str = bgp_notify_admin_message(
-                                               msgbuf, sizeof(msgbuf),
-                                               (uint8_t *)p->notify.data,
-                                               p->notify.length);
-                                       if (msg_str)
-                                               vty_out(vty,
-                                                       "    Message: \"%s\"\n",
-                                                       msg_str);
-                               }
-                       } else {
-                               vty_out(vty, "due to %s\n",
-                                       peer_down_str[(int)p->last_reset]);
-                       }
-
+                       bgp_show_peer_reset(vty, p, NULL, false);
                        if (p->last_reset_cause_size) {
                                msg = p->last_reset_cause;
                                vty_out(vty,
index 961467e2292d079eec84cbe22c2923e004cb49ed..27b5ea47b27d461fa617fa17a6460892fdd1aaa7 100644 (file)
@@ -71,7 +71,7 @@ extern int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty,
                                               safi_t *safi, struct bgp **bgp,
                                               bool use_json);
 extern int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
-                               safi_t safi, bool use_json);
+                               safi_t safi, bool show_failed, bool use_json);
 extern void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp,
                                            afi_t afi);
 #endif /* _QUAGGA_BGP_VTY_H */
index 9e05fd5629d53f2e1ba535f3c0ead97ba4890216..880fceb8f13959aa88ed4f603b77f8a01f97e3b0 100644 (file)
@@ -1194,6 +1194,9 @@ struct peer {
 #define PEER_DOWN_BFD_DOWN              24 /* BFD down */
 #define PEER_DOWN_IF_DOWN               25 /* Interface down */
 #define PEER_DOWN_NBR_ADDR_DEL          26 /* Peer address lost */
+#define PEER_DOWN_WAITING_NHT           27 /* Waiting for NHT to resolve */
+#define PEER_DOWN_NBR_ADDR              28 /* Waiting for peer IPv6 IP Addr */
+#define PEER_DOWN_VRF_UNINIT            29 /* Associated VRF is not init yet */
        size_t last_reset_cause_size;
        uint8_t last_reset_cause[BGP_MAX_PACKET_SIZE];
 
index 92d4126cec1a896aa8d26cbba2d2fb754ea15269..da339b440961a49f6aad8b282d693a02b7e80711 100644 (file)
@@ -2251,6 +2251,12 @@ structure is extended with :clicmd:`show bgp [afi] [safi]`.
    Show a bgp peer summary for the specified address family, and subsequent
    address-family.
 
+.. index:: show bgp [afi] [safi] summary failed [json]
+.. clicmd:: show bgp [afi] [safi] summary failed [json]
+
+   Show a bgp peer summary for peers that are not succesfully exchanging routes
+   for the specified address family, and subsequent address-family.
+
 .. index:: show bgp [afi] [safi] neighbor [PEER]
 .. clicmd:: show bgp [afi] [safi] neighbor [PEER]