]> git.proxmox.com Git - mirror_frr.git/commitdiff
ripd: retrofit the 'distance source' commands to the new northbound model
authorRenato Westphal <renato@opensourcerouting.org>
Wed, 9 May 2018 04:34:59 +0000 (01:34 -0300)
committerRenato Westphal <renato@opensourcerouting.org>
Sat, 27 Oct 2018 18:16:12 +0000 (16:16 -0200)
The "distance (1-255) A.B.C.D/M [WORD]" command was modeled using a
YANG list, which makes it a little bit more complicated to convert to
the new northbound model.

The rip_distance_set() and rip_distance_unset() functions were removed
since they set/unset multiple configuration options at the same time. The
northbound callbacks need to set/unset configuration options individually.

When a distance list is created, use yang_dnode_set_entry() to store
a pointer in the configuration node, and retrieve this pointer in the
other callbacks using yang_dnode_get_entry().

The 'rip_distance' structure was moved to ripd.h so that it can be used
in the rip_northbound.c file.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
ripd/rip_cli.c
ripd/rip_cli.h
ripd/rip_northbound.c
ripd/ripd.c
ripd/ripd.h

index b9824d352fb09f59c64998daec8f7a22f66410cf..4f394bf19e25db8136ab29c2fcb994e7e5d7a318 100644 (file)
@@ -234,6 +234,76 @@ void cli_show_rip_distance(struct vty *vty, struct lyd_node *dnode,
        vty_out(vty, " distance %s\n", yang_dnode_get_string(dnode, NULL));
 }
 
+/*
+ * XPath: /frr-ripd:ripd/instance/distance/source
+ */
+DEFPY (rip_distance_source,
+       rip_distance_source_cmd,
+       "distance (1-255) A.B.C.D/M$prefix [WORD$acl]",
+       "Administrative distance\n"
+       "Distance value\n"
+       "IP source prefix\n"
+       "Access list name\n")
+{
+       char xpath_list[XPATH_MAXLEN];
+       struct cli_config_change changes[] = {
+               {
+                       .xpath = ".",
+                       .operation = NB_OP_CREATE,
+               },
+               {
+                       .xpath = "./distance",
+                       .operation = NB_OP_MODIFY,
+                       .value = distance_str,
+               },
+               {
+                       .xpath = "./access-list",
+                       .operation = acl ? NB_OP_MODIFY : NB_OP_DELETE,
+                       .value = acl,
+               },
+       };
+
+       snprintf(xpath_list, sizeof(xpath_list),
+                "./distance/source[prefix='%s']", prefix_str);
+
+       return nb_cli_cfg_change(vty, xpath_list, changes, array_size(changes));
+}
+
+DEFPY (no_rip_distance_source,
+       no_rip_distance_source_cmd,
+       "no distance (1-255) A.B.C.D/M$prefix [WORD$acl]",
+       NO_STR
+       "Administrative distance\n"
+       "Distance value\n"
+       "IP source prefix\n"
+       "Access list name\n")
+{
+       char xpath_list[XPATH_MAXLEN];
+       struct cli_config_change changes[] = {
+               {
+                       .xpath = ".",
+                       .operation = NB_OP_DELETE,
+               },
+       };
+
+       snprintf(xpath_list, sizeof(xpath_list),
+                "./distance/source[prefix='%s']", prefix_str);
+
+       return nb_cli_cfg_change(vty, xpath_list, changes, 1);
+}
+
+void cli_show_rip_distance_source(struct vty *vty, struct lyd_node *dnode,
+                                 bool show_defaults)
+{
+       vty_out(vty, " distance %s %s",
+               yang_dnode_get_string(dnode, "./distance"),
+               yang_dnode_get_string(dnode, "./prefix"));
+       if (yang_dnode_exists(dnode, "./access-list"))
+               vty_out(vty, " %s",
+                       yang_dnode_get_string(dnode, "./access-list"));
+       vty_out(vty, "\n");
+}
+
 void rip_cli_init(void)
 {
        install_element(CONFIG_NODE, &router_rip_cmd);
@@ -245,4 +315,6 @@ void rip_cli_init(void)
        install_element(RIP_NODE, &no_rip_default_metric_cmd);
        install_element(RIP_NODE, &rip_distance_cmd);
        install_element(RIP_NODE, &no_rip_distance_cmd);
+       install_element(RIP_NODE, &rip_distance_source_cmd);
+       install_element(RIP_NODE, &no_rip_distance_source_cmd);
 }
index 1e2faac7f873f1400eeae8c27d86f9b1ea01e86b..dd810fb70e500d38ae7ca2bb78e7f855a771a999 100644 (file)
@@ -32,5 +32,8 @@ extern void cli_show_rip_default_metric(struct vty *vty, struct lyd_node *dnode,
                                        bool show_defaults);
 extern void cli_show_rip_distance(struct vty *vty, struct lyd_node *dnode,
                                  bool show_defaults);
+extern void cli_show_rip_distance_source(struct vty *vty,
+                                        struct lyd_node *dnode,
+                                        bool show_defaults);
 
 #endif /* _FRR_RIP_CLI_H_ */
index 79b3d252e1eea4944de55014519e6574a8455048..25c279a773b6d0d1a1187dd948244ae044819b0a 100644 (file)
@@ -162,14 +162,40 @@ static int ripd_instance_distance_source_create(enum nb_event event,
                                                const struct lyd_node *dnode,
                                                union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       struct prefix_ipv4 prefix;
+       struct route_node *rn;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       yang_dnode_get_ipv4p(&prefix, dnode, "./prefix");
+
+       /* Get RIP distance node. */
+       rn = route_node_get(rip_distance_table, (struct prefix *)&prefix);
+       rn->info = rip_distance_new();
+       yang_dnode_set_entry(dnode, rn);
+
        return NB_OK;
 }
 
 static int ripd_instance_distance_source_delete(enum nb_event event,
                                                const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       struct route_node *rn;
+       struct rip_distance *rdistance;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       rn = yang_dnode_get_entry(dnode);
+       rdistance = rn->info;
+       if (rdistance->access_list)
+               free(rdistance->access_list);
+       rip_distance_free(rdistance);
+
+       rn->info = NULL;
+       route_unlock_node(rn);
+
        return NB_OK;
 }
 
@@ -181,7 +207,19 @@ ripd_instance_distance_source_distance_modify(enum nb_event event,
                                              const struct lyd_node *dnode,
                                              union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       struct route_node *rn;
+       uint8_t distance;
+       struct rip_distance *rdistance;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       /* Set distance value. */
+       rn = yang_dnode_get_entry(dnode);
+       distance = yang_dnode_get_uint8(dnode, NULL);
+       rdistance = rn->info;
+       rdistance->distance = distance;
+
        return NB_OK;
 }
 
@@ -193,7 +231,22 @@ ripd_instance_distance_source_access_list_modify(enum nb_event event,
                                                 const struct lyd_node *dnode,
                                                 union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       const char *acl_name;
+       struct route_node *rn;
+       struct rip_distance *rdistance;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       acl_name = yang_dnode_get_string(dnode, NULL);
+
+       /* Set access-list */
+       rn = yang_dnode_get_entry(dnode);
+       rdistance = rn->info;
+       if (rdistance->access_list)
+               free(rdistance->access_list);
+       rdistance->access_list = strdup(acl_name);
+
        return NB_OK;
 }
 
@@ -201,7 +254,18 @@ static int
 ripd_instance_distance_source_access_list_delete(enum nb_event event,
                                                 const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       struct route_node *rn;
+       struct rip_distance *rdistance;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       /* Reset access-list configuration. */
+       rn = yang_dnode_get_entry(dnode);
+       rdistance = rn->info;
+       free(rdistance->access_list);
+       rdistance->access_list = NULL;
+
        return NB_OK;
 }
 
@@ -779,6 +843,7 @@ const struct frr_yang_module_info frr_ripd_info = {
                        .xpath = "/frr-ripd:ripd/instance/distance/source",
                        .cbs.create = ripd_instance_distance_source_create,
                        .cbs.delete = ripd_instance_distance_source_delete,
+                       .cbs.cli_show = cli_show_rip_distance_source,
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/distance/source/distance",
index d85ebcc5343c40eef81b6ec1f5cfeca800d67f58..4dbb47ebd235ac496ff65a4e92ecf4d65c5d1728 100644 (file)
@@ -3001,98 +3001,16 @@ DEFUN (no_rip_timers,
 
 struct route_table *rip_distance_table;
 
-struct rip_distance {
-       /* Distance value for the IP source prefix. */
-       uint8_t distance;
-
-       /* Name of the access-list to be matched. */
-       char *access_list;
-};
-
-static struct rip_distance *rip_distance_new(void)
+struct rip_distance *rip_distance_new(void)
 {
        return XCALLOC(MTYPE_RIP_DISTANCE, sizeof(struct rip_distance));
 }
 
-static void rip_distance_free(struct rip_distance *rdistance)
+void rip_distance_free(struct rip_distance *rdistance)
 {
        XFREE(MTYPE_RIP_DISTANCE, rdistance);
 }
 
-static int rip_distance_set(struct vty *vty, const char *distance_str,
-                           const char *ip_str, const char *access_list_str)
-{
-       int ret;
-       struct prefix_ipv4 p;
-       uint8_t distance;
-       struct route_node *rn;
-       struct rip_distance *rdistance;
-
-       ret = str2prefix_ipv4(ip_str, &p);
-       if (ret == 0) {
-               vty_out(vty, "Malformed prefix\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       distance = atoi(distance_str);
-
-       /* Get RIP distance node. */
-       rn = route_node_get(rip_distance_table, (struct prefix *)&p);
-       if (rn->info) {
-               rdistance = rn->info;
-               route_unlock_node(rn);
-       } else {
-               rdistance = rip_distance_new();
-               rn->info = rdistance;
-       }
-
-       /* Set distance value. */
-       rdistance->distance = distance;
-
-       /* Reset access-list configuration. */
-       if (rdistance->access_list) {
-               free(rdistance->access_list);
-               rdistance->access_list = NULL;
-       }
-       if (access_list_str)
-               rdistance->access_list = strdup(access_list_str);
-
-       return CMD_SUCCESS;
-}
-
-static int rip_distance_unset(struct vty *vty, const char *distance_str,
-                             const char *ip_str, const char *access_list_str)
-{
-       int ret;
-       struct prefix_ipv4 p;
-       struct route_node *rn;
-       struct rip_distance *rdistance;
-
-       ret = str2prefix_ipv4(ip_str, &p);
-       if (ret == 0) {
-               vty_out(vty, "Malformed prefix\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       rn = route_node_lookup(rip_distance_table, (struct prefix *)&p);
-       if (!rn) {
-               vty_out(vty, "Can't find specified prefix\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       rdistance = rn->info;
-
-       if (rdistance->access_list)
-               free(rdistance->access_list);
-       rip_distance_free(rdistance);
-
-       rn->info = NULL;
-       route_unlock_node(rn);
-       route_unlock_node(rn);
-
-       return CMD_SUCCESS;
-}
-
 static void rip_distance_reset(void)
 {
        struct route_node *rn;
@@ -3176,68 +3094,6 @@ static void rip_distance_show(struct vty *vty)
                }
 }
 
-DEFUN (rip_distance_source,
-       rip_distance_source_cmd,
-       "distance (1-255) A.B.C.D/M",
-       "Administrative distance\n"
-       "Distance value\n"
-       "IP source prefix\n")
-{
-       int idx_number = 1;
-       int idx_ipv4_prefixlen = 2;
-       rip_distance_set(vty, argv[idx_number]->arg,
-                        argv[idx_ipv4_prefixlen]->arg, NULL);
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_rip_distance_source,
-       no_rip_distance_source_cmd,
-       "no distance (1-255) A.B.C.D/M",
-       NO_STR
-       "Administrative distance\n"
-       "Distance value\n"
-       "IP source prefix\n")
-{
-       int idx_number = 2;
-       int idx_ipv4_prefixlen = 3;
-       rip_distance_unset(vty, argv[idx_number]->arg,
-                          argv[idx_ipv4_prefixlen]->arg, NULL);
-       return CMD_SUCCESS;
-}
-
-DEFUN (rip_distance_source_access_list,
-       rip_distance_source_access_list_cmd,
-       "distance (1-255) A.B.C.D/M WORD",
-       "Administrative distance\n"
-       "Distance value\n"
-       "IP source prefix\n"
-       "Access list name\n")
-{
-       int idx_number = 1;
-       int idx_ipv4_prefixlen = 2;
-       int idx_word = 3;
-       rip_distance_set(vty, argv[idx_number]->arg,
-                        argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_rip_distance_source_access_list,
-       no_rip_distance_source_access_list_cmd,
-       "no distance (1-255) A.B.C.D/M WORD",
-       NO_STR
-       "Administrative distance\n"
-       "Distance value\n"
-       "IP source prefix\n"
-       "Access list name\n")
-{
-       int idx_number = 2;
-       int idx_ipv4_prefixlen = 3;
-       int idx_word = 4;
-       rip_distance_unset(vty, argv[idx_number]->arg,
-                          argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
-       return CMD_SUCCESS;
-}
-
 /* Update ECMP routes to zebra when ECMP is disabled. */
 void rip_ecmp_disable(void)
 {
@@ -3531,7 +3387,6 @@ static int config_write_rip(struct vty *vty)
 {
        int write = 0;
        struct route_node *rn;
-       struct rip_distance *rdistance;
        struct lyd_node *dnode;
 
        dnode = yang_dnode_get(running_config->dnode,
@@ -3569,18 +3424,6 @@ static int config_write_rip(struct vty *vty)
                /* Interface routemap configuration */
                write += config_write_if_rmap(vty);
 
-               /* RIP source IP prefix distance configuration. */
-               for (rn = route_top(rip_distance_table); rn;
-                    rn = route_next(rn))
-                       if ((rdistance = rn->info) != NULL)
-                               vty_out(vty, " distance %d %s/%d %s\n",
-                                       rdistance->distance,
-                                       inet_ntoa(rn->p.u.prefix4),
-                                       rn->p.prefixlen,
-                                       rdistance->access_list
-                                               ? rdistance->access_list
-                                               : "");
-
                /* RIP static route configuration. */
                for (rn = route_top(rip->route); rn; rn = route_next(rn))
                        if (rn->info)
@@ -3863,10 +3706,6 @@ void rip_init(void)
        install_element(RIP_NODE, &no_rip_timers_cmd);
        install_element(RIP_NODE, &rip_route_cmd);
        install_element(RIP_NODE, &no_rip_route_cmd);
-       install_element(RIP_NODE, &rip_distance_source_cmd);
-       install_element(RIP_NODE, &no_rip_distance_source_cmd);
-       install_element(RIP_NODE, &rip_distance_source_access_list_cmd);
-       install_element(RIP_NODE, &no_rip_distance_source_access_list_cmd);
 
        /* Debug related init. */
        rip_debug_init();
index 1ecedf3680f03e9546802056d2db64718e87f0b7..31697264a0aeca53fc2469fa5a101031acae4ee1 100644 (file)
@@ -320,6 +320,14 @@ struct rip_peer {
        struct thread *t_timeout;
 };
 
+struct rip_distance {
+       /* Distance value for the IP source prefix. */
+       uint8_t distance;
+
+       /* Name of the access-list to be matched. */
+       char *access_list;
+};
+
 struct rip_md5_info {
        uint16_t family;
        uint16_t type;
@@ -417,6 +425,8 @@ extern int rip_offset_list_apply_out(struct prefix_ipv4 *, struct interface *,
 extern void rip_offset_clean(void);
 
 extern void rip_info_free(struct rip_info *);
+extern struct rip_distance *rip_distance_new(void);
+extern void rip_distance_free(struct rip_distance *rdistance);
 extern uint8_t rip_distance_apply(struct rip_info *);
 extern void rip_redistribute_clean(void);
 
@@ -439,6 +449,8 @@ extern long rip_global_queries;
 DECLARE_HOOK(rip_ifaddr_add, (struct connected * ifc), (ifc))
 DECLARE_HOOK(rip_ifaddr_del, (struct connected * ifc), (ifc))
 
+extern struct route_table *rip_distance_table;
+
 /* Northbound. */
 extern void rip_cli_init(void);
 extern const struct frr_yang_module_info frr_ripd_info;