diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 650800b962..e3f1abe748 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -9430,7 +9430,7 @@ static int bgp_clear_prefix(struct vty *vty, const char *view_name, /* one clear bgp command to rule them all */ DEFUN (clear_ip_bgp_all, clear_ip_bgp_all_cmd, - "clear [ip] bgp [ VIEWVRFNAME] [ []] <*|A.B.C.D$neighbor|X:X::X:X$neighbor|WORD$neighbor|(1-4294967295)|external|peer-group PGNAME> []|in [prefix-filter]|out>]", + "clear [ip] bgp [ VIEWVRFNAME] [ []] <*|A.B.C.D$neighbor|X:X::X:X$neighbor|WORD$neighbor|(1-4294967295)|external|peer-group PGNAME> []|in [prefix-filter]|out|message-stats>]", CLEAR_STR IP_STR BGP_STR @@ -9452,7 +9452,8 @@ DEFUN (clear_ip_bgp_all, BGP_SOFT_OUT_STR BGP_SOFT_IN_STR "Push out prefix-list ORF and do inbound soft reconfig\n" - BGP_SOFT_OUT_STR) + BGP_SOFT_OUT_STR + "Reset message statistics\n") { char *vrf = NULL; @@ -9509,7 +9510,7 @@ DEFUN (clear_ip_bgp_all, clr_sort = clear_external; } - /* []|in [prefix-filter]|out>] */ + /* []|in [prefix-filter]|out|message-stats>] */ if (argv_find(argv, argc, "soft", &idx)) { if (argv_find(argv, argc, "in", &idx) || argv_find(argv, argc, "out", &idx)) @@ -9524,6 +9525,8 @@ DEFUN (clear_ip_bgp_all, : BGP_CLEAR_SOFT_IN; } else if (argv_find(argv, argc, "out", &idx)) { clr_type = BGP_CLEAR_SOFT_OUT; + } else if (argv_find(argv, argc, "message-stats", &idx)) { + clr_type = BGP_CLEAR_MESSAGE_STATS; } else clr_type = BGP_CLEAR_SOFT_NONE; diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index b592724d27..72e7a936c6 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -7509,6 +7509,34 @@ int peer_ttl_security_hops_unset(struct peer *peer) return ret; } +static void peer_reset_message_stats(struct peer *peer) +{ + if (peer) { + atomic_store_explicit(&peer->open_in, 0, memory_order_relaxed); + atomic_store_explicit(&peer->open_out, 0, memory_order_relaxed); + atomic_store_explicit(&peer->update_in, 0, + memory_order_relaxed); + atomic_store_explicit(&peer->update_out, 0, + memory_order_relaxed); + atomic_store_explicit(&peer->keepalive_in, 0, + memory_order_relaxed); + atomic_store_explicit(&peer->keepalive_out, 0, + memory_order_relaxed); + atomic_store_explicit(&peer->notify_in, 0, + memory_order_relaxed); + atomic_store_explicit(&peer->notify_out, 0, + memory_order_relaxed); + atomic_store_explicit(&peer->refresh_in, 0, + memory_order_relaxed); + atomic_store_explicit(&peer->refresh_out, 0, + memory_order_relaxed); + atomic_store_explicit(&peer->dynamic_cap_in, 0, + memory_order_relaxed); + atomic_store_explicit(&peer->dynamic_cap_out, 0, + memory_order_relaxed); + } +} + /* * If peer clear is invoked in a loop for all peers on the BGP instance, * it may end up freeing the doppelganger, and if this was the next node @@ -7621,6 +7649,10 @@ int peer_clear_soft(struct peer *peer, afi_t afi, safi_t safi, return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED; } } + + if (stype == BGP_CLEAR_MESSAGE_STATS) + peer_reset_message_stats(peer); + return 0; } diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 57d135e781..45ccf014f8 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1905,7 +1905,8 @@ enum bgp_clear_type { BGP_CLEAR_SOFT_OUT, BGP_CLEAR_SOFT_IN, BGP_CLEAR_SOFT_BOTH, - BGP_CLEAR_SOFT_IN_ORF_PREFIX + BGP_CLEAR_SOFT_IN_ORF_PREFIX, + BGP_CLEAR_MESSAGE_STATS }; /* Macros. */ diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 0fb5fa8482..004b1723ee 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -3392,6 +3392,11 @@ The following are available in the top level *enable* mode: Clear peer using soft reconfiguration in this address-family and sub-address-family. +.. clicmd:: clear bgp [ipv4|ipv6] [unicast] PEER|\* message-stats + + Clear BGP message statistics for a specified peer or for all peers, + optionally filtered by activated address-family and sub-address-family. + The following are available in the ``router bgp`` mode: .. clicmd:: write-quanta (1-64)