Skip to content

Commit

Permalink
bgpd: Restarting node does not send EOR after the convergence.
Browse files Browse the repository at this point in the history
*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>
  • Loading branch information
bisdhdh committed Jan 23, 2020
1 parent d6e3c15 commit 9e3b51a
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 18 deletions.
23 changes: 18 additions & 5 deletions bgpd/bgp_fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1813,7 +1818,15 @@ static int bgp_establish(struct peer *peer)
if (status < 0)
zlog_debug("Error in updating graceful restart for %s",
get_afi_safi_str(afi,
safi, false));
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++;
}
}
}
Expand Down
27 changes: 24 additions & 3 deletions bgpd/bgp_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 */
Expand Down Expand Up @@ -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);
}
1 change: 1 addition & 0 deletions bgpd/bgp_packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
8 changes: 4 additions & 4 deletions bgpd/bgp_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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]
Expand Down
9 changes: 5 additions & 4 deletions bgpd/bgp_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,14 @@ void bgp_delete_listnode(struct bgp_node *node)
*/
if (CHECK_FLAG(node->flags, BGP_NODE_SELECT_DEFER)) {
table = bgp_node_table(node);
if (table)

if (table) {
bgp = table->bgp;
afi = table->afi;
safi = table->safi;
}
rn = bgp_node_to_rnode(node);

afi = table->afi;
safi = table->safi;

if (bgp && rn && rn->lock == 1) {
/* Delete the route from the selection pending list */
if ((node->rt_node) &&
Expand Down
21 changes: 19 additions & 2 deletions bgpd/bgp_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand All @@ -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));
Expand Down Expand Up @@ -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");
}
}

Expand Down
21 changes: 21 additions & 0 deletions bgpd/bgp_vty.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
9 changes: 9 additions & 0 deletions bgpd/bgpd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down Expand Up @@ -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 */
/*
Expand Down

0 comments on commit 9e3b51a

Please sign in to comment.