mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 15:58:18 +00:00
bgpd: Respect AFI/SAFI when hard-clearing a peer
The current implementation does not respect the AFI+SAFI combination of a peer when executing a non-soft (hard) clear. An example would be the command `clear bgp ipv4 unicast *`, which will clear all BGP peers, even those that do not have IPv4-Unicast activated. This commit fixes that behavior by applying the same rules to both soft and hard clear commands, so that peers without a matching AFI+SAFI combination will be no longer modified. Additionally, this commit adds warning messages to all `clear bgp [<afi>] [<safi>] <target>` commands when no matching peers with the given AFI+SAFI combination could be found. Both existing and new warning messages have been extended to also mention the AFI+SAFI combination that is missing, which is more helpful to the user than a generic expression 'No peer configured'. Signed-off-by: Pascal Mathis <mail@pascalmathis.com>
This commit is contained in:
parent
62362d70aa
commit
3ae8bfa5d8
@ -553,39 +553,46 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
|
||||
const char *arg)
|
||||
{
|
||||
int ret;
|
||||
bool found = false;
|
||||
struct peer *peer;
|
||||
struct listnode *node, *nnode;
|
||||
|
||||
/* Clear all neighbors. */
|
||||
/*
|
||||
* Pass along pointer to next node to peer_clear() when walking all
|
||||
* nodes
|
||||
* on the BGP instance as that may get freed if it is a doppelganger
|
||||
* nodes on the BGP instance as that may get freed if it is a
|
||||
* doppelganger
|
||||
*/
|
||||
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 if (peer->afc[afi][safi])
|
||||
ret = peer_clear_soft(peer, afi, safi, stype);
|
||||
else
|
||||
ret = 0;
|
||||
ret = peer_clear_soft(peer, afi, safi, stype);
|
||||
|
||||
if (ret < 0)
|
||||
bgp_clear_vty_error(vty, peer, afi, safi, ret);
|
||||
else
|
||||
found = true;
|
||||
}
|
||||
|
||||
/* This is to apply read-only mode on this clear. */
|
||||
if (stype == BGP_CLEAR_SOFT_NONE)
|
||||
bgp->update_delay_over = 0;
|
||||
|
||||
if (!found)
|
||||
vty_out(vty, "%%BGP: No %s peer configured",
|
||||
afi_safi_print(afi, safi));
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* Clear specified neighbors. */
|
||||
/* Clear specified neighbor. */
|
||||
if (sort == clear_peer) {
|
||||
union sockunion su;
|
||||
int ret;
|
||||
|
||||
/* Make sockunion for lookup. */
|
||||
ret = str2sockunion(arg, &su);
|
||||
@ -610,7 +617,9 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
|
||||
}
|
||||
}
|
||||
|
||||
if (stype == BGP_CLEAR_SOFT_NONE)
|
||||
if (!peer->afc[afi][safi])
|
||||
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);
|
||||
@ -621,7 +630,7 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* Clear all peer-group members. */
|
||||
/* Clear all neighbors belonging to a specific peer-group. */
|
||||
if (sort == clear_group) {
|
||||
struct peer_group *group;
|
||||
|
||||
@ -632,27 +641,37 @@ 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 (stype == BGP_CLEAR_SOFT_NONE) {
|
||||
peer_clear(peer, NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!peer->afc[afi][safi])
|
||||
continue;
|
||||
|
||||
ret = peer_clear_soft(peer, afi, safi, stype);
|
||||
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);
|
||||
else
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
vty_out(vty,
|
||||
"%%BGP: No %s peer belonging to peer-group %s is configured\n",
|
||||
afi_safi_print(afi, safi), arg);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* Clear all external (eBGP) neighbors. */
|
||||
if (sort == clear_external) {
|
||||
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
|
||||
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
|
||||
@ -660,33 +679,44 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
|
||||
|
||||
if (ret < 0)
|
||||
bgp_clear_vty_error(vty, peer, afi, safi, ret);
|
||||
else
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
vty_out(vty,
|
||||
"%%BGP: No external %s peer is configured\n",
|
||||
afi_safi_print(afi, safi));
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* Clear all neighbors belonging to a specific AS. */
|
||||
if (sort == clear_as) {
|
||||
as_t as;
|
||||
int find = 0;
|
||||
|
||||
as = strtoul(arg, NULL, 10);
|
||||
as_t as = strtoul(arg, NULL, 10);
|
||||
|
||||
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
|
||||
if (peer->as != as)
|
||||
continue;
|
||||
|
||||
find = 1;
|
||||
if (stype == BGP_CLEAR_SOFT_NONE)
|
||||
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);
|
||||
|
||||
if (ret < 0)
|
||||
bgp_clear_vty_error(vty, peer, afi, safi, ret);
|
||||
else
|
||||
found = true;
|
||||
}
|
||||
if (!find)
|
||||
|
||||
if (!found)
|
||||
vty_out(vty,
|
||||
"%%BGP: No peer is configured with AS %s\n",
|
||||
arg);
|
||||
"%%BGP: No %s peer is configured with AS %s\n",
|
||||
afi_safi_print(afi, safi), arg);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user