forked from Mirror/frr
bgpd: Restarting node does not send EOR after the convergence.
*After a restarting router comes up and the bgp session is successfully established with the peer. If the restarting router doesn’t have any route to send, it send EOR to the peer immediately before receiving updates from its peers. *Instead the restarting router should send EOR, if the selection deferral timer is not running OR count of eor received and eor required are matches then send EOR. Signed-off-by: Biswajit Sadhu <sadhub@vmware.com>
This commit is contained in:
parent
d6e3c15b62
commit
9e3b51a7f3
|
@ -1197,15 +1197,20 @@ int bgp_stop(struct peer *peer)
|
|||
!CHECK_FLAG(peer->af_sflags[afi][safi],
|
||||
PEER_STATUS_EOR_RECEIVED)) {
|
||||
gr_info = &bgp->gr_info[afi][safi];
|
||||
if (gr_info && gr_info->eor_required)
|
||||
|
||||
if (gr_info && (gr_info->eor_required))
|
||||
gr_info->eor_required--;
|
||||
if (BGP_DEBUG(update, UPDATE_OUT))
|
||||
zlog_debug("peer %s, EOR %d",
|
||||
|
||||
if (gr_info && BGP_DEBUG(update,
|
||||
UPDATE_OUT))
|
||||
zlog_debug(
|
||||
"peer %s, EOR %d",
|
||||
peer->host,
|
||||
gr_info->eor_required);
|
||||
|
||||
/* There is no pending EOR message */
|
||||
if (gr_info->eor_required == 0) {
|
||||
if (gr_info && gr_info->eor_required
|
||||
== 0) {
|
||||
BGP_TIMER_OFF(
|
||||
gr_info->t_select_deferral);
|
||||
gr_info->eor_received = 0;
|
||||
|
@ -1814,6 +1819,14 @@ static int bgp_establish(struct peer *peer)
|
|||
zlog_debug("Error in updating graceful restart for %s",
|
||||
get_afi_safi_str(afi,
|
||||
safi, false));
|
||||
} else {
|
||||
if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(
|
||||
peer) &&
|
||||
BGP_PEER_RESTARTING_MODE(peer)
|
||||
&& bgp_flag_check(peer->bgp,
|
||||
BGP_FLAG_GR_PRESERVE_FWD))
|
||||
peer->bgp->gr_info[afi][safi]
|
||||
.eor_required++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -449,14 +449,20 @@ int bgp_generate_updgrp_packets(struct thread *thread)
|
|||
/* If EOR is disabled,
|
||||
* the message is not sent
|
||||
*/
|
||||
if (!bgp_flag_check(peer->bgp,
|
||||
BGP_FLAG_GR_DISABLE_EOR
|
||||
)) {
|
||||
if (BGP_SEND_EOR(peer->bgp,
|
||||
afi, safi)) {
|
||||
SET_FLAG(
|
||||
peer->af_sflags
|
||||
[afi][safi],
|
||||
PEER_STATUS_EOR_SEND);
|
||||
|
||||
/* Update EOR
|
||||
* send time
|
||||
*/
|
||||
peer->eor_stime
|
||||
[afi][safi] =
|
||||
monotime(NULL);
|
||||
|
||||
BGP_UPDATE_EOR_PKT(
|
||||
peer, afi,
|
||||
safi, s);
|
||||
|
@ -465,6 +471,10 @@ int bgp_generate_updgrp_packets(struct thread *thread)
|
|||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Update packet send time */
|
||||
peer->pkt_stime[afi][safi] = monotime(NULL);
|
||||
|
||||
/* Found a packet template to send, overwrite
|
||||
* packet with appropriate attributes from peer
|
||||
* and advance peer */
|
||||
|
@ -2422,3 +2432,14 @@ int bgp_process_packet(struct thread *thread)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Send EOR when routes are processed by selection deferral timer */
|
||||
void bgp_send_delayed_eor(struct bgp *bgp)
|
||||
{
|
||||
struct peer *peer;
|
||||
struct listnode *node, *nnode;
|
||||
|
||||
/* EOR message sent in bgp_write_proceed_actions */
|
||||
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
|
||||
bgp_write_proceed_actions(peer);
|
||||
}
|
||||
|
|
|
@ -81,4 +81,5 @@ extern int bgp_packet_set_size(struct stream *s);
|
|||
extern int bgp_generate_updgrp_packets(struct thread *);
|
||||
extern int bgp_process_packet(struct thread *);
|
||||
|
||||
extern void bgp_send_delayed_eor(struct bgp *bgp);
|
||||
#endif /* _QUAGGA_BGP_PACKET_H */
|
||||
|
|
|
@ -2736,7 +2736,6 @@ int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
|
|||
|
||||
/* Process the route list */
|
||||
node = listhead(bgp->gr_info[afi][safi].route_list);
|
||||
node = listhead(bgp->gr_info[afi][safi].route_list);
|
||||
while (node) {
|
||||
rn = listgetdata(node);
|
||||
nnode = node->next;
|
||||
|
@ -2753,8 +2752,11 @@ int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
|
|||
node = nnode;
|
||||
}
|
||||
|
||||
if (list_isempty(bgp->gr_info[afi][safi].route_list))
|
||||
/* Send EOR message when all routes are processed */
|
||||
if (list_isempty(bgp->gr_info[afi][safi].route_list)) {
|
||||
bgp_send_delayed_eor(bgp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
|
||||
if (thread_info == NULL) {
|
||||
|
@ -3055,8 +3057,6 @@ void bgp_rib_remove(struct bgp_node *rn, struct bgp_path_info *pi,
|
|||
if (delete_route) {
|
||||
if (CHECK_FLAG(rn->flags, BGP_NODE_SELECT_DEFER)) {
|
||||
UNSET_FLAG(rn->flags, BGP_NODE_SELECT_DEFER);
|
||||
UNSET_FLAG(rn->flags,
|
||||
BGP_NODE_PROCESS_SCHEDULED);
|
||||
bgp = pi->peer->bgp;
|
||||
if ((rn->rt_node) &&
|
||||
(bgp->gr_info[afi][safi]
|
||||
|
|
|
@ -141,12 +141,13 @@ void bgp_delete_listnode(struct bgp_node *node)
|
|||
*/
|
||||
if (CHECK_FLAG(node->flags, BGP_NODE_SELECT_DEFER)) {
|
||||
table = bgp_node_table(node);
|
||||
if (table)
|
||||
bgp = table->bgp;
|
||||
rn = bgp_node_to_rnode(node);
|
||||
|
||||
if (table) {
|
||||
bgp = table->bgp;
|
||||
afi = table->afi;
|
||||
safi = table->safi;
|
||||
}
|
||||
rn = bgp_node_to_rnode(node);
|
||||
|
||||
if (bgp && rn && rn->lock == 1) {
|
||||
/* Delete the route from the selection pending list */
|
||||
|
|
|
@ -9474,6 +9474,7 @@ static void bgp_show_neighbor_graceful_restart_capability_per_afi_safi(
|
|||
json_object *json_afi_safi = NULL;
|
||||
json_object *json_timer = NULL;
|
||||
json_object *json_endofrib_status = NULL;
|
||||
bool eor_flag = false;
|
||||
|
||||
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
|
||||
for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN; safi++) {
|
||||
|
@ -9490,6 +9491,12 @@ static void bgp_show_neighbor_graceful_restart_capability_per_afi_safi(
|
|||
json_object_new_object();
|
||||
}
|
||||
|
||||
if (peer->eor_stime[afi][safi] >=
|
||||
peer->pkt_stime[afi][safi])
|
||||
eor_flag = true;
|
||||
else
|
||||
eor_flag = false;
|
||||
|
||||
if (!use_json) {
|
||||
vty_out(vty, " %s :\n",
|
||||
get_afi_safi_str(afi, safi, false));
|
||||
|
@ -9555,22 +9562,32 @@ static void bgp_show_neighbor_graceful_restart_capability_per_afi_safi(
|
|||
|
||||
if (CHECK_FLAG(peer->af_sflags[afi][safi],
|
||||
PEER_STATUS_EOR_SEND)) {
|
||||
|
||||
if (use_json) {
|
||||
json_object_boolean_true_add(
|
||||
json_endofrib_status,
|
||||
"endOfRibSend");
|
||||
|
||||
PRINT_EOR_JSON(eor_flag);
|
||||
} else {
|
||||
vty_out(vty, "Yes\n");
|
||||
}
|
||||
vty_out(vty,
|
||||
" EoRSentAfterUpdate : ");
|
||||
|
||||
PRINT_EOR(eor_flag);
|
||||
}
|
||||
} else {
|
||||
if (use_json) {
|
||||
json_object_boolean_false_add(
|
||||
json_endofrib_status,
|
||||
"endOfRibSend");
|
||||
json_object_boolean_false_add(
|
||||
json_endofrib_status,
|
||||
"endOfRibSentAfterUpdate");
|
||||
} else {
|
||||
vty_out(vty, "No\n");
|
||||
vty_out(vty,
|
||||
" EoRSentAfterUpdate : ");
|
||||
vty_out(vty, "No\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,27 @@ struct bgp;
|
|||
vty, p, use_json, json); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define PRINT_EOR(_eor_flag) \
|
||||
do { \
|
||||
if (eor_flag) \
|
||||
vty_out(vty, "Yes\n"); \
|
||||
else \
|
||||
vty_out(vty, "No\n"); \
|
||||
} while (0)
|
||||
|
||||
#define PRINT_EOR_JSON(_eor_flag) \
|
||||
do { \
|
||||
if (eor_flag) \
|
||||
json_object_boolean_true_add( \
|
||||
json_endofrib_status, \
|
||||
"endOfRibSentAfterUpdate"); \
|
||||
else \
|
||||
json_object_boolean_false_add( \
|
||||
json_endofrib_status, \
|
||||
"endOfRibSentAfterUpdate"); \
|
||||
} while (0)
|
||||
|
||||
extern void bgp_vty_init(void);
|
||||
extern const char *get_afi_safi_str(afi_t afi, safi_t safi, bool for_json);
|
||||
extern int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name,
|
||||
|
|
|
@ -232,6 +232,11 @@ enum bgp_instance_type {
|
|||
BGP_INSTANCE_TYPE_VIEW
|
||||
};
|
||||
|
||||
#define BGP_SEND_EOR(bgp, afi, safi) \
|
||||
(!bgp_flag_check(bgp, BGP_FLAG_GR_DISABLE_EOR) && \
|
||||
((bgp->gr_info[afi][safi].t_select_deferral == NULL) || \
|
||||
(bgp->gr_info[afi][safi].eor_required == \
|
||||
bgp->gr_info[afi][safi].eor_received)))
|
||||
|
||||
/* BGP GR Global ds */
|
||||
|
||||
|
@ -1061,6 +1066,10 @@ struct peer {
|
|||
|
||||
/* NSF mode (graceful restart) */
|
||||
uint8_t nsf[AFI_MAX][SAFI_MAX];
|
||||
/* EOR Send time */
|
||||
time_t eor_stime[AFI_MAX][SAFI_MAX];
|
||||
/* Last update packet sent time */
|
||||
time_t pkt_stime[AFI_MAX][SAFI_MAX];
|
||||
|
||||
/* Peer Per AF flags */
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue