forked from Mirror/frr
bgpd: Adding BGP GR Global & Per Neighbour FSM changes
* Added FSM for peer and global configuration for graceful restart * Added debug option BGP_GRACEFUL_RESTART for logs specific to graceful restart processing Signed-off-by: Biswajit Sadhu <sadhub@vmware.com>
This commit is contained in:
parent
b0965c44e9
commit
794b37d521
|
@ -63,6 +63,7 @@ unsigned long conf_bgp_debug_vpn;
|
|||
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;
|
||||
|
@ -80,6 +81,7 @@ unsigned long term_bgp_debug_vpn;
|
|||
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;
|
||||
|
@ -1644,6 +1646,23 @@ DEFUN (debug_bgp_zebra,
|
|||
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>",
|
||||
|
@ -1702,6 +1721,23 @@ DEFUN (no_debug_bgp_zebra,
|
|||
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>",
|
||||
|
@ -2039,6 +2075,8 @@ DEFUN (no_debug_bgp,
|
|||
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;
|
||||
|
@ -2094,7 +2132,11 @@ DEFUN_NOSH (show_debugging_bgp,
|
|||
|
||||
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");
|
||||
|
@ -2229,6 +2271,11 @@ static int bgp_config_write_debug(struct vty *vty)
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -2262,6 +2309,9 @@ void bgp_debug_init(void)
|
|||
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);
|
||||
|
@ -2327,6 +2377,9 @@ void bgp_debug_init(void)
|
|||
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);
|
||||
|
|
|
@ -94,7 +94,6 @@ extern unsigned long term_bgp_debug_labelpool;
|
|||
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;
|
||||
|
|
387
bgpd/bgp_fsm.c
387
bgpd/bgp_fsm.c
|
@ -1076,6 +1076,7 @@ int bgp_stop(struct peer *peer)
|
|||
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))) {
|
||||
|
@ -1647,6 +1648,8 @@ static int bgp_establish(struct peer *peer)
|
|||
}
|
||||
}
|
||||
|
||||
peer->nsf_af_count = nsf_af_count;
|
||||
|
||||
if (nsf_af_count)
|
||||
SET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
|
||||
else {
|
||||
|
@ -2063,3 +2066,387 @@ int bgp_event_update(struct peer *peer, int event)
|
|||
|
||||
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"));
|
||||
}
|
||||
|
|
|
@ -66,8 +66,6 @@
|
|||
PEER_GRACEFUL_RESTART_NEW_STATE_HELPER);\
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
#define BGP_PEER_GR_ENABLE(peer)\
|
||||
do { \
|
||||
SET_FLAG( \
|
||||
|
@ -78,7 +76,6 @@
|
|||
PEER_GRACEFUL_RESTART_NEW_STATE_HELPER);\
|
||||
} while (0)
|
||||
|
||||
|
||||
#define BGP_PEER_GR_DISABLE(peer)\
|
||||
do { \
|
||||
UNSET_FLAG( \
|
||||
|
@ -89,17 +86,14 @@
|
|||
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 *);
|
||||
|
@ -151,9 +145,8 @@ unsigned int bgp_peer_gr_global_inherit_unset(struct peer *peer);
|
|||
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 */
|
||||
|
|
|
@ -46,8 +46,6 @@ struct bgp;
|
|||
"Address Family modifier\n" \
|
||||
"Address Family modifier\n"
|
||||
|
||||
|
||||
|
||||
#define SHOW_GR_HEADER \
|
||||
"Codes: GR - Graceful Restart," \
|
||||
" * - Inheriting Global GR Config,\n" \
|
||||
|
@ -70,8 +68,6 @@ struct bgp;
|
|||
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,
|
||||
|
|
150
bgpd/bgpd.c
150
bgpd/bgpd.c
|
@ -1102,6 +1102,117 @@ struct peer *peer_unlock_with_caller(const char *name, struct peer *peer)
|
|||
|
||||
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)
|
||||
|
@ -1153,6 +1264,9 @@ 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();
|
||||
|
@ -1534,6 +1648,7 @@ struct peer *peer_create(union sockunion *su, const char *conf_if,
|
|||
else if (!active && peer_active(peer))
|
||||
bgp_timer_set(peer);
|
||||
|
||||
bgp_peer_gr_flags_update(peer);
|
||||
return peer;
|
||||
}
|
||||
|
||||
|
@ -2990,6 +3105,9 @@ static struct bgp *bgp_create(as_t *as, const char *name,
|
|||
|
||||
bgp_evpn_init(bgp);
|
||||
bgp_pbr_init(bgp);
|
||||
|
||||
/*initilize global GR FSM */
|
||||
bgp_global_gr_init(bgp);
|
||||
return bgp;
|
||||
}
|
||||
|
||||
|
@ -7099,3 +7217,35 @@ struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *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);
|
||||
}
|
||||
|
|
15
bgpd/bgpd.h
15
bgpd/bgpd.h
|
@ -238,7 +238,6 @@ enum bgp_instance_type {
|
|||
#define GLOBAL_MODE 4
|
||||
#define EVENT_CMD 4
|
||||
|
||||
|
||||
/* Graceful restart selection deferral timer info */
|
||||
struct graceful_restart_info {
|
||||
/* Count of EOR message expected */
|
||||
|
@ -253,7 +252,6 @@ struct graceful_restart_info {
|
|||
struct thread *t_route_select;
|
||||
};
|
||||
|
||||
|
||||
enum global_mode {
|
||||
GLOBAL_HELPER = 0, /* This is the default mode */
|
||||
GLOBAL_GR,
|
||||
|
@ -271,7 +269,6 @@ enum global_gr_command {
|
|||
#define BGP_GR_SUCCESS 0
|
||||
#define BGP_GR_FAILURE 1
|
||||
|
||||
|
||||
/* BGP instance structure. */
|
||||
struct bgp {
|
||||
/* AS number of this BGP instance. */
|
||||
|
@ -777,7 +774,6 @@ struct peer_af {
|
|||
};
|
||||
/* BGP GR per peer ds */
|
||||
|
||||
|
||||
#define PEER_MODE 5
|
||||
#define PEER_EVENT_CMD 6
|
||||
|
||||
|
@ -1046,7 +1042,7 @@ struct peer {
|
|||
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;
|
||||
|
@ -1076,8 +1072,7 @@ struct peer {
|
|||
#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 */
|
||||
|
@ -1624,7 +1619,6 @@ enum bgp_clear_type {
|
|||
#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
|
||||
|
@ -1884,9 +1878,8 @@ extern void bgp_free(struct bgp *);
|
|||
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);
|
||||
|
|
|
@ -419,7 +419,6 @@ struct cmd_node {
|
|||
"<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"
|
||||
|
@ -434,7 +433,6 @@ struct cmd_node {
|
|||
#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);
|
||||
|
|
Loading…
Reference in a new issue