unsigned long conf_bgp_debug_flowspec;
unsigned long conf_bgp_debug_labelpool;
unsigned long conf_bgp_debug_pbr;
+unsigned long conf_bgp_debug_graceful_restart;
unsigned long term_bgp_debug_as4;
unsigned long term_bgp_debug_neighbor_events;
unsigned long term_bgp_debug_flowspec;
unsigned long term_bgp_debug_labelpool;
unsigned long term_bgp_debug_pbr;
+unsigned long term_bgp_debug_graceful_restart;
struct list *bgp_debug_neighbor_events_peers = NULL;
struct list *bgp_debug_keepalive_peers = NULL;
return CMD_SUCCESS;
}
+DEFUN (debug_bgp_graceful_restart,
+ debug_bgp_graceful_restart_cmd,
+ "debug bgp graceful-restart",
+ DEBUG_STR
+ BGP_STR
+ GR_DEBUG)
+{
+ if (vty->node == CONFIG_NODE) {
+ DEBUG_ON(graceful_restart, GRACEFUL_RESTART);
+ } else {
+ TERM_DEBUG_ON(graceful_restart, GRACEFUL_RESTART);
+ vty_out(vty, "BGP Graceful Restart debugging is on\n");
+ }
+ return CMD_SUCCESS;
+}
+
+
DEFUN (debug_bgp_zebra_prefix,
debug_bgp_zebra_prefix_cmd,
"debug bgp zebra prefix <A.B.C.D/M|X:X::X:X/M>",
return CMD_SUCCESS;
}
+DEFUN (no_debug_bgp_graceful_restart,
+ no_debug_bgp_graceful_restart_cmd,
+ "no debug bgp graceful-restart",
+ DEBUG_STR
+ BGP_STR
+ GR_DEBUG
+ NO_STR)
+{
+ if (vty->node == CONFIG_NODE) {
+ DEBUG_OFF(graceful_restart, GRACEFUL_RESTART);
+ } else {
+ TERM_DEBUG_OFF(graceful_restart, GRACEFUL_RESTART);
+ vty_out(vty, "BGP Graceful Restart debugging is off\n");
+ }
+ return CMD_SUCCESS;
+}
+
DEFUN (no_debug_bgp_zebra_prefix,
no_debug_bgp_zebra_prefix_cmd,
"no debug bgp zebra prefix <A.B.C.D/M|X:X::X:X/M>",
TERM_DEBUG_OFF(labelpool, LABELPOOL);
TERM_DEBUG_OFF(pbr, PBR);
TERM_DEBUG_OFF(pbr, PBR_ERROR);
+ TERM_DEBUG_OFF(graceful_restart, GRACEFUL_RESTART);
+
vty_out(vty, "All possible debugging has been turned off\n");
return CMD_SUCCESS;
if (BGP_DEBUG(zebra, ZEBRA))
bgp_debug_list_print(vty, " BGP zebra debugging is on",
- bgp_debug_zebra_prefixes);
+ bgp_debug_zebra_prefixes);
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ vty_out(vty,
+ " BGP graceful-restart debugging is on");
if (BGP_DEBUG(allow_martians, ALLOW_MARTIANS))
vty_out(vty, " BGP allow martian next hop debugging is on\n");
vty_out(vty, "debug bgp pbr error\n");
write++;
}
+
+ if (CONF_BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) {
+ vty_out(vty, "debug bgp graceful-restart\n");
+ write++;
+ }
return write;
}
install_element(ENABLE_NODE, &debug_bgp_bestpath_prefix_cmd);
install_element(CONFIG_NODE, &debug_bgp_bestpath_prefix_cmd);
+ install_element(ENABLE_NODE, &debug_bgp_graceful_restart_cmd);
+ install_element(CONFIG_NODE, &debug_bgp_graceful_restart_cmd);
+
/* debug bgp updates (in|out) */
install_element(ENABLE_NODE, &debug_bgp_update_direct_cmd);
install_element(CONFIG_NODE, &debug_bgp_update_direct_cmd);
install_element(ENABLE_NODE, &no_debug_bgp_bestpath_prefix_cmd);
install_element(CONFIG_NODE, &no_debug_bgp_bestpath_prefix_cmd);
+ install_element(ENABLE_NODE, &no_debug_bgp_graceful_restart_cmd);
+ install_element(CONFIG_NODE, &no_debug_bgp_graceful_restart_cmd);
+
install_element(ENABLE_NODE, &debug_bgp_vpn_cmd);
install_element(CONFIG_NODE, &debug_bgp_vpn_cmd);
install_element(ENABLE_NODE, &no_debug_bgp_vpn_cmd);
extern unsigned long term_bgp_debug_pbr;
extern unsigned long term_bgp_debug_graceful_restart;
-
extern struct list *bgp_debug_neighbor_events_peers;
extern struct list *bgp_debug_keepalive_peers;
extern struct list *bgp_debug_update_in_peers;
safi_t safi;
char orf_name[BUFSIZ];
int ret = 0;
+ peer->nsf_af_count = 0;
if (peer_dynamic_neighbor(peer)
&& !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
}
}
+ peer->nsf_af_count = nsf_af_count;
+
if (nsf_af_count)
SET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
else {
return ret;
}
+/* BGP GR Code */
+
+int bgp_gr_lookup_n_update_all_peer(struct bgp *bgp,
+ enum global_mode global_new_state,
+ enum global_mode global_old_state)
+{
+ struct peer *peer = {0};
+ struct listnode *node = {0};
+ struct listnode *nnode = {0};
+ enum peer_mode peer_old_state = PEER_INVALID;
+
+ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "BGP_GR:: %s ---> Peer: (%s) :",
+ __func__, peer->host);
+
+ peer_old_state = bgp_peer_gr_mode_get(peer);
+
+ if (peer_old_state == PEER_GLOBAL_INHERIT) {
+
+ /*
+ *Reset only these peers and send a
+ *new open message with the change capabilities.
+ *Considering the mode to be "global_new_state" and
+ *do all operation accordingly
+ */
+
+ switch (global_new_state) {
+
+ case GLOBAL_HELPER:
+
+ BGP_PEER_GR_HELPER_ENABLE(peer);
+ break;
+ case GLOBAL_GR:
+
+ BGP_PEER_GR_ENABLE(peer);
+ break;
+ case GLOBAL_DISABLE:
+
+ BGP_PEER_GR_DISABLE(peer);
+ break;
+ case GLOBAL_INVALID:
+
+ zlog_debug(
+ "BGP_GR:: %s :GLOBAL_INVALID",
+ __func__);
+ return BGP_ERR_GR_OPERATION_FAILED;
+ default:
+
+ zlog_debug(
+ "BGP_GR:: %s :Global unknown ERROR",
+ __func__);
+ return BGP_ERR_GR_OPERATION_FAILED;
+ }
+ }
+ }
+
+ bgp->global_gr_present_state = global_new_state;
+
+ /* debug Trace msg */
+ return BGP_GR_SUCCESS;
+}
+
+int bgp_gr_update_all(struct bgp *bgp, int global_GR_Cmd)
+{
+ enum global_mode global_new_state = GLOBAL_INVALID;
+ enum global_mode global_old_state = GLOBAL_INVALID;
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "BGP_GR::%s:START ---> global_GR_Cmd :%d:",
+ __func__, global_GR_Cmd);
+
+ global_old_state = bgp_global_gr_mode_get(bgp);
+
+ if (global_old_state != GLOBAL_INVALID) {
+
+ global_new_state =
+ bgp->GLOBAL_GR_FSM[global_old_state][global_GR_Cmd];
+ } else {
+ /* Trace msg */
+ zlog_debug("BGP_GR::%s:global_old_state == GLOBAL_INVALID",
+ __func__);
+ return BGP_ERR_GR_OPERATION_FAILED;
+ }
+
+ if (global_new_state == GLOBAL_INVALID) {
+ /* Trace msg */
+ zlog_debug(
+ "BGP_GR::%s: global_new_state == GLOBAL_INVALID",
+ __func__);
+ return BGP_ERR_GR_INVALID_CMD;
+ }
+ if (global_new_state == global_old_state) {
+ /* Trace msg */
+ zlog_debug(
+ "BGP_GR::%s : global_new_state == global_old_state",
+ __func__);
+ return BGP_GR_NO_OPERATION;
+ }
+
+ return bgp_gr_lookup_n_update_all_peer(bgp,
+ global_new_state,
+ global_old_state);
+}
+
+enum global_mode bgp_global_gr_mode_get(struct bgp *bgp)
+{
+ return bgp->global_gr_present_state;
+}
+
+enum peer_mode bgp_peer_gr_mode_get(struct peer *peer)
+{
+ return peer->peer_gr_present_state;
+}
+
+int bgp_neighbor_graceful_restart(struct peer *peer,
+ int peer_GR_Cmd)
+{
+ enum peer_mode peer_new_state = PEER_INVALID;
+ enum peer_mode peer_old_state = PEER_INVALID;
+ struct bgp_peer_gr peer_state;
+ int result = BGP_GR_FAILURE;
+
+ /*
+ * fetch peer_old_state from peer structure also
+ * fetch global_old_state from bgp structure,
+ * peer had a back pointer to bgpo struct ;
+ */
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "BGP_GR:: %s:START--->Peer: (%s) : peer_GR_Cmd :%d:",
+ __func__, peer->host, peer_GR_Cmd);
+
+ peer_old_state = bgp_peer_gr_mode_get(peer);
+
+ if (peer_old_state == PEER_INVALID) {
+ /* debug Trace msg */
+ zlog_debug(
+ "BGP_GR:: peer_old_state ==Invalid state !");
+ return BGP_ERR_GR_OPERATION_FAILED;
+ }
+
+ peer_state = peer->PEER_GR_FSM[peer_old_state][peer_GR_Cmd];
+ peer_new_state = peer_state.next_state;
+
+ if (peer_new_state == PEER_INVALID) {
+ /* debug Trace msg */
+ zlog_debug(
+ "BGP_GR:: Invalid bgp graceful restart command used !");
+ return BGP_ERR_GR_INVALID_CMD;
+ }
+
+ if (peer_new_state != peer_old_state) {
+ result = peer_state.action_fun(peer,
+ peer_old_state,
+ peer_new_state);
+ } else {
+ /* debug Trace msg */
+ zlog_debug(
+ "BGP_GR:: peer_old_state == peer_new_state !");
+ return BGP_GR_NO_OPERATION;
+ }
+
+ if (result == BGP_GR_SUCCESS) {
+
+ /* Update the mode i.e peer_new_state into the peer structure */
+ peer->peer_gr_present_state = peer_new_state;
+ /* debug Trace msg */
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug("BGP_GR:: Succesfully change the state of the peer to : %d : !",
+ peer_new_state);
+
+ return BGP_GR_SUCCESS;
+ }
+
+ return result;
+}
+
+unsigned int bgp_peer_gr_action(struct peer *peer,
+ int old_peer_state, int new_peer_state)
+{
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "BGP_GR:: %s : Move peer from old_peer_state :%d: to old_peer_state :%d: !!!!",
+ __func__, old_peer_state, new_peer_state);
+
+ int bgp_gr_global_mode = GLOBAL_INVALID;
+ unsigned int ret = BGP_GR_FAILURE;
+
+ if (old_peer_state == new_peer_state) {
+ /* Nothing to do over here as the present and old state is the same */
+ /* debug Trace msg */
+ return BGP_GR_NO_OPERATION;
+ }
+ if ((old_peer_state == PEER_INVALID) ||
+ (new_peer_state == PEER_INVALID)) {
+ /* something bad happend , print error message */
+ return BGP_ERR_GR_INVALID_CMD;
+ }
+
+ bgp_gr_global_mode = bgp_global_gr_mode_get(peer->bgp);
+
+ if ((old_peer_state == PEER_GLOBAL_INHERIT) &&
+ (new_peer_state != PEER_GLOBAL_INHERIT)) {
+
+ /* fetch the Mode running in the Global state machine
+ *from the bgp structure into a variable called
+ *bgp_gr_global_mode
+ */
+
+ /* Here we are checking if the
+ *1. peer_new_state == global_mode == helper_mode
+ *2. peer_new_state == global_mode == GR_mode
+ *3. peer_new_state == global_mode == disabled_mode
+ */
+
+ BGP_PEER_GR_GLOBAL_INHERIT_UNSET(peer);
+
+ if (new_peer_state == bgp_gr_global_mode) {
+ /*This is incremental updates i.e no tear down
+ *of the existing session
+ *as the peer is already working in the same mode.
+ */
+ /* debug Trace msg */
+ ret = BGP_GR_SUCCESS;
+ } else {
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "BGP_GR:: Peer state changed from :%d =>",
+ old_peer_state);
+
+ bgp_peer_move_to_gr_mode(peer, new_peer_state);
+
+ ret = BGP_GR_SUCCESS;
+ }
+ }
+ /* In the case below peer is going into Global inherit mode i.e.
+ * the peer would work as the mode configured at the global level
+ */
+ else if ((new_peer_state == PEER_GLOBAL_INHERIT) &&
+ (old_peer_state != PEER_GLOBAL_INHERIT)) {
+ /* Here in this case it would be destructive
+ * in all the cases except one case when,
+ * Global GR is configured Disabled
+ * and present_peer_state is not disable
+ */
+
+ BGP_PEER_GR_GLOBAL_INHERIT_SET(peer);
+
+ if (old_peer_state == bgp_gr_global_mode) {
+
+ /* This is incremental updates
+ *i.e no tear down of the existing session
+ *as the peer is already working in the same mode.
+ */
+ ret = BGP_GR_SUCCESS;
+ } else {
+ /* Destructive always */
+ /* Tear down the old session
+ * and send the new capability
+ * as per the bgp_gr_global_mode
+ */
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug("BGP_GR:: Peer state changed from :%d ==>",
+ old_peer_state);
+
+ bgp_peer_move_to_gr_mode(peer, bgp_gr_global_mode);
+
+ ret = BGP_GR_SUCCESS;
+ }
+ } else {
+ /*
+ *This else case, it include all the cases except -->
+ *(new_peer_state != Peer_Global) &&
+ *( old_peer_state != Peer_Global )
+ */
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug("BGP_GR:: Peer state changed from :%d ===>",
+ old_peer_state);
+
+ bgp_peer_move_to_gr_mode(peer, new_peer_state);
+
+ ret = BGP_GR_SUCCESS;
+ }
+
+ return ret;
+}
+
+inline void bgp_peer_move_to_gr_mode(struct peer *peer, int new_state)
+
+{
+ int bgp_global_gr_mode = bgp_global_gr_mode_get(peer->bgp);
+
+ switch (new_state) {
+
+ case PEER_HELPER:
+ BGP_PEER_GR_HELPER_ENABLE(peer);
+ break;
+
+ case PEER_GR:
+ BGP_PEER_GR_ENABLE(peer);
+ break;
+
+ case PEER_DISABLE:
+ BGP_PEER_GR_DISABLE(peer);
+ break;
+
+ case PEER_GLOBAL_INHERIT:
+ BGP_PEER_GR_GLOBAL_INHERIT_SET(peer);
+
+ if (bgp_global_gr_mode == GLOBAL_HELPER) {
+ BGP_PEER_GR_HELPER_ENABLE(peer);
+ } else if (bgp_global_gr_mode == GLOBAL_GR) {
+ BGP_PEER_GR_ENABLE(peer);
+ } else if (bgp_global_gr_mode == GLOBAL_DISABLE) {
+ BGP_PEER_GR_DISABLE(peer);
+ } else {
+ zlog_debug(
+ "BGP_GR:: Default switch inherit mode ::: SOMETHING IS WORONG !!!");
+ }
+ break;
+ default:
+ zlog_debug("BGP_GR:: Default switch mode ::: SOMETHING IS WORONG !!!");
+ break;
+ }
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug("BGP_GR:: Peer state changed --to--> : %d : !",
+ new_state);
+}
+
+void bgp_peer_gr_flags_update(struct peer *peer)
+{
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "BGP_GR:: %s called !",
+ __func__);
+ if (CHECK_FLAG(peer->peer_gr_new_status_flag,
+ PEER_GRACEFUL_RESTART_NEW_STATE_HELPER))
+ bgp_peer_flag_set(peer,
+ PEER_FLAG_GRACEFUL_RESTART_HELPER);
+ else
+ bgp_peer_flag_unset(peer,
+ PEER_FLAG_GRACEFUL_RESTART_HELPER);
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "BGP_GR:: Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_HELPER : %s : !",
+ peer->host,
+ (bgp_peer_flag_check(peer,
+ PEER_FLAG_GRACEFUL_RESTART_HELPER) ?
+ "Set" : "UnSet"));
+ if (CHECK_FLAG(peer->peer_gr_new_status_flag,
+ PEER_GRACEFUL_RESTART_NEW_STATE_RESTART))
+ bgp_peer_flag_set(peer,
+ PEER_FLAG_GRACEFUL_RESTART);
+ else
+ bgp_peer_flag_unset(peer,
+ PEER_FLAG_GRACEFUL_RESTART);
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "BGP_GR:: Peer %s Flag PEER_FLAG_GRACEFUL_RESTART : %s : !",
+ peer->host,
+ (bgp_peer_flag_check(peer,
+ PEER_FLAG_GRACEFUL_RESTART) ?
+ "Set" : "UnSet"));
+ if (CHECK_FLAG(peer->peer_gr_new_status_flag,
+ PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT))
+ bgp_peer_flag_set(peer,
+ PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT);
+ else
+ bgp_peer_flag_unset(peer,
+ PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT);
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "BGP_GR:: Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT : %s : !",
+ peer->host,
+ (bgp_peer_flag_check(peer,
+ PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT) ?
+ "Set" : "UnSet"));
+}
PEER_GRACEFUL_RESTART_NEW_STATE_HELPER);\
} while (0)
-
-
#define BGP_PEER_GR_ENABLE(peer)\
do { \
SET_FLAG( \
PEER_GRACEFUL_RESTART_NEW_STATE_HELPER);\
} while (0)
-
#define BGP_PEER_GR_DISABLE(peer)\
do { \
UNSET_FLAG( \
PEER_GRACEFUL_RESTART_NEW_STATE_HELPER);\
} while (0)
-
#define BGP_PEER_GR_GLOBAL_INHERIT_SET(peer) \
SET_FLAG(peer->peer_gr_new_status_flag, \
PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT)
-
#define BGP_PEER_GR_GLOBAL_INHERIT_UNSET(peer) \
UNSET_FLAG(peer->peer_gr_new_status_flag, \
PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT)
-
/* Prototypes. */
extern void bgp_fsm_event_update(struct peer *peer, int valid);
extern int bgp_event(struct thread *);
int bgp_gr_lookup_n_update_all_peer(struct bgp *bgp,
enum global_mode global_new_state,
enum global_mode global_old_state);
-
void bgp_peer_gr_flags_update(struct peer *peer);
-extern int bgp_peer_flag_unset(struct peer *peer, int flag_bit);
-extern int bgp_peer_flag_set(struct peer *peer, int flag_bit);
+extern void bgp_peer_flag_unset(struct peer *peer, int flag_bit);
+extern void bgp_peer_flag_set(struct peer *peer, int flag_bit);
#endif /* _QUAGGA_BGP_FSM_H */
"Address Family modifier\n" \
"Address Family modifier\n"
-
-
#define SHOW_GR_HEADER \
"Codes: GR - Graceful Restart," \
" * - Inheriting Global GR Config,\n" \
vty, p, use_json, json); \
} 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,
return peer;
}
+/* BGP GR changes */
+
+int bgp_global_gr_init(struct bgp *bgp)
+{
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug("%s called ..", __func__);
+
+ int local_GLOBAL_GR_FSM[GLOBAL_MODE][EVENT_CMD] = {
+ /* GLOBAL_HELPER Mode */
+ {
+ /*Event -> */
+ /*GLOBAL_GR_cmd*/ /*no_Global_GR_cmd*/
+ GLOBAL_GR, GLOBAL_INVALID,
+ /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
+ GLOBAL_DISABLE, GLOBAL_INVALID
+ },
+ /* GLOBAL_GR Mode */
+ {
+ /*Event -> */
+ /*GLOBAL_GR_cmd*/ /*no_Global_GR_cmd*/
+ GLOBAL_INVALID, GLOBAL_HELPER,
+ /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
+ GLOBAL_DISABLE, GLOBAL_INVALID
+ },
+ /* GLOBAL_DISABLE Mode */
+ {
+ /*Event -> */
+ /*GLOBAL_GR_cmd */ /*no_Global_GR_cmd*/
+ GLOBAL_GR, GLOBAL_INVALID,
+ /*GLOBAL_DISABLE_cmd*//*no_Global_Disable_cmd*/
+ GLOBAL_INVALID, GLOBAL_HELPER
+ },
+ /* GLOBAL_INVALID Mode */
+ {
+ /*Event -> */
+ /*GLOBAL_GR_cmd*/ /*no_Global_GR_cmd*/
+ GLOBAL_INVALID, GLOBAL_INVALID,
+ /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
+ GLOBAL_INVALID, GLOBAL_INVALID
+ }
+ };
+ memcpy(bgp->GLOBAL_GR_FSM, local_GLOBAL_GR_FSM,
+ sizeof(local_GLOBAL_GR_FSM));
+
+ bgp->global_gr_present_state = GLOBAL_HELPER;
+
+ return BGP_GR_SUCCESS;
+}
+
+int bgp_peer_gr_init(struct peer *peer)
+{
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug("%s called ..", __func__);
+
+ struct bgp_peer_gr local_Peer_GR_FSM[PEER_MODE][PEER_EVENT_CMD] = {
+ {
+ /* PEER_HELPER Mode */
+ /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
+ { PEER_GR, bgp_peer_gr_action }, {PEER_INVALID, NULL },
+ /* Event-> */ /* PEER_DISABLE_cmd */ /* NO_PEER_DISABLE_CMD */
+ {PEER_DISABLE, bgp_peer_gr_action }, {PEER_INVALID, NULL },
+ /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
+ { PEER_INVALID, NULL }, {PEER_GLOBAL_INHERIT,
+ bgp_peer_gr_action }
+ },
+ {
+ /* PEER_GR Mode */
+ /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
+ { PEER_INVALID, NULL }, { PEER_GLOBAL_INHERIT,
+ bgp_peer_gr_action },
+ /* Event-> */ /* PEER_DISABLE_cmd */ /* NO_PEER_DISABLE_CMD */
+ {PEER_DISABLE, bgp_peer_gr_action }, { PEER_INVALID, NULL },
+ /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
+ { PEER_HELPER, bgp_peer_gr_action }, { PEER_INVALID, NULL }
+ },
+ {
+ /* PEER_DISABLE Mode */
+ /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
+ { PEER_GR, bgp_peer_gr_action }, { PEER_INVALID, NULL },
+ /* Event-> */ /* PEER_DISABLE_cmd */ /* NO_PEER_DISABLE_CMD */
+ { PEER_INVALID, NULL }, { PEER_GLOBAL_INHERIT,
+ bgp_peer_gr_action },
+ /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
+ { PEER_HELPER, bgp_peer_gr_action }, { PEER_INVALID, NULL }
+ },
+ {
+ /* PEER_INVALID Mode */
+ /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
+ { PEER_INVALID, NULL }, { PEER_INVALID, NULL },
+ /* Event-> */ /* PEER_DISABLE_cmd */ /* NO_PEER_DISABLE_CMD */
+ { PEER_INVALID, NULL }, { PEER_INVALID, NULL },
+ /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
+ { PEER_INVALID, NULL }, { PEER_INVALID, NULL },
+ },
+ {
+ /* PEER_GLOBAL_INHERIT Mode */
+ /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
+ { PEER_GR, bgp_peer_gr_action }, { PEER_INVALID, NULL },
+ /* Event-> */ /* PEER_DISABLE_cmd */ /* NO_PEER_DISABLE_CMD */
+ { PEER_DISABLE, bgp_peer_gr_action}, { PEER_INVALID, NULL },
+ /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
+ { PEER_HELPER, bgp_peer_gr_action }, { PEER_INVALID, NULL }
+ }
+ };
+ memcpy(&peer->PEER_GR_FSM, local_Peer_GR_FSM,
+ sizeof(local_Peer_GR_FSM));
+ peer->peer_gr_present_state = PEER_GLOBAL_INHERIT;
+ bgp_peer_move_to_gr_mode(peer, PEER_GLOBAL_INHERIT);
+
+ return BGP_GR_SUCCESS;
+}
/* Allocate new peer object, implicitely locked. */
struct peer *peer_new(struct bgp *bgp)
SET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
+ /* Initialize per peer bgp GR FSM */
+ bgp_peer_gr_init(peer);
+
/* Create buffers. */
peer->ibuf = stream_fifo_new();
peer->obuf = stream_fifo_new();
else if (!active && peer_active(peer))
bgp_timer_set(peer);
+ bgp_peer_gr_flags_update(peer);
return peer;
}
bgp_evpn_init(bgp);
bgp_pbr_init(bgp);
+
+ /*initilize global GR FSM */
+ bgp_global_gr_init(bgp);
return bgp;
}
return peer;
}
+
+/* BGP peer flag manipulation. */
+void bgp_peer_flag_set(struct peer *peer, int flag)
+{
+ SET_FLAG(peer->flags, flag);
+}
+
+void bgp_peer_flag_unset(struct peer *peer, int flag)
+{
+ UNSET_FLAG(peer->flags, flag);
+}
+
+int bgp_peer_flag_check(struct peer *peer, int flag)
+{
+ return CHECK_FLAG(peer->flags, flag);
+}
+
+void bgp_gr_apply_running_config(void)
+{
+ struct peer *peer = NULL;
+ struct bgp *bgp = NULL;
+ struct listnode *node, *nnode;
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "BGP_GR:: %s called !",
+ __func__);
+
+ for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
+ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
+ bgp_peer_gr_flags_update(peer);
+}
#define GLOBAL_MODE 4
#define EVENT_CMD 4
-
/* Graceful restart selection deferral timer info */
struct graceful_restart_info {
/* Count of EOR message expected */
struct thread *t_route_select;
};
-
enum global_mode {
GLOBAL_HELPER = 0, /* This is the default mode */
GLOBAL_GR,
#define BGP_GR_SUCCESS 0
#define BGP_GR_FAILURE 1
-
/* BGP instance structure. */
struct bgp {
/* AS number of this BGP instance. */
};
/* BGP GR per peer ds */
-
#define PEER_MODE 5
#define PEER_EVENT_CMD 6
uint8_t peer_gr_new_status_flag;
#define PEER_GRACEFUL_RESTART_NEW_STATE_HELPER (1 << 0)
#define PEER_GRACEFUL_RESTART_NEW_STATE_RESTART (1 << 1)
-#define PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT (1 << 2)
+#define PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT (1 << 2)
/* outgoing message sent in CEASE_ADMIN_SHUTDOWN notify */
char *tx_shutdown_message;
#define PEER_FLAG_DEFAULT_ORIGINATE (1 << 9) /* default-originate */
#define PEER_FLAG_REMOVE_PRIVATE_AS (1 << 10) /* remove-private-as */
#define PEER_FLAG_ALLOWAS_IN (1 << 11) /* set allowas-in */
-/* orf capability send-mode */
-#define PEER_FLAG_ORF_PREFIX_SM (1 << 12)
+#define PEER_FLAG_ORF_PREFIX_SM (1 << 12) /* orf capability send-mode */
#define PEER_FLAG_ORF_PREFIX_RM (1 << 13) /* orf capability receive-mode */
#define PEER_FLAG_MAX_PREFIX (1 << 14) /* maximum prefix */
#define PEER_FLAG_MAX_PREFIX_WARNING (1 << 15) /* maximum prefix warning-only */
#define BGP_ERR_PEER_SAFI_CONFLICT -35
/* BGP GR ERRORS */
-
#define BGP_ERR_GR_INVALID_CMD -36
#define BGP_ERR_GR_OPERATION_FAILED -37
#define BGP_GR_NO_OPERATION -38
void bgp_gr_apply_running_config(void);
/* BGP GR */
-
-int bgp_peer_flag_set(struct peer *peer, int flag_bit);
-int bgp_peer_flag_unset(struct peer *peer, int flag_bit);
+void bgp_peer_flag_set(struct peer *peer, int flag_bit);
+void bgp_peer_flag_unset(struct peer *peer, int flag_bit);
int bgp_peer_flag_check(struct peer *peer, int flag_bit);
int bgp_global_gr_init(struct bgp *bgp);
int bgp_peer_gr_init(struct peer *peer);
"<zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd|pbrd|fabricd|pimd|staticd|sharpd|vrrpd|ldpd>"
/* Graceful Restart cli help strings */
-
#define GR_CMD "Global Graceful Restart command\n"
#define NO_GR_CMD "Undo Global Graceful Restart command\n"
#define GR "Global Graceful Restart - GR Mode\n"
#define GR_NEIGHBOR_HELPER_CMD "Graceful Restart Helper command for a neighbor\n"
#define NO_GR_NEIGHBOR_HELPER_CMD "Undo Graceful Restart Helper command for a neighbor\n"
-
/* Prototypes. */
extern void install_node(struct cmd_node *node, int (*)(struct vty *));
extern void install_default(enum node_type);