* Ref rfc3623 section 3.1
*
* ospf
- * Ospf pointer.
+ * OSPF pointer.
*
* lsa
* Grace LSA received from RESTARTER.
* 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.
* If router acting as HELPER, It exits from helper role.
*
* ospf
- * Ospf pointer.
+ * OSPF pointer.
*
* lsa
* Grace LSA received from RESTARTER.
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;
+}
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;
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)
/* 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");
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);