]> git.proxmox.com Git - mirror_frr.git/commitdiff
isisd: retrofit the 'default-originate' command
authorEmanuele Di Pascale <emanuele@voltanet.io>
Wed, 14 Nov 2018 11:12:32 +0000 (12:12 +0100)
committerEmanuele Di Pascale <emanuele@voltanet.io>
Tue, 18 Dec 2018 14:23:49 +0000 (15:23 +0100)
Signed-off-by: Emanuele Di Pascale <emanuele@voltanet.io>
isisd/isis_cli.c
isisd/isis_cli.h
isisd/isis_northbound.c
isisd/isis_redist.c
isisd/isis_redist.h

index fd309e6244acd27eeb8bd79be323e59fc1be69c4..b2948de1cef5265503b9cae2a842f2804bf207ad 100644 (file)
@@ -962,6 +962,88 @@ DEFPY(isis_mpls_te_inter_as, isis_mpls_te_inter_as_cmd,
        return CMD_SUCCESS;
 }
 
        return CMD_SUCCESS;
 }
 
+/*
+ * XPath: /frr-isisd:isis/instance/default-information-originate
+ */
+DEFPY(isis_default_originate, isis_default_originate_cmd,
+      "[no] default-information originate <ipv4|ipv6>$ip"
+      " <level-1|level-2>$level [always]$always"
+      " [<metric (0-16777215)$metric|route-map WORD$rmap>]",
+      NO_STR
+      "Control distribution of default information\n"
+      "Distribute a default route\n"
+      "Distribute default route for IPv4\n"
+      "Distribute default route for IPv6\n"
+      "Distribute default route into level-1\n"
+      "Distribute default route into level-2\n"
+      "Always advertise default route\n"
+      "Metric for default route\n"
+      "ISIS default metric\n"
+      "Route map reference\n"
+      "Pointer to route-map entries\n")
+{
+       if (no)
+               nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL);
+       else {
+               nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+               nb_cli_enqueue_change(vty, "./always",
+                                     always ? NB_OP_CREATE : NB_OP_DELETE,
+                                     NULL);
+               nb_cli_enqueue_change(vty, "./route-map",
+                                     rmap ? NB_OP_MODIFY : NB_OP_DELETE,
+                                     rmap ? rmap : NULL);
+               nb_cli_enqueue_change(vty, "./metric",
+                                     metric ? NB_OP_MODIFY : NB_OP_DELETE,
+                                     metric ? metric_str : NULL);
+               if (strmatch(ip, "ipv6") && !always) {
+                       vty_out(vty,
+                               "Zebra doesn't implement default-originate for IPv6 yet\n");
+                       vty_out(vty,
+                               "so use with care or use default-originate always.\n");
+               }
+       }
+
+       return nb_cli_apply_changes(
+               vty, "./default-information-originate/%s[level='%s']", ip,
+               level);
+}
+
+static void vty_print_def_origin(struct vty *vty, struct lyd_node *dnode,
+                                const char *family, const char *level, bool show_defaults)
+{
+       const char *metric;
+
+       vty_out(vty, " default-information originate %s %s", family, level);
+       if (yang_dnode_exists(dnode, "./always"))
+               vty_out(vty, " always");
+
+       if (yang_dnode_exists(dnode, "./route-map"))
+               vty_out(vty, " route-map %s",
+                       yang_dnode_get_string(dnode, "./route-map"));
+       else if (yang_dnode_exists(dnode, "./metric")) {
+               metric = yang_dnode_get_string(dnode, "./metric");
+               if (show_defaults || !yang_dnode_is_default(dnode, "./metric"))
+                       vty_out(vty, " metric %s", metric);
+       }
+       vty_out(vty, "\n");
+}
+
+void cli_show_isis_def_origin_ipv4(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults)
+{
+       const char *level = yang_dnode_get_string(dnode, "./level");
+
+       vty_print_def_origin(vty, dnode, "ipv4", level, show_defaults);
+}
+
+void cli_show_isis_def_origin_ipv6(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults)
+{
+       const char *level = yang_dnode_get_string(dnode, "./level");
+
+       vty_print_def_origin(vty, dnode, "ipv6", level, show_defaults);
+}
+
 void isis_cli_init(void)
 {
        install_element(CONFIG_NODE, &router_isis_cmd);
 void isis_cli_init(void)
 {
        install_element(CONFIG_NODE, &router_isis_cmd);
@@ -1008,6 +1090,8 @@ void isis_cli_init(void)
        install_element(ISIS_NODE, &no_isis_mpls_te_on_cmd);
        install_element(ISIS_NODE, &isis_mpls_te_router_addr_cmd);
        install_element(ISIS_NODE, &isis_mpls_te_inter_as_cmd);
        install_element(ISIS_NODE, &no_isis_mpls_te_on_cmd);
        install_element(ISIS_NODE, &isis_mpls_te_router_addr_cmd);
        install_element(ISIS_NODE, &isis_mpls_te_inter_as_cmd);
+
+       install_element(ISIS_NODE, &isis_default_originate_cmd);
 }
 
 #endif /* ifndef FABRICD */
 }
 
 #endif /* ifndef FABRICD */
index d28302a71d87a4795529cbff216884fab203a9e1..3cd4f3e4ad9f9ae93985bd051cfa1e5ea0d9308e 100644 (file)
@@ -61,5 +61,9 @@ void cli_show_isis_mpls_te(struct vty *vty, struct lyd_node *dnode,
                           bool show_defaults);
 void cli_show_isis_mpls_te_router_addr(struct vty *vty, struct lyd_node *dnode,
                                       bool show_defaults);
                           bool show_defaults);
 void cli_show_isis_mpls_te_router_addr(struct vty *vty, struct lyd_node *dnode,
                                       bool show_defaults);
+void cli_show_isis_def_origin_ipv4(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults);
+void cli_show_isis_def_origin_ipv6(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults);
 
 #endif /* ISISD_ISIS_CLI_H_ */
 
 #endif /* ISISD_ISIS_CLI_H_ */
index 43e2639b1bf2b90e15a116f6addce4c09f9ed229..e5ddadb44f5fc03e433af9377f7b96b3712018d4 100644 (file)
@@ -845,18 +845,63 @@ static int isis_instance_domain_password_authenticate_snp_modify(
 /*
  * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4
  */
 /*
  * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4
  */
+static void default_info_origin_apply_finish(const struct lyd_node *dnode,
+                                            int family)
+{
+       int originate_type = DEFAULT_ORIGINATE;
+       unsigned long metric = 0;
+       const char *routemap = NULL;
+       struct isis_area *area = yang_dnode_get_entry(dnode, true);
+       int level = yang_dnode_get_enum(dnode, "./level");
+
+       if (yang_dnode_exists(dnode, "./always")) {
+               originate_type = DEFAULT_ORIGINATE_ALWAYS;
+       } else if (family == AF_INET6) {
+               zlog_warn(
+                       "%s: Zebra doesn't implement default-originate for IPv6 yet, so use with care or use default-originate always.",
+                       __func__);
+       }
+
+       if (yang_dnode_exists(dnode, "./metric"))
+               metric = yang_dnode_get_uint32(dnode, "./metric");
+       else if (yang_dnode_exists(dnode, "./route-map"))
+               routemap = yang_dnode_get_string(dnode, "./route-map");
+
+       isis_redist_set(area, level, family, DEFAULT_ROUTE, metric, routemap,
+                       originate_type);
+}
+
+static void default_info_origin_ipv4_apply_finish(const struct lyd_node *dnode)
+{
+       default_info_origin_apply_finish(dnode, AF_INET);
+}
+
+static void default_info_origin_ipv6_apply_finish(const struct lyd_node *dnode)
+{
+       default_info_origin_apply_finish(dnode, AF_INET6);
+}
+
 static int isis_instance_default_information_originate_ipv4_create(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
 static int isis_instance_default_information_originate_ipv4_create(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       /* It's all done by default_info_origin_apply_finish */
        return NB_OK;
 }
 
 static int isis_instance_default_information_originate_ipv4_delete(
        enum nb_event event, const struct lyd_node *dnode)
 {
        return NB_OK;
 }
 
 static int isis_instance_default_information_originate_ipv4_delete(
        enum nb_event event, const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       struct isis_area *area;
+       int level;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       level = yang_dnode_get_enum(dnode, "./level");
+       isis_redist_unset(area, level, AF_INET, DEFAULT_ROUTE);
+
        return NB_OK;
 }
 
        return NB_OK;
 }
 
@@ -867,14 +912,14 @@ static int isis_instance_default_information_originate_ipv4_always_create(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       /* It's all done by default_info_origin_apply_finish */
        return NB_OK;
 }
 
 static int isis_instance_default_information_originate_ipv4_always_delete(
        enum nb_event event, const struct lyd_node *dnode)
 {
        return NB_OK;
 }
 
 static int isis_instance_default_information_originate_ipv4_always_delete(
        enum nb_event event, const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       /* It's all done by default_info_origin_apply_finish */
        return NB_OK;
 }
 
        return NB_OK;
 }
 
@@ -885,14 +930,14 @@ static int isis_instance_default_information_originate_ipv4_route_map_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       /* It's all done by default_info_origin_apply_finish */
        return NB_OK;
 }
 
 static int isis_instance_default_information_originate_ipv4_route_map_delete(
        enum nb_event event, const struct lyd_node *dnode)
 {
        return NB_OK;
 }
 
 static int isis_instance_default_information_originate_ipv4_route_map_delete(
        enum nb_event event, const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       /* It's all done by default_info_origin_apply_finish */
        return NB_OK;
 }
 
        return NB_OK;
 }
 
@@ -903,14 +948,14 @@ static int isis_instance_default_information_originate_ipv4_metric_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       /* It's all done by default_info_origin_apply_finish */
        return NB_OK;
 }
 
 static int isis_instance_default_information_originate_ipv4_metric_delete(
        enum nb_event event, const struct lyd_node *dnode)
 {
        return NB_OK;
 }
 
 static int isis_instance_default_information_originate_ipv4_metric_delete(
        enum nb_event event, const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       /* It's all done by default_info_origin_apply_finish */
        return NB_OK;
 }
 
        return NB_OK;
 }
 
@@ -921,14 +966,23 @@ static int isis_instance_default_information_originate_ipv6_create(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       /* It's all done by default_info_origin_apply_finish */
        return NB_OK;
 }
 
 static int isis_instance_default_information_originate_ipv6_delete(
        enum nb_event event, const struct lyd_node *dnode)
 {
        return NB_OK;
 }
 
 static int isis_instance_default_information_originate_ipv6_delete(
        enum nb_event event, const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       struct isis_area *area;
+       int level;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       area = yang_dnode_get_entry(dnode, true);
+       level = yang_dnode_get_enum(dnode, "./level");
+       isis_redist_unset(area, level, AF_INET6, DEFAULT_ROUTE);
+
        return NB_OK;
 }
 
        return NB_OK;
 }
 
@@ -939,14 +993,14 @@ static int isis_instance_default_information_originate_ipv6_always_create(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       /* It's all done by default_info_origin_apply_finish */
        return NB_OK;
 }
 
 static int isis_instance_default_information_originate_ipv6_always_delete(
        enum nb_event event, const struct lyd_node *dnode)
 {
        return NB_OK;
 }
 
 static int isis_instance_default_information_originate_ipv6_always_delete(
        enum nb_event event, const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       /* It's all done by default_info_origin_apply_finish */
        return NB_OK;
 }
 
        return NB_OK;
 }
 
@@ -957,14 +1011,14 @@ static int isis_instance_default_information_originate_ipv6_route_map_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       /* It's all done by default_info_origin_apply_finish */
        return NB_OK;
 }
 
 static int isis_instance_default_information_originate_ipv6_route_map_delete(
        enum nb_event event, const struct lyd_node *dnode)
 {
        return NB_OK;
 }
 
 static int isis_instance_default_information_originate_ipv6_route_map_delete(
        enum nb_event event, const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       /* It's all done by default_info_origin_apply_finish */
        return NB_OK;
 }
 
        return NB_OK;
 }
 
@@ -975,14 +1029,14 @@ static int isis_instance_default_information_originate_ipv6_metric_modify(
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
        enum nb_event event, const struct lyd_node *dnode,
        union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       /* It's all done by default_info_origin_apply_finish */
        return NB_OK;
 }
 
 static int isis_instance_default_information_originate_ipv6_metric_delete(
        enum nb_event event, const struct lyd_node *dnode)
 {
        return NB_OK;
 }
 
 static int isis_instance_default_information_originate_ipv6_metric_delete(
        enum nb_event event, const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       /* It's all done by default_info_origin_apply_finish */
        return NB_OK;
 }
 
        return NB_OK;
 }
 
@@ -2202,6 +2256,8 @@ const struct frr_yang_module_info frr_isisd_info = {
                        .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4",
                        .cbs.create = isis_instance_default_information_originate_ipv4_create,
                        .cbs.delete = isis_instance_default_information_originate_ipv4_delete,
                        .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4",
                        .cbs.create = isis_instance_default_information_originate_ipv4_create,
                        .cbs.delete = isis_instance_default_information_originate_ipv4_delete,
+                       .cbs.apply_finish = default_info_origin_ipv4_apply_finish,
+                       .cbs.cli_show = cli_show_isis_def_origin_ipv4,
                },
                {
                        .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/always",
                },
                {
                        .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/always",
@@ -2222,6 +2278,8 @@ const struct frr_yang_module_info frr_isisd_info = {
                        .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6",
                        .cbs.create = isis_instance_default_information_originate_ipv6_create,
                        .cbs.delete = isis_instance_default_information_originate_ipv6_delete,
                        .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6",
                        .cbs.create = isis_instance_default_information_originate_ipv6_create,
                        .cbs.delete = isis_instance_default_information_originate_ipv6_delete,
+                       .cbs.apply_finish = default_info_origin_ipv6_apply_finish,
+                       .cbs.cli_show = cli_show_isis_def_origin_ipv6,
                },
                {
                        .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/always",
                },
                {
                        .xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/always",
index 6564149a43d99480d9bb241e288ad66abd900839..71540e9e0bd93ac66f139943c01d90798331fdd7 100644 (file)
@@ -388,9 +388,8 @@ static void isis_redist_update_zebra_subscriptions(struct isis *isis)
                }
 }
 
                }
 }
 
-static void isis_redist_set(struct isis_area *area, int level, int family,
-                           int type, uint32_t metric, const char *routemap,
-                           int originate_type)
+void isis_redist_set(struct isis_area *area, int level, int family, int type,
+                    uint32_t metric, const char *routemap, int originate_type)
 {
        int protocol = redist_protocol(family);
        struct isis_redist *redist =
 {
        int protocol = redist_protocol(family);
        struct isis_redist *redist =
@@ -445,8 +444,7 @@ static void isis_redist_set(struct isis_area *area, int level, int family,
        }
 }
 
        }
 }
 
-static void isis_redist_unset(struct isis_area *area, int level, int family,
-                             int type)
+void isis_redist_unset(struct isis_area *area, int level, int family, int type)
 {
        struct isis_redist *redist =
                get_redist_settings(area, family, type, level);
 {
        struct isis_redist *redist =
                get_redist_settings(area, family, type, level);
@@ -638,21 +636,15 @@ DEFUN (no_isis_redistribute,
        return 0;
 }
 
        return 0;
 }
 
+#ifdef FABRICD
 DEFUN (isis_default_originate,
        isis_default_originate_cmd,
        "default-information originate <ipv4|ipv6>"
 DEFUN (isis_default_originate,
        isis_default_originate_cmd,
        "default-information originate <ipv4|ipv6>"
-#ifndef FABRICD
-       " <level-1|level-2>"
-#endif
        " [always] [<metric (0-16777215)|route-map WORD>]",
        "Control distribution of default information\n"
        "Distribute a default route\n"
        "Distribute default route for IPv4\n"
        "Distribute default route for IPv6\n"
        " [always] [<metric (0-16777215)|route-map WORD>]",
        "Control distribution of default information\n"
        "Distribute a default route\n"
        "Distribute default route for IPv4\n"
        "Distribute default route for IPv6\n"
-#ifndef FABRICD
-       "Distribute default route into level-1\n"
-       "Distribute default route into level-2\n"
-#endif
        "Always advertise default route\n"
        "Metric for default route\n"
        "ISIS default metric\n"
        "Always advertise default route\n"
        "Metric for default route\n"
        "ISIS default metric\n"
@@ -660,7 +652,6 @@ DEFUN (isis_default_originate,
        "Pointer to route-map entries\n")
 {
        int idx_afi = 2;
        "Pointer to route-map entries\n")
 {
        int idx_afi = 2;
-       int idx_level = 3;
        int idx_always = fabricd ? 3 : 4;
        int idx_metric_rmap = fabricd ? 3 : 4;
        VTY_DECLVAR_CONTEXT(isis_area, area);
        int idx_always = fabricd ? 3 : 4;
        int idx_metric_rmap = fabricd ? 3 : 4;
        VTY_DECLVAR_CONTEXT(isis_area, area);
@@ -674,10 +665,7 @@ DEFUN (isis_default_originate,
        if (family < 0)
                return CMD_WARNING_CONFIG_FAILED;
 
        if (family < 0)
                return CMD_WARNING_CONFIG_FAILED;
 
-       if (fabricd)
-               level = 2;
-       else
-               level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2;
+       level = 2;
 
        if ((area->is_type & level) != level) {
                vty_out(vty, "Node is not a level-%d IS\n", level);
 
        if ((area->is_type & level) != level) {
                vty_out(vty, "Node is not a level-%d IS\n", level);
@@ -711,23 +699,14 @@ DEFUN (isis_default_originate,
 
 DEFUN (no_isis_default_originate,
        no_isis_default_originate_cmd,
 
 DEFUN (no_isis_default_originate,
        no_isis_default_originate_cmd,
-       "no default-information originate <ipv4|ipv6>"
-#ifndef FABRICD
-       " <level-1|level-2>"
-#endif
-       , NO_STR
+       "no default-information originate <ipv4|ipv6>",
+       NO_STR
        "Control distribution of default information\n"
        "Distribute a default route\n"
        "Distribute default route for IPv4\n"
        "Control distribution of default information\n"
        "Distribute a default route\n"
        "Distribute default route for IPv4\n"
-       "Distribute default route for IPv6\n"
-#ifndef FABRICD
-       "Distribute default route into level-1\n"
-       "Distribute default route into level-2\n"
-#endif
-       )
+       "Distribute default route for IPv6\n")
 {
        int idx_afi = 3;
 {
        int idx_afi = 3;
-       int idx_level = 4;
        VTY_DECLVAR_CONTEXT(isis_area, area);
        int family;
        int level;
        VTY_DECLVAR_CONTEXT(isis_area, area);
        int family;
        int level;
@@ -736,18 +715,12 @@ DEFUN (no_isis_default_originate,
        if (family < 0)
                return CMD_WARNING_CONFIG_FAILED;
 
        if (family < 0)
                return CMD_WARNING_CONFIG_FAILED;
 
-       if (fabricd)
-               level = 2;
-       else if (strmatch("level-1", argv[idx_level]->text))
-               level = 1;
-       else if (strmatch("level-2", argv[idx_level]->text))
-               level = 2;
-       else
-               return CMD_WARNING_CONFIG_FAILED;
+       level = 2;
 
        isis_redist_unset(area, level, family, DEFAULT_ROUTE);
        return 0;
 }
 
        isis_redist_unset(area, level, family, DEFAULT_ROUTE);
        return 0;
 }
+#endif /* ifdef FABRICD */
 
 int isis_redist_config_write(struct vty *vty, struct isis_area *area,
                             int family)
 
 int isis_redist_config_write(struct vty *vty, struct isis_area *area,
                             int family)
@@ -812,6 +785,8 @@ void isis_redist_init(void)
 {
        install_element(ROUTER_NODE, &isis_redistribute_cmd);
        install_element(ROUTER_NODE, &no_isis_redistribute_cmd);
 {
        install_element(ROUTER_NODE, &isis_redistribute_cmd);
        install_element(ROUTER_NODE, &no_isis_redistribute_cmd);
+#ifdef FABRICD
        install_element(ROUTER_NODE, &isis_default_originate_cmd);
        install_element(ROUTER_NODE, &no_isis_default_originate_cmd);
        install_element(ROUTER_NODE, &isis_default_originate_cmd);
        install_element(ROUTER_NODE, &no_isis_default_originate_cmd);
+#endif /* ifdef FABRICD */
 }
 }
index 95f06f71ec9a343f88e71e4fa4f88867d77797f9..9c37c310eae8e61dfa00c8a7fd9d0b639a590629 100644 (file)
@@ -55,4 +55,8 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area,
 void isis_redist_init(void);
 void isis_redist_area_finish(struct isis_area *area);
 
 void isis_redist_init(void);
 void isis_redist_area_finish(struct isis_area *area);
 
+void isis_redist_set(struct isis_area *area, int level, int family, int type,
+                    uint32_t metric, const char *routemap, int originate_type);
+void isis_redist_unset(struct isis_area *area, int level, int family, int type);
+
 #endif
 #endif