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);
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);
}
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_ */
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;
}
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;
}
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;
}
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;
}
.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",
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;
}
}
-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)
{
{
int write = 0;
struct route_node *rn;
- struct rip_distance *rdistance;
struct lyd_node *dnode;
dnode = yang_dnode_get(running_config->dnode,
/* 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)
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();
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;
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);
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;