]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: Adding BGP GR Per Neighbor show commands.
authorbisdhdh <biswajit.sadhu@gmail.com>
Wed, 23 Oct 2019 10:02:48 +0000 (15:32 +0530)
committerbisdhdh <biswajit.sadhu@gmail.com>
Thu, 23 Jan 2020 04:04:25 +0000 (09:34 +0530)
* Added new show command to show the graceful restart
information for each neighbor.
Cmd: show bgp [<ipv4|ipv6>] neighbors [<A.B.C.D|X:X::X:X|WORD>] graceful-restart
* Changes to show neighbors commands for displaying
graceful restart information.
Cmd :show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6>] neighbors [<A.B.C.D|X:X::X:X|

Signed-off-by: Biswajit Sadhu <sadhub@vmware.com>
bgpd/bgp_fsm.c
bgpd/bgp_fsm.h
bgpd/bgp_open.c
bgpd/bgp_vty.c
bgpd/bgpd.c
bgpd/bgpd.h

index 1f09233c5d7c946d1414c60218221a8aa458dd93..24b54d35355dfb84b4a06eedb323be8eb8c412af 100644 (file)
@@ -1099,6 +1099,7 @@ int bgp_stop(struct peer *peer)
                /* bgp log-neighbor-changes of neighbor Down */
                if (bgp_flag_check(peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) {
                        struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
+
                        zlog_info(
                                "%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s",
                                peer->host,
@@ -2409,44 +2410,44 @@ void bgp_peer_gr_flags_update(struct peer *peer)
                                __func__);
        if (CHECK_FLAG(peer->peer_gr_new_status_flag,
                PEER_GRACEFUL_RESTART_NEW_STATE_HELPER))
-               bgp_peer_flag_set(peer,
+               SET_FLAG(peer->flags,
                                PEER_FLAG_GRACEFUL_RESTART_HELPER);
        else
-               bgp_peer_flag_unset(peer,
+               UNSET_FLAG(peer->flags,
                                PEER_FLAG_GRACEFUL_RESTART_HELPER);
        if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
                zlog_debug(
                        "BGP_GR:: Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_HELPER : %s : !",
                        peer->host,
-                       (bgp_peer_flag_check(peer,
+                       (CHECK_FLAG(peer->flags,
                                PEER_FLAG_GRACEFUL_RESTART_HELPER) ?
                                "Set" : "UnSet"));
        if (CHECK_FLAG(peer->peer_gr_new_status_flag,
                PEER_GRACEFUL_RESTART_NEW_STATE_RESTART))
-               bgp_peer_flag_set(peer,
+               SET_FLAG(peer->flags,
                                PEER_FLAG_GRACEFUL_RESTART);
        else
-               bgp_peer_flag_unset(peer,
+               UNSET_FLAG(peer->flags,
                                PEER_FLAG_GRACEFUL_RESTART);
        if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
                zlog_debug(
                        "BGP_GR:: Peer %s Flag PEER_FLAG_GRACEFUL_RESTART : %s : !",
                        peer->host,
-                       (bgp_peer_flag_check(peer,
+                       (CHECK_FLAG(peer->flags,
                                PEER_FLAG_GRACEFUL_RESTART) ?
                                "Set" : "UnSet"));
        if (CHECK_FLAG(peer->peer_gr_new_status_flag,
                PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT))
-               bgp_peer_flag_set(peer,
+               SET_FLAG(peer->flags,
                                PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT);
        else
-               bgp_peer_flag_unset(peer,
+               UNSET_FLAG(peer->flags,
                                PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT);
        if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
                zlog_debug(
                "BGP_GR:: Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT : %s : !",
                        peer->host,
-                       (bgp_peer_flag_check(peer,
+                       (CHECK_FLAG(peer->flags,
                                PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT) ?
                                "Set" : "UnSet"));
 }
index 8a25d1b29e66a6f6828b2829533d952526cc3d65..e6900213380edd4f2483675aea59912915cbdca2 100644 (file)
@@ -146,7 +146,4 @@ int bgp_gr_lookup_n_update_all_peer(struct bgp *bgp,
                enum global_mode global_new_state,
                enum global_mode global_old_state);
 void bgp_peer_gr_flags_update(struct peer *peer);
-extern void bgp_peer_flag_unset(struct peer *peer, int flag_bit);
-extern void bgp_peer_flag_set(struct peer *peer, int flag_bit);
-
 #endif /* _QUAGGA_BGP_FSM_H */
index f7bb2cc1773fd82e2dffd00271a2af22af4900f1..eb6dc1a753087d405427f1c5b8bb245c0930affd 100644 (file)
@@ -1311,9 +1311,9 @@ static void bgp_peer_send_gr_capability(struct stream *s, struct peer *peer,
        unsigned long capp = 0;
        unsigned long rcapp = 0;
 
-       if ((bgp_peer_flag_check(peer,
+       if ((CHECK_FLAG(peer->flags,
                        PEER_FLAG_GRACEFUL_RESTART)) ||
-               (bgp_peer_flag_check(peer,
+               (CHECK_FLAG(peer->flags,
                        PEER_FLAG_GRACEFUL_RESTART_HELPER))) {
 
                if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
@@ -1331,7 +1331,7 @@ static void bgp_peer_send_gr_capability(struct stream *s, struct peer *peer,
                stream_putc(s, 0);
                restart_time = peer->bgp->restart_time;
                if ((peer->bgp->t_startup) &&
-                       (bgp_peer_flag_check(peer,
+                       (CHECK_FLAG(peer->flags,
                                PEER_FLAG_GRACEFUL_RESTART))) {
                        SET_FLAG(restart_time, RESTART_R_BIT);
                        SET_FLAG(peer->cap, PEER_CAP_RESTART_BIT_ADV);
@@ -1341,7 +1341,7 @@ static void bgp_peer_send_gr_capability(struct stream *s, struct peer *peer,
                /* Send address-family specific graceful-restart capability
                 * only when GR config is present
                 */
-               if (bgp_peer_flag_check(peer, PEER_FLAG_GRACEFUL_RESTART)) {
+               if (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)) {
                        FOREACH_AFI_SAFI (afi, safi) {
                                if (peer->afc[afi][safi]) {
                                        if (BGP_DEBUG(graceful_restart,
index 57ccee49e9c7bcb23e4d31b9f3eaac50d295a79e..1038e79b33248ad21d66fdbca8b5e79b87c29ebb 100644 (file)
@@ -120,6 +120,24 @@ enum show_type {
        show_ipv6_peer
 };
 
+static struct peer_group *listen_range_exists(
+                                               struct bgp *bgp,
+                                               struct prefix *range,
+                                               int exact);
+
+static void bgp_show_global_graceful_restart_mode_vty(
+                                       struct vty *vty,
+                                       struct bgp *bgp,
+                                       bool use_json,
+                                       json_object *json);
+
+static int bgp_show_neighbor_graceful_restart_afi_all(
+                               struct vty *vty,
+                               enum show_type type,
+                               const char *ip_str,
+                               afi_t afi,
+                               bool use_json);
+
 static enum node_type bgp_node_type(afi_t afi, safi_t safi)
 {
        switch (afi) {
@@ -780,6 +798,8 @@ static int bgp_peer_clear(struct peer *peer, afi_t afi, safi_t safi,
                        if (!peer->afc[afi][tmp_safi])
                                continue;
 
+                       bgp_peer_gr_flags_update(peer);
+
                        if (stype == BGP_CLEAR_SOFT_NONE)
                                ret = peer_clear(peer, &nnode);
                        else
@@ -8577,8 +8597,6 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
                if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
                        continue;
 
-               bgp_peer_gr_flags_update(peer);
-
                if (!peer->afc[afi][safi])
                        continue;
 
@@ -9234,6 +9252,405 @@ static void bgp_show_peer_afi_orf_cap(struct vty *vty, struct peer *p,
        }
 }
 
+static void bgp_show_neighnor_graceful_restart_rbit(
+                                               struct vty *vty,
+                                               struct peer *p,
+                                               bool use_json,
+                                               json_object *json)
+{
+       bool rbit_status = 0;
+
+       if (!use_json)
+               vty_out(vty, "\n    R bit          : ");
+
+       if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_ADV) &&
+               (CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) &&
+               (p->status == Established)) {
+
+               if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_BIT_RCV))
+                       rbit_status = 1;
+               else
+                       rbit_status = 0;
+       }
+
+       if (rbit_status) {
+               if (use_json)
+                       json_object_boolean_true_add(
+                                       json, "rBit");
+               else
+                       vty_out(vty, "True\n");
+       } else {
+               if (use_json)
+                       json_object_boolean_false_add(
+                                       json, "rBit");
+               else
+                       vty_out(vty, "False\n");
+       }
+}
+
+static void bgp_show_neighbor_graceful_restart_remote_mode(
+                                               struct vty *vty,
+                                               struct peer *peer,
+                                               bool use_json,
+                                               json_object *json)
+{
+       const char *mode = "NotReceived";
+
+       if (!use_json)
+               vty_out(vty, "\n    Remote GR Mode : ");
+
+       if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV) &&
+               (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) &&
+               (peer->status == Established)) {
+
+               if ((peer->nsf_af_count == 0) &&
+                       !CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
+
+                       /*Gr disabled case*/
+                       mode = "Disable";
+
+               } else if (peer->nsf_af_count == 0) {
+
+                       /* Helper */
+                       mode = "Helper";
+
+               } else if (peer->nsf_af_count != 0) {
+
+                       /* Restart */
+                       mode = "Restart";
+
+               }
+       }
+
+       if (use_json) {
+               json_object_string_add(json,
+                               "remoteGrMode", mode);
+       } else
+               vty_out(vty, mode, "\n");
+}
+
+static void  bgp_show_neighbor_graceful_restart_local_mode(struct vty *vty,
+                                               struct peer *p,
+                                               bool use_json,
+                                               json_object *json)
+{
+       const char *mode = "Invalid";
+
+       if (!use_json)
+               vty_out(vty, "    Local GR Mode  : ");
+
+       if (bgp_peer_gr_mode_get(p) == PEER_HELPER)
+               mode = "Helper";
+       else if (bgp_peer_gr_mode_get(p) == PEER_GR)
+               mode = "Restart";
+       else if (bgp_peer_gr_mode_get(p) == PEER_DISABLE)
+               mode = "Disable";
+       else if (bgp_peer_gr_mode_get(p) == PEER_GLOBAL_INHERIT)
+               if (bgp_global_gr_mode_get(p->bgp) == GLOBAL_HELPER)
+                       mode = "Helper*";
+               else if (bgp_global_gr_mode_get(p->bgp) == GLOBAL_GR)
+                       mode = "Restart*";
+               else if (bgp_global_gr_mode_get(p->bgp) == GLOBAL_DISABLE)
+                       mode = "Disable*";
+               else
+                       mode = "Invalid*";
+       else
+               mode = "Invalid";
+
+       if (use_json) {
+               json_object_string_add(json,
+                               "localGrMode", mode);
+       } else {
+               vty_out(vty, mode, "\n");
+       }
+}
+
+static void  bgp_show_neighbor_graceful_restart_capability_per_afi_safi(
+                                       struct vty *vty, struct peer *peer,
+                                       bool use_json, json_object *json)
+{
+       afi_t afi = AFI_MAX;
+       safi_t safi = SAFI_MAX;
+       json_object *json_afi_safi = NULL;
+       json_object *json_timer = NULL;
+       json_object *json_endofrib_status = NULL;
+
+       for (afi = AFI_IP; afi < AFI_MAX; afi++) {
+               for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN; safi++) {
+
+                       if (peer->afc_nego[afi][safi]
+                               && CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV)
+                               && CHECK_FLAG(peer->af_cap[afi][safi],
+                               PEER_CAP_RESTART_AF_RCV)) {
+
+                               if (use_json) {
+                                       json_afi_safi =
+                                               json_object_new_object();
+                                       json_endofrib_status =
+                                               json_object_new_object();
+                                       json_timer =
+                                               json_object_new_object();
+                               }
+
+                               if (!use_json) {
+                                       vty_out(vty, "    %s :\n",
+                                       get_afi_safi_str(afi, safi, false));
+
+                                       vty_out(vty,
+                                       "     F bit                 : ");
+                               } else
+                                       get_afi_safi_str(afi, safi, true);
+
+                               if (peer->nsf[afi][safi]
+                                       && CHECK_FLAG(
+                                       peer->af_cap[afi][safi],
+                                       PEER_CAP_RESTART_AF_PRESERVE_RCV)) {
+
+                                       if (use_json) {
+                                               json_object_boolean_true_add(
+                                               json_afi_safi, "fBit");
+                                       } else {
+                                               vty_out(vty,
+                                                       "True\n");
+                                       }
+
+                               } else {
+
+                                       if (use_json) {
+                                               json_object_boolean_false_add(
+                                               json_afi_safi, "fBit");
+                                       } else {
+                                               vty_out(vty,
+                                                       "False\n");
+                                       }
+
+                               }
+
+                               if (!use_json)
+                                       vty_out(vty,
+                                       "     End-of-RIB Received   : ");
+
+                               if (CHECK_FLAG(peer->af_sflags[afi][safi],
+                                               PEER_STATUS_EOR_RECEIVED)) {
+
+                                       if (use_json) {
+                                               json_object_boolean_true_add(
+                                               json_endofrib_status,
+                                                       "endOfRibRecv");
+                                       } else {
+                                               vty_out(vty, "Yes\n");
+                                       }
+
+                               } else {
+                                       if (use_json) {
+                                               json_object_boolean_false_add(
+                                               json_endofrib_status,
+                                                       "endOfRibRecv");
+                                       } else {
+                                               vty_out(vty, "No\n");
+                                       }
+                               }
+
+                               if (!use_json)
+                                       vty_out(vty,
+                                       "     End-of-RIB Send       : ");
+
+                               if (CHECK_FLAG(peer->af_sflags[afi][safi],
+                                               PEER_STATUS_EOR_SEND)) {
+
+                                       if (use_json) {
+                                               json_object_boolean_true_add(
+                                               json_endofrib_status,
+                                                        "endOfRibSend");
+                                       } else {
+                                               vty_out(vty, "Yes\n");
+                                       }
+
+                               } else {
+                                       if (use_json) {
+                                               json_object_boolean_false_add(
+                                               json_endofrib_status,
+                                                       "endOfRibSend");
+                                       } else {
+                                               vty_out(vty, "No\n");
+                                       }
+                               }
+
+                               if (use_json) {
+
+                                       json_object_int_add(json_timer,
+                                               "stalePathTimer",
+                                               peer->bgp->stalepath_time);
+
+                                       if (peer->t_gr_stale != NULL) {
+
+                                               json_object_int_add(
+                                               json_timer,
+                                               "stalePathTimerRemaining",
+                                               thread_timer_remain_second(
+                                               peer->t_gr_stale));
+                                       }
+
+                                       json_object_int_add(json_timer,
+                                               "selectionDeferralTimer",
+                                               peer->bgp->stalepath_time);
+
+                                       if (peer->bgp
+                                               ->gr_info[afi][safi]
+                                               .t_select_deferral != NULL) {
+
+                                               json_object_int_add(
+                                               json_timer,
+                                               "selectionDeferralTimerRemaining",
+                                               thread_timer_remain_second(
+                                               peer->bgp
+                                               ->gr_info[afi][safi]
+                                               .t_select_deferral));
+                                       }
+
+                               } else {
+
+                                       vty_out(vty, "     Timers:\n");
+
+                                       vty_out(vty, "%*s", 6, "");
+                                       vty_out(vty,
+                                       "Stale Path Time(sec)%*s: %u\n",
+                                               19, "",
+                                       peer->bgp->stalepath_time);
+
+                                       if (peer->t_gr_stale != NULL) {
+                                               vty_out(vty, "%*s", 6, "");
+                                               vty_out(vty,
+                                               "Stale Path Remaining(sec)%*s: %ld\n",
+                                               14, "",
+                                               thread_timer_remain_second(
+                                               peer->t_gr_stale));
+                                       }
+
+                                       vty_out(vty, "%*s", 6, "");
+                                       vty_out(vty,
+                                       "Selection Deferral Time(sec)%*s: %u\n",
+                                       11, "",
+                                       peer->bgp->select_defer_time);
+
+                                       if (peer->bgp
+                                               ->gr_info[afi][safi]
+                                               .t_select_deferral != NULL) {
+
+                                               vty_out(vty, "%*s", 6, "");
+                                               vty_out(vty,
+                                               "Selection Deferral Time Remaining(sec) : %ld\n",
+                                               thread_timer_remain_second(
+                                               peer->bgp
+                                               ->gr_info[afi][safi]
+                                               .t_select_deferral));
+                                       }
+
+                               }
+                               if (use_json) {
+                                       json_object_object_add(json_afi_safi,
+                                                       "endOfRibStatus",
+                                                        json_endofrib_status);
+                                       json_object_object_add(json_afi_safi,
+                                                       "timers",
+                                                        json_timer);
+                                       json_object_object_add(json,
+                                               get_afi_safi_str(afi, safi, true),
+                                                        json_afi_safi);
+                               }
+                       }
+               }
+       }
+}
+
+static void  bgp_show_neighbor_graceful_restart_time(struct vty *vty,
+                                                       struct peer *p,
+                                                       bool use_json,
+                                                       json_object *json)
+{
+       if (use_json) {
+               json_object *json_timer = NULL;
+
+               json_timer = json_object_new_object();
+
+               json_object_int_add(json_timer,
+                                       "configuredRestartTimer",
+                                       p->bgp->restart_time);
+
+               json_object_int_add(json_timer,
+                                       "recivedRestartTimer",
+                                       p->v_gr_restart);
+
+               if (p->t_gr_restart != NULL) {
+                       json_object_int_add(json_timer,
+                                       "restartTimerRemaining",
+                                       thread_timer_remain_second(
+                                       p->t_gr_restart)
+                                       );
+               }
+
+               json_object_object_add(json, "timers", json_timer);
+       } else {
+
+               vty_out(vty, "    Timers :\n");
+               vty_out(vty,
+                       "     Configured Restart Time(sec)  : %u\n",
+                               p->bgp->restart_time);
+
+               vty_out(vty,
+                       "     Received Restart Time(sec)    : %u\n",
+                                       p->v_gr_restart);
+               if (p->t_gr_restart != NULL) {
+                       vty_out(vty,
+                       "     Restart Time Remaining(sec)   : %ld\n",
+                               thread_timer_remain_second(
+                                       p->t_gr_restart));
+               }
+       }
+}
+
+static void bgp_show_peer_gr_status(struct vty *vty, struct peer *p,
+                                       bool use_json,
+                                       json_object *json)
+{
+       char buf[SU_ADDRSTRLEN] = {0};
+       char dn_flag[2] = {0};
+       char neighborAddr[INET6_ADDRSTRLEN] = {0};
+
+       memset(dn_flag, '\0', sizeof(dn_flag));
+       if (!p->conf_if && peer_dynamic_neighbor(p))
+               dn_flag[0] = '*';
+
+       if (p->conf_if) {
+               if (use_json)
+                       json_object_string_add(json, "neighborAddr",
+                               BGP_PEER_SU_UNSPEC(p)
+                               ? "none"
+                               : sockunion2str(&p->su, buf,
+                                       SU_ADDRSTRLEN));
+               else
+                       vty_out(vty, "BGP neighbor on %s: %s\n",
+                               p->conf_if,
+                               BGP_PEER_SU_UNSPEC(p)
+                                       ? "none"
+                                       : sockunion2str(&p->su, buf,
+                                                       SU_ADDRSTRLEN));
+       } else {
+               sprintf(neighborAddr, "%s%s", dn_flag, p->host);
+
+               if (use_json)
+                       json_object_string_add(
+                               json, "neighborAddr",
+                               neighborAddr);
+               else
+                       vty_out(vty, "BGP neighbor is %s\n",
+                               neighborAddr);
+       }
+
+       /* more gr info in new format */
+       BGP_SHOW_PEER_GR_CAPABILITY(vty, p, use_json, json);
+}
+
 static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
                              safi_t safi, bool use_json,
                              json_object *json_neigh)
@@ -9548,7 +9965,9 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
                                        "prefixAllowedRestartIntervalMsecs",
                                        p->pmax_restart[afi][safi] * 60000);
                }
-               json_object_object_add(json_neigh, get_afi_safi_str(afi, safi, true),
+               json_object_object_add(json_neigh,
+                                       get_afi_safi_str(afi,
+                                               safi, true),
                                       json_addr);
 
        } else {
@@ -10987,14 +11406,12 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                                                        vty_out(vty, "none");
                                                vty_out(vty, "\n");
                                        }
-                               }
+                               } /* Gracefull Restart */
                        }
                }
        }
 
        /* graceful restart information */
-       if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV) || p->t_gr_restart
-           || p->t_gr_stale) {
                json_object *json_grace = NULL;
                json_object *json_grace_send = NULL;
                json_object *json_grace_recv = NULL;
@@ -11006,10 +11423,11 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                        json_grace_send = json_object_new_object();
                        json_grace_recv = json_object_new_object();
 
-                       if (p->status == Established) {
+                       if ((p->status == Established) &&
+                                       CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) {
                                FOREACH_AFI_SAFI (afi, safi) {
                                        if (CHECK_FLAG(p->af_sflags[afi][safi],
-                                                      PEER_STATUS_EOR_SEND)) {
+                                               PEER_STATUS_EOR_SEND)) {
                                                json_object_boolean_true_add(
                                                        json_grace_send,
                                                        get_afi_safi_str(afi,
@@ -11020,8 +11438,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                                }
                                FOREACH_AFI_SAFI (afi, safi) {
                                        if (CHECK_FLAG(
-                                                   p->af_sflags[afi][safi],
-                                                   PEER_STATUS_EOR_RECEIVED)) {
+                                               p->af_sflags[afi][safi],
+                                               PEER_STATUS_EOR_RECEIVED)) {
                                                json_object_boolean_true_add(
                                                        json_grace_recv,
                                                        get_afi_safi_str(afi,
@@ -11031,11 +11449,13 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                                        }
                                }
                        }
+                       json_object_object_add(json_grace,
+                                               "endOfRibSend",
+                                                       json_grace_send);
+                       json_object_object_add(json_grace,
+                                               "endOfRibRecv",
+                                               json_grace_recv);
 
-                       json_object_object_add(json_grace, "endOfRibSend",
-                                              json_grace_send);
-                       json_object_object_add(json_grace, "endOfRibRecv",
-                                              json_grace_recv);
 
                        if (p->t_gr_restart)
                                json_object_int_add(json_grace,
@@ -11051,12 +11471,16 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                                        thread_timer_remain_second(
                                                p->t_gr_stale)
                                                * 1000);
-
+                       /* more gr info in new format */
+                       BGP_SHOW_PEER_GR_CAPABILITY(vty, p, use_json,
+                                                       json_grace);
                        json_object_object_add(
                                json_neigh, "gracefulRestartInfo", json_grace);
                } else {
-                       vty_out(vty, "  Graceful restart information:\n");
-                       if (p->status == Established) {
+                       vty_out(vty, "  Graceful restart informations:\n");
+                       if ((p->status == Established) &&
+                               CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) {
+
                                vty_out(vty, "    End-of-RIB send: ");
                                FOREACH_AFI_SAFI (afi, safi) {
                                        if (CHECK_FLAG(p->af_sflags[afi][safi],
@@ -11065,8 +11489,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                                                        eor_send_af_count ? ", "
                                                                          : "",
                                                        get_afi_safi_str(afi,
-                                                                        safi,
-                                                                        false));
+                                                                       safi,
+                                                                       false));
                                                eor_send_af_count++;
                                        }
                                }
@@ -11100,8 +11524,11 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                                        "    The remaining time of stalepath timer is %ld\n",
                                        thread_timer_remain_second(
                                                p->t_gr_stale));
+
+                       /* more gr info in new format */
+                       BGP_SHOW_PEER_GR_CAPABILITY(vty, p, use_json, NULL);
                }
-       }
+
        if (use_json) {
                json_object *json_stat = NULL;
                json_stat = json_object_new_object();
@@ -11515,6 +11942,84 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
        }
 }
 
+static int bgp_show_neighbor_graceful_restart(struct vty *vty,
+                                       struct bgp *bgp,
+                                       enum show_type type,
+                                       union sockunion *su,
+                                       const char *conf_if, afi_t afi,
+                                       bool use_json, json_object *json)
+{
+       struct listnode *node, *nnode;
+       struct peer *peer;
+       int find = 0;
+       safi_t safi = SAFI_UNICAST;
+       json_object *json_neighbor = NULL;
+
+       for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+
+               if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
+                       continue;
+
+               if ((peer->afc[afi][safi]) == 0)
+                       continue;
+
+               if (use_json)
+                       json_neighbor = json_object_new_object();
+
+               if (show_all == type) {
+                       bgp_show_peer_gr_status(vty, peer, use_json,
+                                                       json_neighbor);
+
+                       if (use_json)
+                               json_object_object_add(json,
+                                               peer->host, json_neighbor);
+
+               } else if (show_peer == type) {
+                       if (conf_if) {
+                               if ((peer->conf_if
+                                       && !strcmp(peer->conf_if, conf_if))
+                                       || (peer->hostname
+                                       && !strcmp(peer->hostname, conf_if))) {
+                                       find = 1;
+                                       bgp_show_peer_gr_status(vty,
+                                               peer, use_json,
+                                               json_neighbor);
+                               }
+                       } else {
+                               if (sockunion_same(&peer->su, su)) {
+                                       find = 1;
+                                       bgp_show_peer_gr_status(vty,
+                                               peer, use_json,
+                                               json_neighbor);
+                               }
+                       }
+                       if (use_json && find) {
+                               json_object_object_add(json,
+                                               peer->host, json_neighbor);
+                       }
+               }
+
+               if (find)
+                       break;
+       }
+
+       if (type == show_peer && !find) {
+               if (use_json)
+                       json_object_boolean_true_add(json,
+                                                       "bgpNoSuchNeighbor");
+               else
+                       vty_out(vty, "%% No such neighbor\n");
+       }
+       if (use_json) {
+               vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                                            json, JSON_C_TO_STRING_PRETTY));
+       } else {
+               vty_out(vty, "\n");
+       }
+
+       return CMD_SUCCESS;
+}
+
 static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
                             enum show_type type, union sockunion *su,
                             const char *conf_if, bool use_json,
@@ -11620,6 +12125,46 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
        return CMD_SUCCESS;
 }
 
+static void  bgp_show_neighbor_graceful_restart_vty(struct vty *vty,
+                                enum show_type type, const char *ip_str,
+                                afi_t afi, bool use_json)
+{
+
+       int ret;
+       struct bgp *bgp;
+       union sockunion su;
+       json_object *json = NULL;
+
+       bgp = bgp_get_default();
+
+       if (bgp) {
+
+               if (!use_json) {
+                       bgp_show_global_graceful_restart_mode_vty(vty, bgp,
+                                               use_json, NULL);
+               }
+
+               json = json_object_new_object();
+               if (ip_str) {
+                       ret = str2sockunion(ip_str, &su);
+                       if (ret < 0)
+                               bgp_show_neighbor_graceful_restart(vty,
+                                       bgp, type, NULL, ip_str,
+                                       afi, use_json, json);
+                       else
+                               bgp_show_neighbor_graceful_restart(vty,
+                                       bgp, type, &su, NULL,
+                                       afi, use_json, json);
+               } else {
+                       bgp_show_neighbor_graceful_restart(vty, bgp,
+                                       type, NULL, NULL, afi,
+                                       use_json, json);
+               }
+               json_object_free(json);
+       }
+
+}
+
 static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
                                                 enum show_type type,
                                                 const char *ip_str,
@@ -11757,6 +12302,52 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name,
        return CMD_SUCCESS;
 }
 
+
+
+/* "show [ip] bgp neighbors graceful-restart" commands.  */
+DEFUN (show_ip_bgp_neighbors_gracrful_restart,
+       show_ip_bgp_neighbors_graceful_restart_cmd,
+       "show bgp [<ipv4|ipv6>] neighbors [<A.B.C.D|X:X::X:X|WORD>] graceful-restart [json]",
+       SHOW_STR
+       BGP_STR
+       IP_STR
+       IPV6_STR
+       NEIGHBOR_STR
+       "Neighbor to display information about\n"
+       "Neighbor to display information about\n"
+       "Neighbor on BGP configured interface\n"
+       GR_SHOW
+       JSON_STR)
+{
+       char *sh_arg = NULL;
+       enum show_type sh_type;
+       int idx = 0;
+       afi_t afi = AFI_MAX;
+
+       bool uj = use_json(argc, argv);
+
+       if      (!argv_find_and_parse_afi(argv, argc, &idx, &afi))
+               afi = AFI_MAX;
+
+       idx++;
+
+       if (argv_find(argv, argc, "A.B.C.D", &idx)
+           || argv_find(argv, argc, "X:X::X:X", &idx)
+           || argv_find(argv, argc, "WORD", &idx)) {
+               sh_type = show_peer;
+               sh_arg = argv[idx]->arg;
+       } else
+               sh_type = show_all;
+
+       if (!argv_find(argv, argc, "graceful-restart", &idx))
+               return CMD_SUCCESS;
+
+
+       return bgp_show_neighbor_graceful_restart_afi_all(vty,
+                                               sh_type, sh_arg,
+                                               afi, uj);
+}
+
 /* "show [ip] bgp neighbors" commands.  */
 DEFUN (show_ip_bgp_neighbors,
        show_ip_bgp_neighbors_cmd,
@@ -11895,8 +12486,73 @@ DEFUN (show_ip_bgp_lcommunity_info,
 
        return CMD_SUCCESS;
 }
+/* Graceful Restart */
+
+static void bgp_show_global_graceful_restart_mode_vty(struct vty *vty,
+                                       struct bgp *bgp,
+                                       bool use_json,
+                                       json_object *json)
+{
 
 
+       vty_out(vty, "\n%s", SHOW_GR_HEADER);
+
+       int bgp_global_gr_mode = bgp_global_gr_mode_get(bgp);
+
+       switch (bgp_global_gr_mode) {
+
+       case GLOBAL_HELPER:
+               vty_out(vty,
+                               "Global Bgp GR Mode :  Helper\n");
+               break;
+
+       case GLOBAL_GR:
+               vty_out(vty,
+                       "Global Bgp GR Mode :  Restart\n");
+               break;
+
+       case GLOBAL_DISABLE:
+               vty_out(vty,
+                               "Global Bgp GR Mode :  Disable\n");
+               break;
+
+       case GLOBAL_INVALID:
+       default:
+               vty_out(vty,
+                       "Global Bgp GR Mode  Invalid\n");
+               break;
+       }
+       vty_out(vty, "\n");
+}
+
+static int  bgp_show_neighbor_graceful_restart_afi_all(struct vty *vty,
+                                               enum show_type type,
+                                               const char *ip_str,
+                                               afi_t afi,
+                                               bool use_json)
+{
+       if ((afi == AFI_MAX) && (ip_str == NULL)) {
+               afi = AFI_IP;
+
+               while ((afi != AFI_L2VPN) && (afi < AFI_MAX)) {
+
+                       bgp_show_neighbor_graceful_restart_vty(vty,
+                                                       type, ip_str,
+                                                       afi, use_json);
+                       afi++;
+               }
+       } else if (afi != AFI_MAX) {
+               bgp_show_neighbor_graceful_restart_vty(vty,
+                                                       type, ip_str,
+                                                       afi, use_json);
+       } else {
+               return CMD_ERR_INCOMPLETE;
+       }
+
+       return CMD_SUCCESS;
+}
+/* Graceful Restart */
+
 DEFUN (show_ip_bgp_attr_info,
        show_ip_bgp_attr_info_cmd,
        "show [ip] bgp attribute-info",
@@ -15664,6 +16320,9 @@ void bgp_vty_init(void)
        /* "show [ip] bgp neighbors" commands. */
        install_element(VIEW_NODE, &show_ip_bgp_neighbors_cmd);
 
+       install_element(VIEW_NODE,
+                       &show_ip_bgp_neighbors_graceful_restart_cmd);
+
        /* "show [ip] bgp peer-group" commands. */
        install_element(VIEW_NODE, &show_ip_bgp_peer_groups_cmd);
 
index 05e5822c8c84d7ee33fd3d215cb8a7c93ea75037..1a89fbec5d70f7af2b242180e17a33d234ca7f48 100644 (file)
@@ -7217,23 +7217,6 @@ struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
        return peer;
 }
 
-
-/* BGP peer flag manipulation.  */
-void bgp_peer_flag_set(struct peer *peer, int flag)
-{
-       SET_FLAG(peer->flags, flag);
-}
-
-void bgp_peer_flag_unset(struct peer *peer, int flag)
-{
-       UNSET_FLAG(peer->flags, flag);
-}
-
-int bgp_peer_flag_check(struct peer *peer, int flag)
-{
-       return CHECK_FLAG(peer->flags, flag);
-}
-
 void bgp_gr_apply_running_config(void)
 {
        struct peer *peer = NULL;
index 028f1179cfe37c284a531ae4499983da1488037f..57b01af9acfc2f0e63f78d932bfb2dc8e535b080 100644 (file)
@@ -1878,9 +1878,6 @@ extern void bgp_free(struct bgp *);
 void bgp_gr_apply_running_config(void);
 
 /* BGP GR */
-void bgp_peer_flag_set(struct peer *peer, int flag_bit);
-void bgp_peer_flag_unset(struct peer *peer, int flag_bit);
-int bgp_peer_flag_check(struct peer *peer, int flag_bit);
 int bgp_global_gr_init(struct bgp *bgp);
 int bgp_peer_gr_init(struct peer *peer);