unsigned char conf_debug_ospf6_gr;
+static int ospf6_grace_lsa_show_info(struct vty *vty, struct ospf6_lsa *lsa,
+ json_object *json, bool use_json);
+
+struct ospf6_lsa_handler grace_lsa_handler = {.lh_type = OSPF6_LSTYPE_GRACE_LSA,
+ .lh_name = "Grace",
+ .lh_short_name = "GR",
+ .lh_show =
+ ospf6_grace_lsa_show_info,
+ .lh_get_prefix_str = NULL,
+ .lh_debug = 0};
+
const char *ospf6_exit_reason_desc[] = {
- "Unknown reason", "Helper inprogress", "Topology Change",
- "Grace timer expiry", "Successful graceful restart",
+ "Unknown reason",
+ "Helper in progress",
+ "Topology Change",
+ "Grace timer expiry",
+ "Successful graceful restart",
};
const char *ospf6_restart_reason_desc[] = {
return OSPF6_FAILURE;
break;
default:
- if (IS_DEBUG_OSPF6_GR_HELPER)
- zlog_debug(
- "%s, Ignoring unknown TLV type:%d",
- __func__, ntohs(tlvh->type));
+ if (IS_DEBUG_OSPF6_GR)
+ zlog_debug("%s, Ignoring unknown TLV type:%d",
+ __func__, ntohs(tlvh->type));
}
}
ret = ospf6_extract_grace_lsa_fields(lsa, &grace_interval,
&restart_reason);
if (ret != OSPF6_SUCCESS) {
- if (IS_DEBUG_OSPF6_GR_HELPER)
- zlog_debug("%s, Wrong Grace LSA packet.",
- __func__);
+ if (IS_DEBUG_OSPF6_GR)
+ zlog_debug("%s, Wrong Grace LSA packet.", __func__);
return OSPF6_GR_NOT_HELPER;
}
- if (IS_DEBUG_OSPF6_GR_HELPER)
+ if (IS_DEBUG_OSPF6_GR)
zlog_debug(
"%s, Grace LSA received from %pI4, grace interval:%u, restart reason :%s",
- __func__, &restarter->router_id,
- grace_interval,
+ __func__, &restarter->router_id, grace_interval,
ospf6_restart_reason_desc[restart_reason]);
/* Verify Helper enabled globally */
if (!hash_lookup(ospf6->ospf6_helper_cfg.enable_rtr_list,
&lookup)) {
- if (IS_DEBUG_OSPF6_GR_HELPER)
+ if (IS_DEBUG_OSPF6_GR)
zlog_debug(
"%s, HELPER support is disabled, So not a HELPER",
__func__);
* became a adjacency.
*/
if (!IS_NBR_STATE_FULL(restarter)) {
- if (IS_DEBUG_OSPF6_GR_HELPER)
+ if (IS_DEBUG_OSPF6_GR)
zlog_debug(
"%s, This Neighbour %pI6 is not in FULL state.",
__func__, &restarter->linklocal_addr);
*/
if (ospf6->ospf6_helper_cfg.only_planned_restart
&& !OSPF6_GR_IS_PLANNED_RESTART(restart_reason)) {
- if (IS_DEBUG_OSPF6_GR_HELPER)
+ if (IS_DEBUG_OSPF6_GR)
zlog_debug(
"%s, Router supports only planned restarts but received the GRACE LSA due a unplanned restart",
__func__);
if (ospf6->ospf6_helper_cfg.strict_lsa_check
&& restarter->retrans_list->count
&& ospf6_check_chg_in_rxmt_list(restarter)) {
- if (IS_DEBUG_OSPF6_GR_HELPER)
+ if (IS_DEBUG_OSPF6_GR)
zlog_debug(
"%s, Changed LSA in Rxmt list.So not Helper.",
__func__);
return OSPF6_GR_NOT_HELPER;
}
- /*LSA age must be less than the grace period */
+ /* LSA age must be less than the grace period */
if (ntohs(lsa->header->age) >= grace_interval) {
- if (IS_DEBUG_OSPF6_GR_HELPER)
+ if (IS_DEBUG_OSPF6_GR)
zlog_debug(
"%s, Grace LSA age(%d) is more than the grace interval(%d)",
- __func__, lsa->header->age,
- grace_interval);
+ __func__, lsa->header->age, grace_interval);
restarter->gr_helper_info.rejected_reason =
OSPF6_HELPER_LSA_AGE_MORE;
return OSPF6_GR_NOT_HELPER;
*/
actual_grace_interval = grace_interval;
if (grace_interval > ospf6->ospf6_helper_cfg.supported_grace_time) {
- if (IS_DEBUG_OSPF6_GR_HELPER)
+ if (IS_DEBUG_OSPF6_GR)
zlog_debug(
"%s, Received grace period %d is larger than supported grace %d",
__func__, grace_interval,
if (ospf6->ospf6_helper_cfg.active_restarter_cnt > 0)
ospf6->ospf6_helper_cfg.active_restarter_cnt--;
- if (IS_DEBUG_OSPF6_GR_HELPER)
+ if (IS_DEBUG_OSPF6_GR)
zlog_debug(
"%s, Router is already acting as a HELPER for this nbr,so restart the grace timer",
__func__);
} else {
- if (IS_DEBUG_OSPF6_GR_HELPER)
+ if (IS_DEBUG_OSPF6_GR)
zlog_debug(
"%s, This Router becomes a HELPER for the neighbour %pI6",
__func__, &restarter->linklocal_addr);
/* Increment the active restart nbr count */
ospf6->ospf6_helper_cfg.active_restarter_cnt++;
- if (IS_DEBUG_OSPF6_GR_HELPER)
- zlog_debug("%s, Grace timer started.interval:%u",
- __func__, actual_grace_interval);
+ if (IS_DEBUG_OSPF6_GR)
+ zlog_debug("%s, Grace timer started.interval:%u", __func__,
+ actual_grace_interval);
/* Start the grace timer */
thread_add_timer(master, ospf6_handle_grace_timer_expiry, restarter,
if (!OSPF6_GR_IS_ACTIVE_HELPER(nbr))
return;
- if (IS_DEBUG_OSPF6_GR_HELPER)
+ if (IS_DEBUG_OSPF6_GR)
zlog_debug("%s, Exiting from HELPER support to %pI6, due to %s",
__func__, &nbr->linklocal_addr,
ospf6_exit_reason_desc[reason]);
ospf6->ospf6_helper_cfg.last_exit_reason = reason;
/* If the exit not triggered due to grace timer
- * expairy , stop the grace timer.
+ * expiry, stop the grace timer.
*/
if (reason != OSPF6_GR_HELPER_GRACE_TIMEOUT)
THREAD_OFF(nbr->gr_helper_info.t_grace_timer);
"OSPF6 GR-Helper: Number of active Restarters should be greater than zero.");
return;
}
- /* Decrement active Restarter count */
+ /* Decrement active restarter count */
ospf6->ospf6_helper_cfg.active_restarter_cnt--;
/* check exit triggered due to successful completion
* of graceful restart.
*/
if (reason != OSPF6_GR_HELPER_COMPLETED) {
- if (IS_DEBUG_OSPF6_GR_HELPER)
+ if (IS_DEBUG_OSPF6_GR)
zlog_debug("%s, Unsuccessful GR exit. RESTARTER : %pI6",
__func__, &nbr->linklocal_addr);
}
}
/*
- * Process Maxage Grace LSA.
- * It is a indication for successfull completion of GR.
+ * Process max age Grace LSA.
+ * It is a indication for successful completion of GR.
* If router acting as HELPER, It exits from helper role.
*
* ospf6
* Grace LSA received from RESTARTER.
*
* nbr
- * ospf6 neighbour which requets the router to act as
+ * ospf6 neighbour which request the router to act as
* HELPER.
*
* Returns:
ret = ospf6_extract_grace_lsa_fields(lsa, &grace_interval,
&restart_reason);
if (ret != OSPF6_SUCCESS) {
- if (IS_DEBUG_OSPF6_GR_HELPER)
- zlog_debug("%s, Wrong Grace LSA packet.",
- __func__);
+ if (IS_DEBUG_OSPF6_GR)
+ zlog_debug("%s, Wrong Grace LSA packet.", __func__);
return;
}
- if (IS_DEBUG_OSPF6_GR_HELPER)
+ if (IS_DEBUG_OSPF6_GR)
zlog_debug("%s, GraceLSA received for neighbour %pI4.",
__func__, &restarter->router_id);
* ospf6
* ospf6 pointer
* lsa
- * topo change occured due to this lsa(type (1-5 and 7)
+ * topo change occurred due to this lsa(type (1-5 and 7)
*
* Returns:
* Nothing
if (!ospf6->ospf6_helper_cfg.active_restarter_cnt)
return;
- /* Topo change not required to be hanlded if strict
- * LSA check is disbaled for this router.
+ /* Topo change not required to be handled if strict
+ * LSA check is disabled for this router.
*/
if (!ospf6->ospf6_helper_cfg.strict_lsa_check)
return;
- if (IS_DEBUG_OSPF6_GR_HELPER)
- zlog_debug(
- "%s, Topo change detected due to lsa details : %s",
- __func__, lsa->name);
+ if (IS_DEBUG_OSPF6_GR)
+ zlog_debug("%s, Topo change detected due to lsa details : %s",
+ __func__, lsa->name);
lsa->tobe_acknowledged = OSPF6_TRUE;
}
}
+/* Configuration handlers */
+/*
+ * Disable/Enable HELPER support on router level.
+ *
+ * ospf6
+ * Ospf6 pointer.
+ *
+ * status
+ * TRUE/FALSE
+ *
+ * Returns:
+ * Nothing.
+ */
+static void ospf6_gr_helper_support_set(struct ospf6 *ospf6, bool support)
+{
+ struct ospf6_interface *oi;
+ struct advRtr lookup;
+ struct listnode *i, *j, *k;
+ struct ospf6_neighbor *nbr = NULL;
+ struct ospf6_area *oa = NULL;
+
+ if (ospf6->ospf6_helper_cfg.is_helper_supported == support)
+ return;
+
+ ospf6->ospf6_helper_cfg.is_helper_supported = support;
+
+ /* If helper support disabled, cease HELPER role for all
+ * supporting neighbors.
+ */
+ if (support == OSPF6_FALSE) {
+ for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa))
+ for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
+
+ for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k,
+ nbr)) {
+
+ lookup.advRtrAddr = nbr->router_id;
+ /* check if helper support enabled for
+ * the corresponding routerid.
+ * If enabled,
+ * dont exit from helper role.
+ */
+ if (hash_lookup(
+ ospf6->ospf6_helper_cfg
+ .enable_rtr_list,
+ &lookup))
+ continue;
+
+ ospf6_gr_helper_exit(
+ nbr, OSPF6_GR_HELPER_TOPO_CHG);
+ }
+ }
+ }
+}
+
+/*
+ * Api to enable/disable strict lsa check on the HELPER.
+ *
+ * ospf6
+ * Ospf6 pointer.
+ *
+ * enabled
+ * True - disable the lsa check.
+ * False - enable the strict lsa check.
+ *
+ * Returns:
+ * Nothing.
+ */
+static void ospf6_gr_helper_lsacheck_set(struct ospf6 *ospf6, bool enabled)
+{
+ if (ospf6->ospf6_helper_cfg.strict_lsa_check == enabled)
+ return;
+
+ ospf6->ospf6_helper_cfg.strict_lsa_check = enabled;
+}
+
+/*
+ * Api to set the supported restart reason.
+ *
+ * ospf6
+ * Ospf6 pointer.
+ *
+ * only_planned
+ * True: support only planned restart.
+ * False: support for planned/unplanned restarts.
+ *
+ * Returns:
+ * Nothing.
+ */
+
+static void
+ospf6_gr_helper_set_supported_onlyPlanned_restart(struct ospf6 *ospf6,
+ bool only_planned)
+{
+ ospf6->ospf6_helper_cfg.only_planned_restart = only_planned;
+}
+
+/*
+ * Api to set the supported grace interval in this router.
+ *
+ * ospf6
+ * Ospf6 pointer.
+ *
+ * interval
+ * The supported grace interval..
+ *
+ * Returns:
+ * Nothing.
+ */
+static void ospf6_gr_helper_supported_gracetime_set(struct ospf6 *ospf6,
+ uint32_t interval)
+{
+ ospf6->ospf6_helper_cfg.supported_grace_time = interval;
+}
+
+/* API to walk and print all the Helper supported router ids */
+static int ospf6_print_vty_helper_dis_rtr_walkcb(struct hash_bucket *bucket,
+ void *arg)
+{
+ struct advRtr *rtr = bucket->data;
+ struct vty *vty = (struct vty *)arg;
+ static unsigned int count;
+
+ vty_out(vty, "%-6pI4,", &rtr->advRtrAddr);
+ count++;
+
+ if (count % 5 == 0)
+ vty_out(vty, "\n");
+
+ return HASHWALK_CONTINUE;
+}
+
+/* API to walk and print all the Helper supported router ids.*/
+static int ospf6_print_json_helper_dis_rtr_walkcb(struct hash_bucket *bucket,
+ void *arg)
+{
+ struct advRtr *rtr = bucket->data;
+ struct json_object *json_rid_array = (struct json_object *)arg;
+ struct json_object *json_rid;
+ char router_id[16];
+
+ inet_ntop(AF_INET, &rtr->advRtrAddr, router_id, sizeof(router_id));
+
+ json_rid = json_object_new_object();
+
+ json_object_string_add(json_rid, "routerId", router_id);
+ json_object_array_add(json_rid_array, json_rid);
+
+ return HASHWALK_CONTINUE;
+}
+
+/*
+ * Enable/Disable HELPER support on a specified advertisement
+ * router.
+ *
+ * ospf6
+ * Ospf6 pointer.
+ *
+ * advRtr
+ * HELPER support for given Advertisement Router.
+ *
+ * support
+ * True - Enable Helper Support.
+ * False - Disable Helper Support.
+ *
+ * Returns:
+ * Nothing.
+ */
+static void ospf6_gr_helper_support_set_per_routerid(struct ospf6 *ospf6,
+ struct in_addr router_id,
+ bool support)
+{
+ struct advRtr temp;
+ struct advRtr *rtr;
+ struct listnode *i, *j, *k;
+ struct ospf6_interface *oi;
+ struct ospf6_neighbor *nbr;
+ struct ospf6_area *oa;
+
+ temp.advRtrAddr = router_id.s_addr;
+
+ if (support == OSPF6_FALSE) {
+ /*Delete the routerid from the enable router hash table */
+ rtr = hash_lookup(ospf6->ospf6_helper_cfg.enable_rtr_list,
+ &temp);
+
+ if (rtr) {
+ hash_release(ospf6->ospf6_helper_cfg.enable_rtr_list,
+ rtr);
+ ospf6_disable_rtr_hash_free(rtr);
+ }
+
+ /* If helper support is enabled globally
+ * no action is required.
+ */
+ if (ospf6->ospf6_helper_cfg.is_helper_supported)
+ return;
+
+ /* Cease the HELPER role fore neighbours from the
+ * specified advertisement router.
+ */
+ for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa))
+ for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
+
+ for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k,
+ nbr)) {
+
+ if (nbr->router_id != router_id.s_addr)
+ continue;
+
+ if (OSPF6_GR_IS_ACTIVE_HELPER(nbr))
+ ospf6_gr_helper_exit(
+ nbr,
+ OSPF6_GR_HELPER_TOPO_CHG);
+ }
+ }
+
+ } else {
+ /* Add the routerid to the enable router hash table */
+ hash_get(ospf6->ospf6_helper_cfg.enable_rtr_list, &temp,
+ ospf6_enable_rtr_hash_alloc);
+ }
+}
+
+static void show_ospfv6_gr_helper_per_nbr(struct vty *vty, json_object *json,
+ bool uj, struct ospf6_neighbor *nbr)
+{
+ if (!uj) {
+ vty_out(vty, " Routerid : %pI4\n", &nbr->router_id);
+ vty_out(vty, " Received Grace period : %d(in seconds).\n",
+ nbr->gr_helper_info.recvd_grace_period);
+ vty_out(vty, " Actual Grace period : %d(in seconds)\n",
+ nbr->gr_helper_info.actual_grace_period);
+ vty_out(vty, " Remaining GraceTime:%ld(in seconds).\n",
+ thread_timer_remain_second(
+ nbr->gr_helper_info.t_grace_timer));
+ vty_out(vty, " Graceful Restart reason: %s.\n\n",
+ ospf6_restart_reason_desc[nbr->gr_helper_info
+ .gr_restart_reason]);
+ } else {
+ char nbrid[16];
+ json_object *json_neigh = NULL;
+
+ inet_ntop(AF_INET, &nbr->router_id, nbrid, sizeof(nbrid));
+ json_neigh = json_object_new_object();
+ json_object_string_add(json_neigh, "routerid", nbrid);
+ json_object_int_add(json_neigh, "recvdGraceInterval",
+ nbr->gr_helper_info.recvd_grace_period);
+ json_object_int_add(json_neigh, "actualGraceInterval",
+ nbr->gr_helper_info.actual_grace_period);
+ json_object_int_add(json_neigh, "remainGracetime",
+ thread_timer_remain_second(
+ nbr->gr_helper_info.t_grace_timer));
+ json_object_string_add(json_neigh, "restartReason",
+ ospf6_restart_reason_desc[
+ nbr->gr_helper_info.gr_restart_reason]);
+ json_object_object_add(json, nbr->name, json_neigh);
+ }
+}
+
+static int show_ospf6_gr_helper_details(struct vty *vty, struct ospf6 *ospf6,
+ json_object *json, bool uj, bool detail)
+{
+ struct ospf6_interface *oi;
+
+ /* Show Router ID. */
+ if (uj) {
+ char router_id[16];
+
+ inet_ntop(AF_INET, &ospf6->router_id, router_id,
+ sizeof(router_id));
+ json_object_string_add(json, "routerId", router_id);
+ } else
+ vty_out(vty,
+ " OSPFv3 Routing Process (0) with Router-ID %pI4\n",
+ &ospf6->router_id);
+
+ if (!uj) {
+
+ if (ospf6->ospf6_helper_cfg.is_helper_supported)
+ vty_out(vty,
+ " Graceful restart helper support enabled.\n");
+ else
+ vty_out(vty,
+ " Graceful restart helper support disabled.\n");
+
+ if (ospf6->ospf6_helper_cfg.strict_lsa_check)
+ vty_out(vty, " Strict LSA check is enabled.\n");
+ else
+ vty_out(vty, " Strict LSA check is disabled.\n");
+
+ if (ospf6->ospf6_helper_cfg.only_planned_restart)
+ vty_out(vty,
+ " Helper supported for planned restarts only.\n");
+ else
+ vty_out(vty,
+ " Helper supported for Planned and Unplanned Restarts.\n");
+
+ vty_out(vty,
+ " Supported Graceful restart interval: %d(in seconds).\n",
+ ospf6->ospf6_helper_cfg.supported_grace_time);
+
+ if (OSPF6_HELPER_ENABLE_RTR_COUNT(ospf)) {
+ vty_out(vty, " Enable Router list:\n");
+ vty_out(vty, " ");
+ hash_walk(ospf6->ospf6_helper_cfg.enable_rtr_list,
+ ospf6_print_vty_helper_dis_rtr_walkcb, vty);
+ vty_out(vty, "\n\n");
+ }
+
+ if (ospf6->ospf6_helper_cfg.last_exit_reason
+ != OSPF6_GR_HELPER_EXIT_NONE) {
+ vty_out(vty, " Last Helper exit Reason :%s\n",
+ ospf6_exit_reason_desc
+ [ospf6->ospf6_helper_cfg
+ .last_exit_reason]);
+
+ if (ospf6->ospf6_helper_cfg.active_restarter_cnt)
+ vty_out(vty,
+ " Number of Active neighbours in graceful restart: %d\n",
+ ospf6->ospf6_helper_cfg
+ .active_restarter_cnt);
+ else
+ vty_out(vty, "\n");
+ }
+
+
+ } else {
+ json_object_string_add(
+ json, "helperSupport",
+ (ospf6->ospf6_helper_cfg.is_helper_supported)
+ ? "Enabled"
+ : "Disabled");
+ json_object_string_add(
+ json, "strictLsaCheck",
+ (ospf6->ospf6_helper_cfg.strict_lsa_check)
+ ? "Enabled"
+ : "Disabled");
+ json_object_string_add(
+ json, "restartSupoort",
+ (ospf6->ospf6_helper_cfg.only_planned_restart)
+ ? "Planned Restart only"
+ : "Planned and Unplanned Restarts");
+
+ json_object_int_add(
+ json, "supportedGracePeriod",
+ ospf6->ospf6_helper_cfg.supported_grace_time);
+
+ if (ospf6->ospf6_helper_cfg.last_exit_reason
+ != OSPF6_GR_HELPER_EXIT_NONE)
+ json_object_string_add(
+ json, "LastExitReason",
+ ospf6_exit_reason_desc
+ [ospf6->ospf6_helper_cfg
+ .last_exit_reason]);
+
+ if (OSPF6_HELPER_ENABLE_RTR_COUNT(ospf6)) {
+ struct json_object *json_rid_array =
+ json_object_new_array();
+
+ json_object_object_add(json, "enabledRouterIds",
+ json_rid_array);
+
+ hash_walk(ospf6->ospf6_helper_cfg.enable_rtr_list,
+ ospf6_print_json_helper_dis_rtr_walkcb,
+ json_rid_array);
+ }
+ }
+
+ if (detail) {
+ int cnt = 1;
+ struct listnode *i, *j, *k;
+ struct ospf6_area *oa;
+ json_object *json_neighbors = NULL;
+
+ for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa))
+ for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
+ struct ospf6_neighbor *nbr;
+
+ if (uj) {
+ json_object_object_get_ex(
+ json, "Neighbors",
+ &json_neighbors);
+ if (!json_neighbors) {
+ json_neighbors =
+ json_object_new_object();
+ json_object_object_add(
+ json, "Neighbors",
+ json_neighbors);
+ }
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k,
+ nbr)) {
+
+ if (!OSPF6_GR_IS_ACTIVE_HELPER(nbr))
+ continue;
+
+ if (!uj)
+ vty_out(vty,
+ " Neighbour %d :\n",
+ cnt++);
+
+ show_ospfv6_gr_helper_per_nbr(
+ vty, json_neighbors, uj, nbr);
+
+ }
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+/* Graceful Restart HELPER config Commands */
+DEFPY(ospf6_gr_helper_enable,
+ ospf6_gr_helper_enable_cmd,
+ "graceful-restart helper-only [A.B.C.D$rtr_id]",
+ "ospf6 graceful restart\n"
+ "Enable Helper support\n"
+ "Advertisement RouterId\n")
+{
+ VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+ if (rtr_id_str != NULL) {
+
+ ospf6_gr_helper_support_set_per_routerid(ospf6, rtr_id,
+ OSPF6_TRUE);
+
+ return CMD_SUCCESS;
+ }
+
+ ospf6_gr_helper_support_set(ospf6, OSPF6_TRUE);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY(ospf6_gr_helper_disable,
+ ospf6_gr_helper_disable_cmd,
+ "no graceful-restart helper-only [A.B.C.D$rtr_id]",
+ NO_STR
+ "ospf6 graceful restart\n"
+ "Disable Helper support\n"
+ "Advertisement RouterId\n")
+{
+ VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+ if (rtr_id_str != NULL) {
+
+ ospf6_gr_helper_support_set_per_routerid(ospf6, rtr_id,
+ OSPF6_FALSE);
+
+ return CMD_SUCCESS;
+ }
+
+ ospf6_gr_helper_support_set(ospf6, OSPF6_FALSE);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY(ospf6_gr_helper_disable_lsacheck,
+ ospf6_gr_helper_disable_lsacheck_cmd,
+ "graceful-restart helper lsa-check-disable",
+ "ospf6 graceful restart\n"
+ "ospf6 GR Helper\n"
+ "disable strict LSA check\n")
+{
+ VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+ ospf6_gr_helper_lsacheck_set(ospf6, OSPF6_FALSE);
+ return CMD_SUCCESS;
+}
+
+DEFPY(no_ospf6_gr_helper_disable_lsacheck,
+ no_ospf6_gr_helper_disable_lsacheck_cmd,
+ "no graceful-restart helper lsa-check-disable",
+ NO_STR
+ "ospf6 graceful restart\n"
+ "ospf6 GR Helper\n"
+ "diasble strict LSA check\n")
+{
+ VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+ ospf6_gr_helper_lsacheck_set(ospf6, OSPF6_TRUE);
+ return CMD_SUCCESS;
+}
+
+DEFPY(ospf6_gr_helper_planned_only,
+ ospf6_gr_helper_planned_only_cmd,
+ "graceful-restart helper planned-only",
+ "ospf6 graceful restart\n"
+ "ospf6 GR Helper\n"
+ "supported only planned restart\n")
+{
+ VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+ ospf6_gr_helper_set_supported_onlyPlanned_restart(ospf6, OSPF6_TRUE);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY(no_ospf6_gr_helper_planned_only, no_ospf6_gr_helper_planned_only_cmd,
+ "no graceful-restart helper planned-only",
+ NO_STR
+ "ospf6 graceful restart\n"
+ "ospf6 GR Helper\n"
+ "supported only for planned restart\n")
+{
+ VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+ ospf6_gr_helper_set_supported_onlyPlanned_restart(ospf6, OSPF6_FALSE);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY(ospf6_gr_helper_supported_grace_time,
+ ospf6_gr_helper_supported_grace_time_cmd,
+ "graceful-restart helper supported-grace-time (10-1800)$interval",
+ "ospf6 graceful restart\n"
+ "ospf6 GR Helper\n"
+ "supported grace timer\n"
+ "grace interval(in seconds)\n")
+{
+ VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+ ospf6_gr_helper_supported_gracetime_set(ospf6, interval);
+ return CMD_SUCCESS;
+}
+
+DEFPY(no_ospf6_gr_helper_supported_grace_time,
+ no_ospf6_gr_helper_supported_grace_time_cmd,
+ "no graceful-restart helper supported-grace-time (10-1800)$interval",
+ NO_STR
+ "ospf6 graceful restart\n"
+ "ospf6 GR Helper\n"
+ "supported grace timer\n"
+ "grace interval(in seconds)\n")
+{
+ VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+ ospf6_gr_helper_supported_gracetime_set(ospf6,
+ OSPF6_MAX_GRACE_INTERVAL);
+ return CMD_SUCCESS;
+}
+
+/* Show commands */
+DEFPY(show_ipv6_ospf6_gr_helper,
+ show_ipv6_ospf6_gr_helper_cmd,
+ "show ipv6 ospf6 graceful-restart helper [detail] [json]",
+ SHOW_STR
+ "Ipv6 Information\n"
+ "OSPF6 information\n"
+ "ospf6 graceful restart\n"
+ "helper details in the router\n"
+ "detailed information\n" JSON_STR)
+{
+ int idx = 0;
+ bool uj = use_json(argc, argv);
+ struct ospf6 *ospf6 = NULL;
+ json_object *json = NULL;
+ bool detail = false;
+
+ ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+ OSPF6_CMD_CHECK_RUNNING();
+
+ if (argv_find(argv, argc, "detail", &idx))
+ detail = true;
+
+ if (uj)
+ json = json_object_new_object();
+
+ show_ospf6_gr_helper_details(vty, ospf6, json, uj, detail);
+
+ if (uj) {
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+
+ return CMD_SUCCESS;
+}
+
/* Debug commands */
-DEFPY(debug_ospf6_gr,
- debug_ospf6_gr_cmd,
+DEFPY(debug_ospf6_gr, debug_ospf6_gr_cmd,
"[no$no] debug ospf6 graceful-restart",
- NO_STR
- DEBUG_STR OSPF6_STR
- "Graceful restart\n")
+ NO_STR DEBUG_STR OSPF6_STR "Graceful restart\n")
{
if (!no)
- OSPF6_DEBUG_GR_HELPER_ON();
+ OSPF6_DEBUG_GR_ON();
else
- OSPF6_DEBUG_GR_HELPER_OFF();
+ OSPF6_DEBUG_GR_OFF();
return CMD_SUCCESS;
}
+/*
+ * Api to display the grace LSA information.
+ *
+ * vty
+ * vty pointer.
+ * lsa
+ * Grace LSA.
+ * json
+ * json object
+ *
+ * Returns:
+ * Nothing.
+ */
+static int ospf6_grace_lsa_show_info(struct vty *vty, struct ospf6_lsa *lsa,
+ json_object *json, bool use_json)
+{
+ struct ospf6_lsa_header *lsah = NULL;
+ struct tlv_header *tlvh = NULL;
+ struct grace_tlv_graceperiod *gracePeriod;
+ struct grace_tlv_restart_reason *grReason;
+ uint16_t length = 0;
+ int sum = 0;
+
+ lsah = (struct ospf6_lsa_header *)lsa->header;
+
+ length = ntohs(lsah->length) - OSPF6_LSA_HEADER_SIZE;
+
+ if (vty) {
+ if (!use_json)
+ vty_out(vty, "TLV info:\n");
+ } else {
+ zlog_debug(" TLV info:");
+ }
+
+ for (tlvh = TLV_HDR_TOP(lsah); sum < length;
+ tlvh = TLV_HDR_NEXT(tlvh)) {
+ switch (ntohs(tlvh->type)) {
+ case GRACE_PERIOD_TYPE:
+ gracePeriod = (struct grace_tlv_graceperiod *)tlvh;
+ sum += TLV_SIZE(tlvh);
+
+ if (vty) {
+ if (use_json)
+ json_object_int_add(
+ json, "gracePeriod",
+ ntohl(gracePeriod->interval));
+ else
+ vty_out(vty, " Grace period:%d\n",
+ ntohl(gracePeriod->interval));
+ } else {
+ zlog_debug(" Grace period:%d",
+ ntohl(gracePeriod->interval));
+ }
+ break;
+ case RESTART_REASON_TYPE:
+ grReason = (struct grace_tlv_restart_reason *)tlvh;
+ sum += TLV_SIZE(tlvh);
+ if (vty) {
+ if (use_json)
+ json_object_string_add(
+ json, "restartReason",
+ ospf6_restart_reason_desc
+ [grReason->reason]);
+ else
+ vty_out(vty, " Restart reason:%s\n",
+ ospf6_restart_reason_desc
+ [grReason->reason]);
+ } else {
+ zlog_debug(" Restart reason:%s",
+ ospf6_restart_reason_desc
+ [grReason->reason]);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+void ospf6_gr_helper_config_init(void)
+{
+
+ ospf6_install_lsa_handler(&grace_lsa_handler);
+
+ install_element(OSPF6_NODE, &ospf6_gr_helper_enable_cmd);
+ install_element(OSPF6_NODE, &ospf6_gr_helper_disable_cmd);
+ install_element(OSPF6_NODE, &ospf6_gr_helper_disable_lsacheck_cmd);
+ install_element(OSPF6_NODE, &no_ospf6_gr_helper_disable_lsacheck_cmd);
+ install_element(OSPF6_NODE, &ospf6_gr_helper_planned_only_cmd);
+ install_element(OSPF6_NODE, &no_ospf6_gr_helper_planned_only_cmd);
+ install_element(OSPF6_NODE, &ospf6_gr_helper_supported_grace_time_cmd);
+ install_element(OSPF6_NODE,
+ &no_ospf6_gr_helper_supported_grace_time_cmd);
+
+ install_element(VIEW_NODE, &show_ipv6_ospf6_gr_helper_cmd);
+
+ install_element(CONFIG_NODE, &debug_ospf6_gr_cmd);
+ install_element(ENABLE_NODE, &debug_ospf6_gr_cmd);
+}
+
+
/*
* Initialize GR helper config data structure.
*
*/
void ospf6_gr_helper_init(struct ospf6 *ospf6)
{
- if (IS_DEBUG_OSPF6_GR_HELPER)
+ if (IS_DEBUG_OSPF6_GR)
zlog_debug("%s, GR Helper init.", __func__);
ospf6->ospf6_helper_cfg.is_helper_supported = OSPF6_FALSE;
}
/*
- * De-Initilise GR helper config datastructer.
+ * De-initialize GR helper config data structure.
*
* ospf6
* ospf6 pointer
void ospf6_gr_helper_deinit(struct ospf6 *ospf6)
{
- if (IS_DEBUG_OSPF6_GR_HELPER)
+ if (IS_DEBUG_OSPF6_GR)
zlog_debug("%s, GR helper deinit.", __func__);
ospf6_enable_rtr_hash_destroy(ospf6);
}
+
+static int ospf6_cfg_write_helper_enable_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 %pI4\n", &rtr->advRtrAddr);
+ return HASHWALK_CONTINUE;
+}
+
+int config_write_ospf6_gr_helper(struct vty *vty, struct ospf6 *ospf6)
+{
+ if (ospf6->ospf6_helper_cfg.is_helper_supported)
+ vty_out(vty, " graceful-restart helper-only\n");
+
+ if (!ospf6->ospf6_helper_cfg.strict_lsa_check)
+ vty_out(vty, " graceful-restart helper lsa-check-disable\n");
+
+ if (ospf6->ospf6_helper_cfg.only_planned_restart)
+ vty_out(vty, " graceful-restart helper planned-only\n");
+
+ if (ospf6->ospf6_helper_cfg.supported_grace_time
+ != OSPF6_MAX_GRACE_INTERVAL)
+ vty_out(vty,
+ " graceful-restart helper supported-grace-time %d\n",
+ ospf6->ospf6_helper_cfg.supported_grace_time);
+
+ if (OSPF6_HELPER_ENABLE_RTR_COUNT(ospf6)) {
+ hash_walk(ospf6->ospf6_helper_cfg.enable_rtr_list,
+ ospf6_cfg_write_helper_enable_rtr_walkcb, vty);
+ }
+
+ return 0;
+}
+
+int config_write_ospf6_debug_gr_helper(struct vty *vty)
+{
+ if (IS_DEBUG_OSPF6_GR)
+ vty_out(vty, "debug ospf6 gr helper\n");
+ return 0;
+}