From dc91261567a46848eb9f3634cecce4fe1c08e0a2 Mon Sep 17 00:00:00 2001 From: Don Slice Date: Mon, 12 Aug 2019 19:02:39 +0000 Subject: [PATCH] bgpd: make clear bgp * clear all peers in all afi/safis Problem reported that "clear bgp *" only cleared ipv6 peers. Changed the logic to clear all afi/safis of all peers in that case. Also improved the operation of clearing individual afi/safi using soft/in/out to do the right thing. Ticket: CM-25887 Signed-off-by: Don Slice --- bgpd/bgp_vty.c | 96 ++++++++++++++++++++++++++++++------------------ doc/user/bgp.rst | 30 ++++++++++++--- lib/zebra.h | 1 + 3 files changed, 87 insertions(+), 40 deletions(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 50a439f00f..4447c2ccf8 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -596,12 +596,61 @@ static void bgp_clear_vty_error(struct vty *vty, struct peer *peer, afi_t afi, } } +static int bgp_peer_clear(struct peer *peer, afi_t afi, safi_t safi, + struct listnode *nnode, enum bgp_clear_type stype) +{ + int ret = 0; + + /* if afi/.safi not specified, spin thru all of them */ + if ((afi == AFI_UNSPEC) && (safi == SAFI_UNSPEC)) { + afi_t tmp_afi; + safi_t tmp_safi; + + FOREACH_AFI_SAFI (tmp_afi, tmp_safi) { + if (!peer->afc[tmp_afi][tmp_safi]) + continue; + + if (stype == BGP_CLEAR_SOFT_NONE) + ret = peer_clear(peer, &nnode); + else + ret = peer_clear_soft(peer, tmp_afi, tmp_safi, + stype); + } + /* if afi specified and safi not, spin thru safis on this afi */ + } else if (safi == SAFI_UNSPEC) { + safi_t tmp_safi; + + for (tmp_safi = SAFI_UNICAST; + tmp_safi < SAFI_MAX; tmp_safi++) { + if (!peer->afc[afi][tmp_safi]) + continue; + + if (stype == BGP_CLEAR_SOFT_NONE) + ret = peer_clear(peer, &nnode); + else + ret = peer_clear_soft(peer, afi, + tmp_safi, stype); + } + /* both afi/safi specified, let the caller know if not defined */ + } else { + if (!peer->afc[afi][safi]) + return 1; + + if (stype == BGP_CLEAR_SOFT_NONE) + ret = peer_clear(peer, &nnode); + else + ret = peer_clear_soft(peer, afi, safi, stype); + } + + return ret; +} + /* `clear ip bgp' functions. */ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, enum clear_sort sort, enum bgp_clear_type stype, const char *arg) { - int ret; + int ret = 0; bool found = false; struct peer *peer; struct listnode *node, *nnode; @@ -614,13 +663,8 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, */ if (sort == clear_all) { for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - if (!peer->afc[afi][safi]) - continue; - - if (stype == BGP_CLEAR_SOFT_NONE) - ret = peer_clear(peer, &nnode); - else - ret = peer_clear_soft(peer, afi, safi, stype); + ret = bgp_peer_clear(peer, afi, safi, nnode, + stype); if (ret < 0) bgp_clear_vty_error(vty, peer, afi, safi, ret); @@ -660,12 +704,11 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, } } - if (!peer->afc[afi][safi]) + ret = bgp_peer_clear(peer, afi, safi, NULL, stype); + + /* if afi/safi not defined for this peer, let caller know */ + if (ret == 1) ret = BGP_ERR_AF_UNCONFIGURED; - else if (stype == BGP_CLEAR_SOFT_NONE) - ret = peer_clear(peer, NULL); - else - ret = peer_clear_soft(peer, afi, safi, stype); if (ret < 0) bgp_clear_vty_error(vty, peer, afi, safi, ret); @@ -684,13 +727,7 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, } for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) { - if (!peer->afc[afi][safi]) - continue; - - if (stype == BGP_CLEAR_SOFT_NONE) - ret = peer_clear(peer, NULL); - else - ret = peer_clear_soft(peer, afi, safi, stype); + ret = bgp_peer_clear(peer, afi, safi, nnode, stype); if (ret < 0) bgp_clear_vty_error(vty, peer, afi, safi, ret); @@ -712,13 +749,7 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, if (peer->sort == BGP_PEER_IBGP) continue; - if (!peer->afc[afi][safi]) - continue; - - if (stype == BGP_CLEAR_SOFT_NONE) - ret = peer_clear(peer, &nnode); - else - ret = peer_clear_soft(peer, afi, safi, stype); + ret = bgp_peer_clear(peer, afi, safi, nnode, stype); if (ret < 0) bgp_clear_vty_error(vty, peer, afi, safi, ret); @@ -742,12 +773,7 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, if (peer->as != as) continue; - if (!peer->afc[afi][safi]) - ret = BGP_ERR_AF_UNCONFIGURED; - else if (stype == BGP_CLEAR_SOFT_NONE) - ret = peer_clear(peer, &nnode); - else - ret = peer_clear_soft(peer, afi, safi, stype); + ret = bgp_peer_clear(peer, afi, safi, nnode, stype); if (ret < 0) bgp_clear_vty_error(vty, peer, afi, safi, ret); @@ -7238,8 +7264,8 @@ DEFUN (clear_ip_bgp_all, { char *vrf = NULL; - afi_t afi = AFI_IP6; - safi_t safi = SAFI_UNICAST; + afi_t afi = AFI_UNSPEC; + safi_t safi = SAFI_UNSPEC; enum clear_sort clr_sort = clear_peer; enum bgp_clear_type clr_type; char *clr_arg = NULL; diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index f2b1328075..c329ab6d9f 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -2138,20 +2138,40 @@ Dumping Messages and Routing Tables Other BGP Commands ------------------ +.. index:: clear bgp \* +.. clicmd:: clear bgp \* + + Clear all peers. + .. index:: clear bgp ipv4|ipv6 \* .. clicmd:: clear bgp ipv4|ipv6 \* - Clear all address family peers. + Clear all peers with this address-family activated. + +.. index:: clear bgp ipv4|ipv6 unicast \* +.. clicmd:: clear bgp ipv4|ipv6 unicast \* + + Clear all peers with this address-family and sub-address-family activated. .. index:: clear bgp ipv4|ipv6 PEER .. clicmd:: clear bgp ipv4|ipv6 PEER - Clear peers which have addresses of X.X.X.X + Clear peers with address of X.X.X.X and this address-family activated. + +.. index:: clear bgp ipv4|ipv6 unicast PEER +.. clicmd:: clear bgp ipv4|ipv6 unicast PEER + + Clear peer with address of X.X.X.X and this address-family and sub-address-family activated. + +.. index:: clear bgp ipv4|ipv6 PEER soft|in|out +.. clicmd:: clear bgp ipv4|ipv6 PEER soft|in|out + + Clear peer using soft reconfiguration in this address-family. -.. index:: clear bgp ipv4|ipv6 PEER soft in -.. clicmd:: clear bgp ipv4|ipv6 PEER soft in +.. index:: clear bgp ipv4|ipv6 unicast PEER soft|in|out +.. clicmd:: clear bgp ipv4|ipv6 unicast PEER soft|in|out - Clear peer using soft reconfiguration. + Clear peer using soft reconfiguration in this address-family and sub-address-family. .. _bgp-displaying-bgp-information: diff --git a/lib/zebra.h b/lib/zebra.h index 352887eca8..789a93a3c4 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -360,6 +360,7 @@ typedef enum { /* Subsequent Address Family Identifier. */ typedef enum { + SAFI_UNSPEC = 0, SAFI_UNICAST = 1, SAFI_MULTICAST = 2, SAFI_MPLS_VPN = 3, -- 2.39.5