summaryrefslogtreecommitdiff
path: root/bgpd/bgp_vty.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_vty.c')
-rw-r--r--bgpd/bgp_vty.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index e97b4c97..13c37b57 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -2074,6 +2074,7 @@ peer_rsclient_set_vty (struct vty *vty, const char *peer_str,
struct listnode *node, *nnode;
struct bgp_filter *pfilter;
struct bgp_filter *gfilter;
+ int locked_and_added = 0;
bgp = vty->index;
@@ -2089,15 +2090,25 @@ peer_rsclient_set_vty (struct vty *vty, const char *peer_str,
{
peer = peer_lock (peer); /* rsclient peer list reference */
listnode_add_sort (bgp->rsclient, peer);
+ locked_and_added = 1;
}
ret = peer_af_flag_set (peer, afi, safi, PEER_FLAG_RSERVER_CLIENT);
if (ret < 0)
- return bgp_vty_return (vty, ret);
+ {
+ if (locked_and_added)
+ {
+ listnode_delete (bgp->rsclient, peer);
+ peer_unlock (peer); /* rsclient peer list reference */
+ }
+
+ return bgp_vty_return (vty, ret);
+ }
peer->rib[afi][safi] = bgp_table_init (afi, safi);
peer->rib[afi][safi]->type = BGP_TABLE_RSCLIENT;
- peer->rib[afi][safi]->owner = peer;
+ /* RIB peer reference. Released when table is free'd in bgp_table_free. */
+ peer->rib[afi][safi]->owner = peer_lock (peer);
/* Check for existing 'network' and 'redistribute' routes. */
bgp_check_local_routes_rsclient (peer, afi, safi);
@@ -2190,8 +2201,9 @@ peer_rsclient_unset_vty (struct vty *vty, const char *peer_str,
if ( ! peer_rsclient_active (peer) )
{
- peer_unlock (peer); /* peer bgp rsclient reference */
+ bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_MY_RSCLIENT);
listnode_delete (bgp->rsclient, peer);
+ peer_unlock (peer); /* peer bgp rsclient reference */
}
bgp_table_finish (&peer->rib[bgp_node_afi(vty)][bgp_node_safi(vty)]);