ospfd: GR helper config commands

Description:
	The following commands are added for helper support.
	1.[no] graceful-restart helper-only
	2.[no] graceful-restart helper-only <A.B.C.D>
	3.[no] graceful-restart helper lsa-check-disable
	4.[no] graceful-restart helper supported-grace-time
	5.[no] graceful-restart helper planned-only

Signed-off-by: Rajesh Girada <rgirada@vmware.com>
This commit is contained in:
rgirada 2020-08-22 11:23:01 -07:00
parent df074ec33a
commit 07b33add1d
3 changed files with 400 additions and 4 deletions

View File

@ -250,7 +250,7 @@ static int ospf_handle_grace_timer_expiry(struct thread *thread)
* Ref rfc3623 section 3.1
*
* ospf
* Ospf pointer.
* OSPF pointer.
*
* lsa
* Grace LSA received from RESTARTER.
@ -560,10 +560,10 @@ void ospf_helper_handle_topo_chg(struct ospf *ospf, struct ospf_lsa *lsa)
* Ref rfc3623 section 3.2
*
* ospf
* Ospf pointer.
* OSPF pointer.
*
* nbr
* Ospf neighbour for which it is acting as HELPER.
* OSPF neighbour for which it is acting as HELPER.
*
* reason
* The reason for exiting from HELPER.
@ -636,7 +636,7 @@ void ospf_gr_helper_exit(struct ospf_neighbor *nbr,
* If router acting as HELPER, It exits from helper role.
*
* ospf
* Ospf pointer.
* OSPF pointer.
*
* lsa
* Grace LSA received from RESTARTER.
@ -692,3 +692,199 @@ void ospf_process_maxage_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
ospf_gr_helper_exit(restarter, OSPF_GR_HELPER_COMPLETED);
}
/* Configuration handlers */
/*
* Disable/Enable HELPER support on router level.
*
* ospf
* OSPFpointer.
*
* status
* TRUE/FALSE
*
* Returns:
* Nothing.
*/
void ospf_gr_helper_support_set(struct ospf *ospf, bool support)
{
struct ospf_interface *oi;
struct listnode *node;
struct advRtr lookup;
if (ospf->is_helper_supported == support)
return;
ospf->is_helper_supported = support;
/* If helper support disabled, cease HELPER role for all
* supporting neighbors.
*/
if (support == OSPF_GR_FALSE) {
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
struct route_node *rn = NULL;
if (ospf_interface_neighbor_count(oi) == 0)
continue;
for (rn = route_top(oi->nbrs); rn;
rn = route_next(rn)) {
struct ospf_neighbor *nbr = NULL;
if (!rn->info)
continue;
nbr = rn->info;
lookup.advRtrAddr.s_addr =
nbr->router_id.s_addr;
/* check if helper support enabled for the
* correspodning routerid.If enabled, dont
* dont exit from helper role.
*/
if (hash_lookup(ospf->enable_rtr_list, &lookup))
continue;
if (OSPF_GR_IS_ACTIVE_HELPER(nbr))
ospf_gr_helper_exit(
nbr, OSPF_GR_HELPER_TOPO_CHG);
}
}
}
}
/*
* Enable/Disable HELPER support on a specified advertagement
* router.
*
* ospf
* OSPF pointer.
*
* advRtr
* HELPER support for given Advertisement Router.
*
* support
* True - Enable Helper Support.
* False - Disable Helper Support.
*
* Returns:
* Nothing.
*/
void ospf_gr_helper_support_set_per_routerid(struct ospf *ospf,
struct in_addr *advrtr,
bool support)
{
struct advRtr temp;
struct advRtr *rtr;
struct ospf_interface *oi;
struct listnode *node;
temp.advRtrAddr.s_addr = advrtr->s_addr;
if (support == OSPF_GR_FALSE) {
/*Delete the routerid from the enable router hash table */
rtr = hash_lookup(ospf->enable_rtr_list, &temp);
if (rtr) {
hash_release(ospf->enable_rtr_list, rtr);
ospf_disable_rtr_hash_free(rtr);
}
/* If helper support is enabled globally
* no action is required.
*/
if (ospf->is_helper_supported)
return;
/* Cease the HELPER role fore neighbours from the
* specified advertisement router.
*/
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
struct route_node *rn = NULL;
if (ospf_interface_neighbor_count(oi) == 0)
continue;
for (rn = route_top(oi->nbrs); rn;
rn = route_next(rn)) {
struct ospf_neighbor *nbr = NULL;
if (!rn->info)
continue;
nbr = rn->info;
if (nbr->router_id.s_addr != advrtr->s_addr)
continue;
if (OSPF_GR_IS_ACTIVE_HELPER(nbr))
ospf_gr_helper_exit(
nbr, OSPF_GR_HELPER_TOPO_CHG);
}
}
} else {
/* Add the routerid to the enable router hash table */
hash_get(ospf->enable_rtr_list, &temp,
ospf_enable_rtr_hash_alloc);
}
}
/*
* Api to enable/disable strict lsa check on the HELPER.
*
* ospf
* OSPF pointer.
*
* enabled
* True - disable the lsa check.
* False - enable the strict lsa check.
*
* Returns:
* Nothing.
*/
void ospf_gr_helper_lsa_check_set(struct ospf *ospf, bool enabled)
{
if (ospf->strict_lsa_check == enabled)
return;
ospf->strict_lsa_check = enabled;
}
/*
* Api to set the supported grace interval in this router.
*
* ospf
* OSPF pointer.
*
* interval
* The supported grace interval..
*
* Returns:
* Nothing.
*/
void ospf_gr_helper_supported_gracetime_set(struct ospf *ospf,
uint32_t interval)
{
ospf->supported_grace_time = interval;
}
/*
* Api to set the supported restart reason.
*
* ospf
* OSPF pointer.
*
* planned_only
* True: support only planned restart.
* False: support for planned/unplanned restarts.
*
* Returns:
* Nothing.
*/
void ospf_gr_helper_set_supported_planned_only_restart(struct ospf *ospf,
bool planned_only)
{
ospf->only_planned_restart = planned_only;
}

View File

@ -163,4 +163,13 @@ extern void ospf_process_maxage_grace_lsa(struct ospf *ospf,
struct ospf_neighbor *nbr);
extern void ospf_helper_handle_topo_chg(struct ospf *ospf,
struct ospf_lsa *lsa);
extern void ospf_gr_helper_support_set(struct ospf *ospf, bool support);
extern void ospf_gr_helper_support_set_per_routerid(struct ospf *ospf,
struct in_addr *rid,
bool support);
extern void ospf_gr_helper_lsa_check_set(struct ospf *ospf, bool lsacheck);
extern void ospf_gr_helper_supported_gracetime_set(struct ospf *ospf,
uint32_t interval);
extern void ospf_gr_helper_set_supported_planned_only_restart(struct ospf *ospf,
bool planned_only);
#endif /* _ZEBRA_OSPF_HELPER_H */

View File

@ -8988,6 +8988,149 @@ DEFUN (no_ospf_proactive_arp,
return CMD_SUCCESS;
}
/* Graceful Restart HELPER Commands */
DEFPY(ospf_gr_helper_enable, ospf_gr_helper_enable_cmd,
"graceful-restart helper-only [A.B.C.D]",
"OSPF Graceful Restart\n"
"Enable Helper support\n"
"Advertising router id\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
struct in_addr addr;
int ret;
if (argc == 3) {
ret = inet_aton(argv[2]->arg, &addr);
if (!ret) {
vty_out(vty,
"Please specify the valid routerid address.\n");
return CMD_WARNING_CONFIG_FAILED;
}
ospf_gr_helper_support_set_per_routerid(ospf, &addr, OSPF_GR_TRUE);
return CMD_SUCCESS;
}
ospf_gr_helper_support_set(ospf, OSPF_GR_TRUE);
return CMD_SUCCESS;
}
DEFPY(no_ospf_gr_helper_enable,
no_ospf_gr_helper_enable_cmd,
"no graceful-restart helper-only [A.B.C.D]",
NO_STR
"OSPF Graceful Restart\n"
"Disable Helper support\n"
"Advertising router id\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
struct in_addr addr;
int ret;
if (argc == 4) {
ret = inet_aton(argv[3]->arg, &addr);
if (!ret) {
vty_out(vty,
"Please specify the valid routerid address.\n");
return CMD_WARNING_CONFIG_FAILED;
}
ospf_gr_helper_support_set_per_routerid(ospf, &addr,
OSPF_GR_FALSE);
return CMD_SUCCESS;
}
ospf_gr_helper_support_set(ospf, OSPF_GR_FALSE);
return CMD_SUCCESS;
}
DEFPY(ospf_gr_helper_enable_lsacheck,
ospf_gr_helper_enable_lsacheck_cmd,
"graceful-restart helper strict-lsa-checking",
"OSPF Graceful Restart\n"
"OSPF GR Helper\n"
"Enable strict LSA check\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
ospf_gr_helper_lsa_check_set(ospf, OSPF_GR_TRUE);
return CMD_SUCCESS;
}
DEFPY(no_ospf_gr_helper_enable_lsacheck,
no_ospf_gr_helper_enable_lsacheck_cmd,
"no graceful-restart helper strict-lsa-checking",
NO_STR
"OSPF Graceful Restart\n"
"OSPF GR Helper\n"
"Disable strict LSA check\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
ospf_gr_helper_lsa_check_set(ospf, OSPF_GR_FALSE);
return CMD_SUCCESS;
}
DEFPY(ospf_gr_helper_supported_grace_time,
ospf_gr_helper_supported_grace_time_cmd,
"graceful-restart helper supported-grace-time (10-1800)$interval",
"OSPF Graceful Restart\n"
"OSPF GR Helper\n"
"Supported grace timer\n"
"Grace interval(in seconds)\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
ospf_gr_helper_supported_gracetime_set(ospf, interval);
return CMD_SUCCESS;
}
DEFPY(no_ospf_gr_helper_supported_grace_time,
no_ospf_gr_helper_supported_grace_time_cmd,
"no graceful-restart helper supported-grace-time (10-1800)$interval",
NO_STR
"OSPF Graceful Restart\n"
"OSPF GR Helper\n"
"Supported grace timer\n"
"Grace interval(in seconds)\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
ospf_gr_helper_supported_gracetime_set(ospf, OSPF_MAX_GRACE_INTERVAL);
return CMD_SUCCESS;
}
DEFPY(ospf_gr_helper_planned_only,
ospf_gr_helper_planned_only_cmd,
"graceful-restart helper planned-only",
"OSPF Graceful Restart\n"
"OSPF GR Helper\n"
"Supported only planned restart\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
ospf_gr_helper_set_supported_planned_only_restart(ospf, OSPF_GR_TRUE);
return CMD_SUCCESS;
}
DEFPY(no_ospf_gr_helper_planned_only,
no_ospf_gr_helper_planned_only_cmd,
"no graceful-restart helper planned-only",
NO_STR
"OSPF Graceful Restart\n"
"OSPF GR Helper\n"
"Supported only for planned restart\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
ospf_gr_helper_set_supported_planned_only_restart(ospf, OSPF_GR_FALSE);
return CMD_SUCCESS;
}
/* Graceful Restart HELPER commands end */
static void config_write_stub_router(struct vty *vty, struct ospf *ospf)
{
struct listnode *ln;
@ -10310,6 +10453,41 @@ static int config_write_ospf_redistribute(struct vty *vty, struct ospf *ospf)
return 0;
}
static int ospf_cfg_write_helper_dis_rtr_walkcb(struct hash_bucket *backet,
void *arg)
{
struct advRtr *rtr = backet->data;
struct vty *vty = (struct vty *)arg;
vty_out(vty, " graceful-restart helper-only %s\n",
inet_ntoa(rtr->advRtrAddr));
return HASHWALK_CONTINUE;
}
static int config_write_ospf_gr_helper(struct vty *vty, struct ospf *ospf)
{
if (ospf->is_helper_supported)
vty_out(vty, " graceful-restart helper-only\n");
if (!ospf->strict_lsa_check)
vty_out(vty, " no graceful-restart helper strict-lsa-checking\n");
if (ospf->only_planned_restart)
vty_out(vty, " graceful-restart helper planned-only\n");
if (ospf->supported_grace_time != OSPF_MAX_GRACE_INTERVAL)
vty_out(vty,
" graceful-restart helper supported-grace-time %d\n",
ospf->supported_grace_time);
if (OSPF_HELPER_ENABLE_RTR_COUNT(ospf)) {
hash_walk(ospf->enable_rtr_list,
ospf_cfg_write_helper_dis_rtr_walkcb, vty);
}
return 0;
}
static int config_write_ospf_default_metric(struct vty *vty, struct ospf *ospf)
{
if (ospf->default_metric != -1)
@ -10477,6 +10655,9 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
/* Redistribute information print. */
config_write_ospf_redistribute(vty, ospf);
/* Print gr helper configs */
config_write_ospf_gr_helper(vty, ospf);
/* passive-interface print. */
if (ospf->passive_interface_default == OSPF_IF_PASSIVE)
vty_out(vty, " passive-interface default\n");
@ -10735,6 +10916,16 @@ static void ospf_vty_zebra_init(void)
install_element(OSPF_NODE, &no_ospf_distance_cmd);
install_element(OSPF_NODE, &no_ospf_distance_ospf_cmd);
install_element(OSPF_NODE, &ospf_distance_ospf_cmd);
/*Ospf garcefull restart helper configurations */
install_element(OSPF_NODE, &ospf_gr_helper_enable_cmd);
install_element(OSPF_NODE, &no_ospf_gr_helper_enable_cmd);
install_element(OSPF_NODE, &ospf_gr_helper_enable_lsacheck_cmd);
install_element(OSPF_NODE, &no_ospf_gr_helper_enable_lsacheck_cmd);
install_element(OSPF_NODE, &ospf_gr_helper_supported_grace_time_cmd);
install_element(OSPF_NODE, &no_ospf_gr_helper_supported_grace_time_cmd);
install_element(OSPF_NODE, &ospf_gr_helper_planned_only_cmd);
install_element(OSPF_NODE, &no_ospf_gr_helper_planned_only_cmd);
#if 0
install_element (OSPF_NODE, &ospf_distance_source_cmd);
install_element (OSPF_NODE, &no_ospf_distance_source_cmd);