mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 13:33:15 +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)
|
const char *arg)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
bool found = false;
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
/* Clear all neighbors. */
|
/* Clear all neighbors. */
|
||||||
/*
|
/*
|
||||||
* Pass along pointer to next node to peer_clear() when walking all
|
* Pass along pointer to next node to peer_clear() when walking all
|
||||||
* nodes
|
* nodes on the BGP instance as that may get freed if it is a
|
||||||
* on the BGP instance as that may get freed if it is a doppelganger
|
* doppelganger
|
||||||
*/
|
*/
|
||||||
if (sort == clear_all) {
|
if (sort == clear_all) {
|
||||||
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
|
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
|
||||||
|
if (!peer->afc[afi][safi])
|
||||||
|
continue;
|
||||||
|
|
||||||
if (stype == BGP_CLEAR_SOFT_NONE)
|
if (stype == BGP_CLEAR_SOFT_NONE)
|
||||||
ret = peer_clear(peer, &nnode);
|
ret = peer_clear(peer, &nnode);
|
||||||
else if (peer->afc[afi][safi])
|
|
||||||
ret = peer_clear_soft(peer, afi, safi, stype);
|
|
||||||
else
|
else
|
||||||
ret = 0;
|
ret = peer_clear_soft(peer, afi, safi, stype);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
bgp_clear_vty_error(vty, peer, afi, safi, ret);
|
bgp_clear_vty_error(vty, peer, afi, safi, ret);
|
||||||
|
else
|
||||||
|
found = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is to apply read-only mode on this clear. */
|
/* This is to apply read-only mode on this clear. */
|
||||||
if (stype == BGP_CLEAR_SOFT_NONE)
|
if (stype == BGP_CLEAR_SOFT_NONE)
|
||||||
bgp->update_delay_over = 0;
|
bgp->update_delay_over = 0;
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
vty_out(vty, "%%BGP: No %s peer configured",
|
||||||
|
afi_safi_print(afi, safi));
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear specified neighbors. */
|
/* Clear specified neighbor. */
|
||||||
if (sort == clear_peer) {
|
if (sort == clear_peer) {
|
||||||
union sockunion su;
|
union sockunion su;
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Make sockunion for lookup. */
|
/* Make sockunion for lookup. */
|
||||||
ret = str2sockunion(arg, &su);
|
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);
|
ret = peer_clear(peer, NULL);
|
||||||
else
|
else
|
||||||
ret = peer_clear_soft(peer, afi, safi, stype);
|
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;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear all peer-group members. */
|
/* Clear all neighbors belonging to a specific peer-group. */
|
||||||
if (sort == clear_group) {
|
if (sort == clear_group) {
|
||||||
struct peer_group *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)) {
|
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])
|
if (!peer->afc[afi][safi])
|
||||||
continue;
|
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)
|
if (ret < 0)
|
||||||
bgp_clear_vty_error(vty, peer, afi, safi, ret);
|
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;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear all external (eBGP) neighbors. */
|
||||||
if (sort == clear_external) {
|
if (sort == clear_external) {
|
||||||
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
|
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
|
||||||
if (peer->sort == BGP_PEER_IBGP)
|
if (peer->sort == BGP_PEER_IBGP)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!peer->afc[afi][safi])
|
||||||
|
continue;
|
||||||
|
|
||||||
if (stype == BGP_CLEAR_SOFT_NONE)
|
if (stype == BGP_CLEAR_SOFT_NONE)
|
||||||
ret = peer_clear(peer, &nnode);
|
ret = peer_clear(peer, &nnode);
|
||||||
else
|
else
|
||||||
@ -660,33 +679,44 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
|
|||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
bgp_clear_vty_error(vty, peer, afi, safi, ret);
|
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;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear all neighbors belonging to a specific AS. */
|
||||||
if (sort == clear_as) {
|
if (sort == clear_as) {
|
||||||
as_t as;
|
as_t as = strtoul(arg, NULL, 10);
|
||||||
int find = 0;
|
|
||||||
|
|
||||||
as = strtoul(arg, NULL, 10);
|
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
|
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
|
||||||
if (peer->as != as)
|
if (peer->as != as)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
find = 1;
|
if (!peer->afc[afi][safi])
|
||||||
if (stype == BGP_CLEAR_SOFT_NONE)
|
ret = BGP_ERR_AF_UNCONFIGURED;
|
||||||
|
else if (stype == BGP_CLEAR_SOFT_NONE)
|
||||||
ret = peer_clear(peer, &nnode);
|
ret = peer_clear(peer, &nnode);
|
||||||
else
|
else
|
||||||
ret = peer_clear_soft(peer, afi, safi, stype);
|
ret = peer_clear_soft(peer, afi, safi, stype);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
bgp_clear_vty_error(vty, peer, afi, safi, ret);
|
bgp_clear_vty_error(vty, peer, afi, safi, ret);
|
||||||
|
else
|
||||||
|
found = true;
|
||||||
}
|
}
|
||||||
if (!find)
|
|
||||||
|
if (!found)
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
"%%BGP: No peer is configured with AS %s\n",
|
"%%BGP: No %s peer is configured with AS %s\n",
|
||||||
arg);
|
afi_safi_print(afi, safi), arg);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user