]> git.proxmox.com Git - mirror_frr.git/commitdiff
ripd: implement the 'clear-rip-route' YANG RPC
authorRenato Westphal <renato@opensourcerouting.org>
Wed, 9 May 2018 04:35:04 +0000 (01:35 -0300)
committerRenato Westphal <renato@opensourcerouting.org>
Sat, 27 Oct 2018 18:16:12 +0000 (16:16 -0200)
This command deletes all received routes from the RIP routing table.
It should be used with caution as it can create black holes in the
network until RIP reconverges. Very useful to make automated testing
(e.g. ANVL) more predictable, since the internal state of ripd can be
cleared after each test.

Implement the command using a YANG RPC so that it can be executed by
other northbound clients in addition to the CLI.

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

index fda258ae88973580583bf64f98a340cf5f4deaaa..510aa661553ec1ab4cdb9bc6900d999bbdb02c4c 100644 (file)
@@ -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);
 }
index b190076f600b231f53ce07f6913dda47ef4d33ef..c6d2dc2162eb62308e75ffecaca42559bfe291b9 100644 (file)
@@ -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;
 }
 
index 5dab61b4e1f22ca1b4b1d926f7faf591480cfbea..356de94931bfed6d709c2240fec23df511174ec0 100644 (file)
@@ -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);
index 81e97f842881b829e190ef9604301697f17dc369..367b1d5bfbd3e5a92753eea7f59c958b5397e898 100644 (file)
@@ -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 *);