diff --git a/ripd/rip_cli.c b/ripd/rip_cli.c index fda258ae88..510aa66155 100644 --- a/ripd/rip_cli.c +++ b/ripd/rip_cli.c @@ -1227,6 +1227,19 @@ void cli_show_ip_rip_authentication_key_chain(struct vty *vty, yang_dnode_get_string(dnode, NULL)); } +/* + * XPath: /frr-ripd:clear-rip-route + */ +DEFPY (clear_ip_rip, + clear_ip_rip_cmd, + "clear ip rip", + CLEAR_STR + IP_STR + "Clear IP RIP database\n") +{ + return nb_cli_rpc("/frr-ripd:clear-rip-route", NULL, NULL); +} + void rip_cli_init(void) { install_element(CONFIG_NODE, &router_rip_cmd); @@ -1269,4 +1282,5 @@ void rip_cli_init(void) install_element(INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd); + install_element(ENABLE_NODE, &clear_ip_rip_cmd); } diff --git a/ripd/rip_northbound.c b/ripd/rip_northbound.c index b190076f60..c6d2dc2162 100644 --- a/ripd/rip_northbound.c +++ b/ripd/rip_northbound.c @@ -1206,7 +1206,40 @@ ripd_state_routes_route_metric_get_elem(const char *xpath, static int clear_rip_route_rpc(const char *xpath, const struct list *input, struct list *output) { - /* TODO: implement me. */ + struct route_node *rp; + struct rip_info *rinfo; + struct list *list; + struct listnode *listnode; + + /* Clear received RIP routes */ + for (rp = route_top(rip->table); rp; rp = route_next(rp)) { + list = rp->info; + if (!list) + continue; + + for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { + if (!rip_route_rte(rinfo)) + continue; + + if (CHECK_FLAG(rinfo->flags, RIP_RTF_FIB)) + rip_zebra_ipv4_delete(rp); + break; + } + + if (rinfo) { + RIP_TIMER_OFF(rinfo->t_timeout); + RIP_TIMER_OFF(rinfo->t_garbage_collect); + listnode_delete(list, rinfo); + rip_info_free(rinfo); + } + + if (list_isempty(list)) { + list_delete(&list); + rp->info = NULL; + route_unlock_node(rp); + } + } + return NB_OK; } diff --git a/ripd/ripd.c b/ripd/ripd.c index 5dab61b4e1..356de94931 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -95,7 +95,7 @@ static int sockopt_broadcast(int sock) return 0; } -static int rip_route_rte(struct rip_info *rinfo) +int rip_route_rte(struct rip_info *rinfo) { return (rinfo->type == ZEBRA_ROUTE_RIP && rinfo->sub_type == RIP_ROUTE_RTE); diff --git a/ripd/ripd.h b/ripd/ripd.h index 81e97f8428..367b1d5bfb 100644 --- a/ripd/ripd.h +++ b/ripd/ripd.h @@ -437,6 +437,7 @@ extern void rip_distance_free(struct rip_distance *rdistance); extern uint8_t rip_distance_apply(struct rip_info *); extern void rip_redistribute_clean(void); +extern int rip_route_rte(struct rip_info *rinfo); extern struct rip_info *rip_ecmp_add(struct rip_info *); extern struct rip_info *rip_ecmp_replace(struct rip_info *); extern struct rip_info *rip_ecmp_delete(struct rip_info *);