]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospf6d: GR helper configurations 8935/head
authorrgirada <rgirada@vmware.com>
Thu, 1 Jul 2021 14:09:38 +0000 (07:09 -0700)
committerrgirada <rgirada@vmware.com>
Thu, 12 Aug 2021 06:06:49 +0000 (23:06 -0700)
Description:
Adding the following cli commands to enable/disable GR helper
functionality.
1. [no] graceful-restart helper-only [A.B.C.D]
2. [no] graceful-restart helper lsa-check-disable
3. [no] graceful-restart helper planned-only
4. [no] graceful-restart helper supported-grace-time (10-1800)

show commands:
show ipv6 ospf6 graceful-restart helper [detail] [json]

Signed-off-by: Rajesh Girada <rgirada@vmware.com>
ospf6d/ospf6_flood.c
ospf6d/ospf6_gr.h
ospf6d/ospf6_gr_helper.c
ospf6d/ospf6_message.c
ospf6d/ospf6_neighbor.c
ospf6d/ospf6_top.c
ospf6d/ospf6d.c

index 458b81f2eaf3dea2fbbe2d4bdaffd7f35acbf877..87c43c46574297075dd0fd5fb9504a37c221bd89 100644 (file)
@@ -1026,7 +1026,7 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from,
 
                        if (OSPF6_LSA_IS_MAXAGE(new)) {
 
-                               if (IS_DEBUG_OSPF6_GR_HELPER)
+                               if (IS_DEBUG_OSPF6_GR)
                                        zlog_debug(
                                                "%s, Received a maxage GraceLSA from router %pI4",
                                                __func__,
@@ -1035,7 +1035,7 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from,
                                        ospf6_process_maxage_grace_lsa(
                                                ospf6, new, from);
                                } else {
-                                       if (IS_DEBUG_OSPF6_GR_HELPER)
+                                       if (IS_DEBUG_OSPF6_GR)
                                                zlog_debug(
                                                        "%s, GraceLSA doesn't exist in lsdb, so discarding GraceLSA",
                                                        __func__);
@@ -1043,7 +1043,7 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from,
                                }
                        } else {
 
-                               if (IS_DEBUG_OSPF6_GR_HELPER)
+                               if (IS_DEBUG_OSPF6_GR)
                                        zlog_debug(
                                                "%s, Received a GraceLSA from router %pI4",
                                                __func__,
@@ -1051,7 +1051,7 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from,
 
                                if (ospf6_process_grace_lsa(ospf6, new, from)
                                    == OSPF6_GR_NOT_HELPER) {
-                                       if (IS_DEBUG_OSPF6_GR_HELPER)
+                                       if (IS_DEBUG_OSPF6_GR)
                                                zlog_debug(
                                                        "%s, Not moving to HELPER role, So dicarding GraceLSA",
                                                        __func__);
index 49fc86a4e21a68c0dfa26a2c8c12d5e47e24826f..378b7193cdba041b4d3c3924e6752b739c2fc7ca 100644 (file)
 /* Debug option */
 extern unsigned char conf_debug_ospf6_gr;
 
-#define OSPF6_DEBUG_GR_HELPER 0x01
+#define OSPF6_DEBUG_GR 0x01
 
-#define OSPF6_DEBUG_GR_HELPER_ON()                                             \
-       (conf_debug_ospf6_gr |= OSPF6_DEBUG_GR_HELPER)
+#define OSPF6_DEBUG_GR_ON() (conf_debug_ospf6_gr |= OSPF6_DEBUG_GR)
 
-#define OSPF6_DEBUG_GR_HELPER_OFF()                                            \
-       (conf_debug_ospf6_gr &= ~OSPF6_DEBUG_GR_HELPER)
+#define OSPF6_DEBUG_GR_OFF() (conf_debug_ospf6_gr &= ~OSPF6_DEBUG_GR)
 
-#define IS_DEBUG_OSPF6_GR_HELPER conf_debug_ospf6_gr
+#define IS_DEBUG_OSPF6_GR conf_debug_ospf6_gr
 
 
 enum ospf6_helper_exit_reason {
@@ -98,7 +96,7 @@ struct tlv_header {
 #define TLV_HDR_NEXT(tlvh)                                                     \
        (struct tlv_header *)((char *)(tlvh) + TLV_SIZE(tlvh))
 
-/* Ref RFC5187 appendex-A */
+/* Ref RFC5187 appendix-A */
 /* Grace period TLV */
 #define GRACE_PERIOD_TYPE 1
 #define GRACE_PERIOD_LENGTH 4
@@ -126,7 +124,7 @@ struct advRtr {
 };
 
 #define OSPF6_HELPER_ENABLE_RTR_COUNT(ospf)                                    \
-       (ospf6->ospf6_helper_cfg.enableRtrList->count)
+       (ospf6->ospf6_helper_cfg.enable_rtr_list->count)
 
 /* Check , it is a planned restart */
 #define OSPF6_GR_IS_PLANNED_RESTART(reason)                                    \
@@ -146,6 +144,7 @@ extern const char *ospf6_exit_reason_desc[];
 extern const char *ospf6_restart_reason_desc[];
 extern const char *ospf6_rejected_reason_desc[];
 
+extern void ospf6_gr_helper_config_init(void);
 extern void ospf6_gr_helper_init(struct ospf6 *ospf6);
 extern void ospf6_gr_helper_deinit(struct ospf6 *ospf6);
 extern void ospf6_gr_helper_exit(struct ospf6_neighbor *nbr,
@@ -157,4 +156,6 @@ extern void ospf6_process_maxage_grace_lsa(struct ospf6 *ospf,
                                           struct ospf6_neighbor *nbr);
 extern void ospf6_helper_handle_topo_chg(struct ospf6 *ospf6,
                                         struct ospf6_lsa *lsa);
+extern int config_write_ospf6_gr_helper(struct vty *vty, struct ospf6 *ospf6);
+extern int config_write_ospf6_debug_gr_helper(struct vty *vty);
 #endif /* OSPF6_GR_H */
index 60c62a9341988ee0b53c938a8600c75ec4e7c46d..07e479efcb8aa6e1227d7d67ee21acd1f5759329 100644 (file)
@@ -57,9 +57,23 @@ DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_GR_HELPER, "OSPF6 Graceful restart helper");
 
 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[] = {
@@ -165,10 +179,9 @@ static int ospf6_extract_grace_lsa_fields(struct ospf6_lsa *lsa,
                                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));
                }
        }
 
@@ -259,17 +272,15 @@ int ospf6_process_grace_lsa(struct ospf6 *ospf6, struct ospf6_lsa *lsa,
        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 */
@@ -281,7 +292,7 @@ int ospf6_process_grace_lsa(struct ospf6 *ospf6, struct ospf6_lsa *lsa,
 
                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__);
@@ -295,7 +306,7 @@ int ospf6_process_grace_lsa(struct ospf6 *ospf6, struct ospf6_lsa *lsa,
         * 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);
@@ -309,7 +320,7 @@ int ospf6_process_grace_lsa(struct ospf6 *ospf6, struct ospf6_lsa *lsa,
         */
        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__);
@@ -324,7 +335,7 @@ int ospf6_process_grace_lsa(struct ospf6 *ospf6, struct ospf6_lsa *lsa,
        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__);
@@ -333,13 +344,12 @@ int ospf6_process_grace_lsa(struct ospf6 *ospf6, struct ospf6_lsa *lsa,
                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;
@@ -352,7 +362,7 @@ int ospf6_process_grace_lsa(struct ospf6 *ospf6, struct ospf6_lsa *lsa,
         */
        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,
@@ -368,12 +378,12 @@ int ospf6_process_grace_lsa(struct ospf6 *ospf6, struct ospf6_lsa *lsa,
                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);
@@ -391,9 +401,9 @@ int ospf6_process_grace_lsa(struct ospf6 *ospf6, struct ospf6_lsa *lsa,
        /* 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,
@@ -434,7 +444,7 @@ void ospf6_gr_helper_exit(struct ospf6_neighbor *nbr,
        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]);
@@ -448,7 +458,7 @@ void ospf6_gr_helper_exit(struct ospf6_neighbor *nbr,
        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);
@@ -458,14 +468,14 @@ void ospf6_gr_helper_exit(struct ospf6_neighbor *nbr,
                        "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);
        }
@@ -482,8 +492,8 @@ void ospf6_gr_helper_exit(struct ospf6_neighbor *nbr,
 }
 
 /*
- * 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
@@ -493,7 +503,7 @@ void ospf6_gr_helper_exit(struct ospf6_neighbor *nbr,
  *    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:
@@ -510,13 +520,12 @@ void ospf6_process_maxage_grace_lsa(struct ospf6 *ospf6, struct ospf6_lsa *lsa,
        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);
 
@@ -530,7 +539,7 @@ void ospf6_process_maxage_grace_lsa(struct ospf6 *ospf6, struct ospf6_lsa *lsa,
  * 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
@@ -545,16 +554,15 @@ void ospf6_helper_handle_topo_chg(struct ospf6 *ospf6, struct ospf6_lsa *lsa)
        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;
 
@@ -582,22 +590,704 @@ void ospf6_helper_handle_topo_chg(struct ospf6 *ospf6, struct ospf6_lsa *lsa)
                }
 }
 
+/* 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.
  *
@@ -609,7 +1299,7 @@ DEFPY(debug_ospf6_gr,
  */
 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;
@@ -625,7 +1315,7 @@ void ospf6_gr_helper_init(struct ospf6 *ospf6)
 }
 
 /*
- * De-Initilise GR helper config datastructer.
+ * De-initialize GR helper config data structure.
  *
  * ospf6
  *    ospf6 pointer
@@ -636,8 +1326,50 @@ void ospf6_gr_helper_init(struct ospf6 *ospf6)
 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;
+}
index a80ec4430fa9f5550dafe2452ee8392e3dd650c5..cd73e3d4062632c7cd83c42606e1a196a16024cf 100644 (file)
@@ -515,7 +515,7 @@ static void ospf6_hello_recv(struct in6_addr *src, struct in6_addr *dst,
        if (twoway)
                thread_execute(master, twoway_received, on, 0);
        else {
-               if (IS_DEBUG_OSPF6_GR_HELPER)
+               if (IS_DEBUG_OSPF6_GR)
                        zlog_debug(
                                "%s, Received oneway hello from RESTARTER so ignore here.",
                                __PRETTY_FUNCTION__);
@@ -545,7 +545,7 @@ static void ospf6_hello_recv(struct in6_addr *src, struct in6_addr *dst,
                 * period, it can handle if there is any change before GR and
                 * after GR.
                 */
-               if (IS_DEBUG_OSPF6_GR_HELPER)
+               if (IS_DEBUG_OSPF6_GR)
                        zlog_debug(
                                "%s, Neighbor is under GR Restart, hence ignoring the ISM Events",
                                __PRETTY_FUNCTION__);
@@ -1302,7 +1302,7 @@ static unsigned ospf6_lsa_examin(struct ospf6_lsa_header *lsah,
        case OSPF6_LSTYPE_GRACE_LSA:
                if (lsalen < OSPF6_LSA_HEADER_SIZE + GRACE_PERIOD_TLV_SIZE
                                     + GRACE_RESTART_REASON_TLV_SIZE) {
-                       if (IS_DEBUG_OSPF6_GR_HELPER)
+                       if (IS_DEBUG_OSPF6_GR)
                                zlog_debug("%s: Undersized GraceLSA.",
                                           __func__);
                        return MSG_NG;
index 331b75f80389ed2cd1eb49d74e1d59c18cfaf4e0..4ea615f32b7f5923bb84ba44bfe5a7dbb3b6b18a 100644 (file)
@@ -622,7 +622,7 @@ int inactivity_timer(struct thread *thread)
                ospf6_neighbor_delete(on);
 
        } else {
-               if (IS_DEBUG_OSPF6_GR_HELPER)
+               if (IS_DEBUG_OSPF6_GR)
                        zlog_debug(
                                "%s, Acting as HELPER for this neighbour, So restart the dead timer.",
                                __PRETTY_FUNCTION__);
index 37361de6890a6fb8fc9d59efb0cdb700a5e0b692..fc181a6d188a3d97014fdecf05546dcccce32354 100644 (file)
@@ -2236,6 +2236,7 @@ static int config_write_ospf6(struct vty *vty)
                ospf6_distance_config_write(vty, ospf6);
                ospf6_distribute_config_write(vty, ospf6);
                ospf6_asbr_summary_config_write(vty, ospf6);
+               config_write_ospf6_gr_helper(vty, ospf6);
                vty_out(vty, "!\n");
        }
        return 0;
index fb6ac4402a9bb11487c4ef7d7514b3080705568a..5dfd986e2aafe8a3275df4385b094892acc8b23b 100644 (file)
@@ -45,6 +45,7 @@
 #include "ospf6_flood.h"
 #include "ospf6d.h"
 #include "ospf6_bfd.h"
+#include "ospf6_gr.h"
 #include "lib/json.h"
 #include "ospf6_nssa.h"
 
@@ -96,6 +97,7 @@ static int config_write_ospf6_debug(struct vty *vty)
        config_write_ospf6_debug_abr(vty);
        config_write_ospf6_debug_flood(vty);
        config_write_ospf6_debug_nssa(vty);
+       config_write_ospf6_debug_gr_helper(vty);
 
        return 0;
 }
@@ -1402,6 +1404,7 @@ void ospf6_init(struct thread_master *master)
        ospf6_intra_init();
        ospf6_asbr_init();
        ospf6_abr_init();
+       ospf6_gr_helper_config_init();
 
        /* initialize hooks for modifying filter rules */
        prefix_list_add_hook(ospf6_plist_add);