diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index caa11313976c..3959a472799e 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -562,42 +562,45 @@ void bgp_delayopen_timer(struct event *thread) } /* BGP Peer Down Cause */ -const char *const peer_down_str[] = {"", - "Router ID changed", - "Remote AS changed", - "Local AS change", - "Cluster ID changed", - "Confederation identifier changed", - "Confederation peer changed", - "RR client config change", - "RS client config change", - "Update source change", - "Address family activated", - "Admin. shutdown", - "User reset", - "BGP Notification received", - "BGP Notification send", - "Peer closed the session", - "Neighbor deleted", - "Peer-group add member", - "Peer-group delete member", - "Capability changed", - "Passive config change", - "Multihop config change", - "NSF peer closed the session", - "Intf peering v6only config change", - "BFD down received", - "Interface down", - "Neighbor address lost", - "No path to specified Neighbor", - "Waiting for Peer IPv6 LLA", - "Waiting for VRF to be initialized", - "No AFI/SAFI activated for peer", - "AS Set config change", - "Waiting for peer OPEN", - "Reached received prefix count", - "Socket Error", - "Admin. shutdown (RTT)"}; +const char *const peer_down_str[] = { + "", + "Router ID changed", + "Remote AS changed", + "Local AS change", + "Cluster ID changed", + "Confederation identifier changed", + "Confederation peer changed", + "RR client config change", + "RS client config change", + "Update source change", + "Address family activated", + "Admin. shutdown", + "User reset", + "BGP Notification received", + "BGP Notification send", + "Peer closed the session", + "Neighbor deleted", + "Peer-group add member", + "Peer-group delete member", + "Capability changed", + "Passive config change", + "Multihop config change", + "NSF peer closed the session", + "Intf peering v6only config change", + "BFD down received", + "Interface down", + "Neighbor address lost", + "No path to specified Neighbor", + "Waiting for Peer IPv6 LLA", + "Waiting for VRF to be initialized", + "No AFI/SAFI activated for peer", + "AS Set config change", + "Waiting for peer OPEN", + "Reached received prefix count", + "Socket Error", + "Admin. shutdown (RTT)", + "Suppress Fib Turned On or Off", +}; static void bgp_graceful_restart_timer_off(struct peer_connection *connection, struct peer *peer) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 9888be0a2758..90ac529f8cfb 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -410,6 +410,9 @@ void bgp_router_id_static_set(struct bgp *bgp, struct in_addr id) void bm_wait_for_fib_set(bool set) { bool send_msg = false; + struct bgp *bgp; + struct peer *peer; + struct listnode *next, *node; if (bm->wait_for_fib == set) return; @@ -428,12 +431,32 @@ void bm_wait_for_fib_set(bool set) if (send_msg && zclient) zebra_route_notify_send(ZEBRA_ROUTE_NOTIFY_REQUEST, zclient, set); + + /* + * If this is configed at a time when peers are already set + * FRR needs to reset the connection(s) as that some installs + * may have already happened in some shape fashion or form + * let's just start over + */ + for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) { + for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) { + if (!BGP_IS_VALID_STATE_FOR_NOTIF( + peer->connection->status)) + continue; + + peer->last_reset = PEER_DOWN_SUPPRESS_FIB_PENDING; + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, + BGP_NOTIFY_CEASE_CONFIG_CHANGE); + } + } } /* Set the suppress fib pending for the bgp configuration */ void bgp_suppress_fib_pending_set(struct bgp *bgp, bool set) { bool send_msg = false; + struct peer *peer; + struct listnode *node; if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW) return; @@ -465,6 +488,21 @@ void bgp_suppress_fib_pending_set(struct bgp *bgp, bool set) zebra_route_notify_send(ZEBRA_ROUTE_NOTIFY_REQUEST, zclient, set); } + + /* + * If this is configed at a time when peers are already set + * FRR needs to reset the connection as that some installs + * may have already happened in some shape fashion or form + * let's just start over + */ + for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) { + if (!BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) + continue; + + peer->last_reset = PEER_DOWN_SUPPRESS_FIB_PENDING; + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, + BGP_NOTIFY_CEASE_CONFIG_CHANGE); + } } /* BGP's cluster-id control. */ diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 9e9d1c1e1ea6..4c12872ee9e0 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1757,6 +1757,7 @@ struct peer { #define PEER_DOWN_PFX_COUNT 33U /* Reached received prefix count */ #define PEER_DOWN_SOCKET_ERROR 34U /* Some socket error happened */ #define PEER_DOWN_RTT_SHUTDOWN 35U /* Automatically shutdown due to RTT */ +#define PEER_DOWN_SUPPRESS_FIB_PENDING 36U /* Suppress fib pending changed */ /* * Remember to update peer_down_str in bgp_fsm.c when you add * a new value to the last_reset reason