]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospfd: GR helper config commands
authorrgirada <rgirada@vmware.com>
Sat, 22 Aug 2020 18:23:01 +0000 (11:23 -0700)
committerrgirada <rgirada@vmware.com>
Tue, 22 Sep 2020 07:02:37 +0000 (00:02 -0700)
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>
ospfd/ospf_gr_helper.c
ospfd/ospf_gr_helper.h
ospfd/ospf_vty.c

index 1c2c4f5f9dff78e3ac811a219a5dd33c93aea88c..6d630f942a821fc79192368ffb86dc1334ab52ea 100644 (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;
+}
index a6a7bebcf0b4181de233f227c98e80905459df5e..2432610a9c0a972cfbc629f79a3406e21bd26409 100644 (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 */
index 8099b0160cf386a4983df465f5446fbf36caf9b8..3bed817f614d68027ef12868ad842229a9e3a3b9 100644 (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);