]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: make clear bgp * clear all peers in all afi/safis
authorDon Slice <dslice@cumulusnetworks.com>
Mon, 12 Aug 2019 19:02:39 +0000 (19:02 +0000)
committerDon Slice <dslice@cumulusnetworks.com>
Tue, 20 Aug 2019 13:50:58 +0000 (13:50 +0000)
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 <dslice@cumulusnetworks.com>
bgpd/bgp_vty.c
doc/user/bgp.rst
lib/zebra.h

index 50a439f00f9dcc5b8209c35b0ee44d8850a1333a..4447c2ccf8569b19d0359006021a9837f7fb2593 100644 (file)
@@ -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;
index f2b132807529f980f3fa35099355c144207342a3..c329ab6d9fb98d3fbd9875d3856ce9fb5bab4a9f 100644 (file)
@@ -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:
index 352887eca8c78212b7e6d7a96b97559f849994a8..789a93a3c475eab9e7e4666c6eaaa0ba960a7ef2 100644 (file)
@@ -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,