]> git.proxmox.com Git - mirror_frr.git/blame - ripd/rip_cli.c
Merge pull request #6845 from opensourcerouting/foreach-safi-formatting
[mirror_frr.git] / ripd / rip_cli.c
CommitLineData
707656ec
RW
1/*
2 * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
3 * Copyright (C) 2018 NetDEF, Inc.
4 * Renato Westphal
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <zebra.h>
22
23#include "if.h"
24#include "vrf.h"
25#include "log.h"
26#include "prefix.h"
27#include "command.h"
28#include "northbound_cli.h"
29#include "libfrr.h"
30
31#include "ripd/ripd.h"
f80ec39e 32#include "ripd/rip_nb.h"
707656ec
RW
33#ifndef VTYSH_EXTRACT_PL
34#include "ripd/rip_cli_clippy.c"
35#endif
36
8c9226c2
RW
37/*
38 * XPath: /frr-ripd:ripd/instance
39 */
40DEFPY_NOSH (router_rip,
41 router_rip_cmd,
ae7b826a 42 "router rip [vrf NAME]",
8c9226c2 43 "Enable a routing process\n"
ae7b826a
RW
44 "Routing Information Protocol (RIP)\n"
45 VRF_CMD_HELP_STR)
8c9226c2 46{
ae7b826a 47 char xpath[XPATH_MAXLEN];
8c9226c2
RW
48 int ret;
49
ae7b826a
RW
50 /* Build RIP instance XPath. */
51 if (!vrf)
52 vrf = VRF_DEFAULT_NAME;
53 snprintf(xpath, sizeof(xpath), "/frr-ripd:ripd/instance[vrf='%s']",
54 vrf);
55
56 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
a6233bfc
RW
57
58 ret = nb_cli_apply_changes(vty, NULL);
8c9226c2 59 if (ret == CMD_SUCCESS)
ae7b826a 60 VTY_PUSH_XPATH(RIP_NODE, xpath);
8c9226c2
RW
61
62 return ret;
63}
64
65DEFPY (no_router_rip,
66 no_router_rip_cmd,
ae7b826a 67 "no router rip [vrf NAME]",
8c9226c2
RW
68 NO_STR
69 "Enable a routing process\n"
ae7b826a
RW
70 "Routing Information Protocol (RIP)\n"
71 VRF_CMD_HELP_STR)
8c9226c2 72{
ae7b826a
RW
73 char xpath[XPATH_MAXLEN];
74
75 /* Build RIP instance XPath. */
76 if (!vrf)
77 vrf = VRF_DEFAULT_NAME;
78 snprintf(xpath, sizeof(xpath), "/frr-ripd:ripd/instance[vrf='%s']",
79 vrf);
80
8f88441d 81 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
a6233bfc
RW
82
83 return nb_cli_apply_changes(vty, NULL);
8c9226c2
RW
84}
85
86void cli_show_router_rip(struct vty *vty, struct lyd_node *dnode,
87 bool show_defaults)
88{
ae7b826a
RW
89 const char *vrf_name;
90
91 vrf_name = yang_dnode_get_string(dnode, "./vrf");
92
8c9226c2 93 vty_out(vty, "!\n");
ae7b826a
RW
94 vty_out(vty, "router rip");
95 if (!strmatch(vrf_name, VRF_DEFAULT_NAME))
96 vty_out(vty, " vrf %s", vrf_name);
97 vty_out(vty, "\n");
8c9226c2
RW
98}
99
edbf59d2
RW
100/*
101 * XPath: /frr-ripd:ripd/instance/allow-ecmp
102 */
103DEFPY (rip_allow_ecmp,
104 rip_allow_ecmp_cmd,
105 "[no] allow-ecmp",
106 NO_STR
107 "Allow Equal Cost MultiPath\n")
108{
a6233bfc
RW
109 nb_cli_enqueue_change(vty, "./allow-ecmp", NB_OP_MODIFY,
110 no ? "false" : "true");
111
112 return nb_cli_apply_changes(vty, NULL);
edbf59d2
RW
113}
114
115void cli_show_rip_allow_ecmp(struct vty *vty, struct lyd_node *dnode,
116 bool show_defaults)
117{
118 if (!yang_dnode_get_bool(dnode, NULL))
119 vty_out(vty, " no");
120
121 vty_out(vty, " allow-ecmp\n");
122}
123
0b0609ba
RW
124/*
125 * XPath: /frr-ripd:ripd/instance/default-information-originate
126 */
127DEFPY (rip_default_information_originate,
128 rip_default_information_originate_cmd,
129 "[no] default-information originate",
130 NO_STR
131 "Control distribution of default route\n"
132 "Distribute a default route\n")
133{
a6233bfc
RW
134 nb_cli_enqueue_change(vty, "./default-information-originate",
135 NB_OP_MODIFY, no ? "false" : "true");
136
137 return nb_cli_apply_changes(vty, NULL);
0b0609ba
RW
138}
139
140void cli_show_rip_default_information_originate(struct vty *vty,
141 struct lyd_node *dnode,
142 bool show_defaults)
143{
144 if (!yang_dnode_get_bool(dnode, NULL))
145 vty_out(vty, " no");
146
147 vty_out(vty, " default-information originate\n");
148}
149
282ae30c
RW
150/*
151 * XPath: /frr-ripd:ripd/instance/default-metric
152 */
153DEFPY (rip_default_metric,
154 rip_default_metric_cmd,
155 "default-metric (1-16)",
156 "Set a metric of redistribute routes\n"
157 "Default metric\n")
158{
a6233bfc
RW
159 nb_cli_enqueue_change(vty, "./default-metric", NB_OP_MODIFY,
160 default_metric_str);
161
162 return nb_cli_apply_changes(vty, NULL);
282ae30c
RW
163}
164
165DEFPY (no_rip_default_metric,
166 no_rip_default_metric_cmd,
167 "no default-metric [(1-16)]",
168 NO_STR
169 "Set a metric of redistribute routes\n"
170 "Default metric\n")
171{
a6233bfc
RW
172 nb_cli_enqueue_change(vty, "./default-metric", NB_OP_MODIFY, NULL);
173
174 return nb_cli_apply_changes(vty, NULL);
282ae30c
RW
175}
176
177void cli_show_rip_default_metric(struct vty *vty, struct lyd_node *dnode,
178 bool show_defaults)
179{
180 vty_out(vty, " default-metric %s\n",
181 yang_dnode_get_string(dnode, NULL));
182}
183
7f8a9cba
RW
184/*
185 * XPath: /frr-ripd:ripd/instance/distance/default
186 */
187DEFPY (rip_distance,
188 rip_distance_cmd,
189 "distance (1-255)",
190 "Administrative distance\n"
191 "Distance value\n")
192{
a6233bfc
RW
193 nb_cli_enqueue_change(vty, "./distance/default", NB_OP_MODIFY,
194 distance_str);
195
196 return nb_cli_apply_changes(vty, NULL);
7f8a9cba
RW
197}
198
199DEFPY (no_rip_distance,
200 no_rip_distance_cmd,
201 "no distance [(1-255)]",
202 NO_STR
203 "Administrative distance\n"
204 "Distance value\n")
205{
a6233bfc
RW
206 nb_cli_enqueue_change(vty, "./distance/default", NB_OP_MODIFY, NULL);
207
208 return nb_cli_apply_changes(vty, NULL);
7f8a9cba
RW
209}
210
211void cli_show_rip_distance(struct vty *vty, struct lyd_node *dnode,
212 bool show_defaults)
213{
bb5b9c10
RW
214 if (yang_dnode_is_default(dnode, NULL))
215 vty_out(vty, " no distance\n");
216 else
217 vty_out(vty, " distance %s\n",
218 yang_dnode_get_string(dnode, NULL));
7f8a9cba
RW
219}
220
23b23d8c
RW
221/*
222 * XPath: /frr-ripd:ripd/instance/distance/source
223 */
224DEFPY (rip_distance_source,
225 rip_distance_source_cmd,
a6233bfc 226 "[no] distance (1-255) A.B.C.D/M$prefix [WORD$acl]",
23b23d8c
RW
227 NO_STR
228 "Administrative distance\n"
229 "Distance value\n"
230 "IP source prefix\n"
231 "Access list name\n")
232{
a6233bfc
RW
233 if (!no) {
234 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
d682d365
RW
235 nb_cli_enqueue_change(vty, "./distance", NB_OP_MODIFY,
236 distance_str);
a6233bfc 237 nb_cli_enqueue_change(vty, "./access-list",
95ce849b 238 acl ? NB_OP_MODIFY : NB_OP_DESTROY, acl);
a6233bfc 239 } else
95ce849b 240 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
a6233bfc
RW
241
242 return nb_cli_apply_changes(vty, "./distance/source[prefix='%s']",
243 prefix_str);
23b23d8c
RW
244}
245
246void cli_show_rip_distance_source(struct vty *vty, struct lyd_node *dnode,
247 bool show_defaults)
248{
249 vty_out(vty, " distance %s %s",
250 yang_dnode_get_string(dnode, "./distance"),
251 yang_dnode_get_string(dnode, "./prefix"));
252 if (yang_dnode_exists(dnode, "./access-list"))
253 vty_out(vty, " %s",
254 yang_dnode_get_string(dnode, "./access-list"));
255 vty_out(vty, "\n");
256}
257
f0ab22fb
RW
258/*
259 * XPath: /frr-ripd:ripd/instance/explicit-neighbor
260 */
261DEFPY (rip_neighbor,
262 rip_neighbor_cmd,
263 "[no] neighbor A.B.C.D",
264 NO_STR
265 "Specify a neighbor router\n"
266 "Neighbor address\n")
267{
a6233bfc 268 nb_cli_enqueue_change(vty, "./explicit-neighbor",
95ce849b 269 no ? NB_OP_DESTROY : NB_OP_CREATE, neighbor_str);
a6233bfc
RW
270
271 return nb_cli_apply_changes(vty, NULL);
f0ab22fb
RW
272}
273
274void cli_show_rip_neighbor(struct vty *vty, struct lyd_node *dnode,
275 bool show_defaults)
276{
277 vty_out(vty, " neighbor %s\n", yang_dnode_get_string(dnode, NULL));
278}
279
3d7a1be8
RW
280/*
281 * XPath: /frr-ripd:ripd/instance/network
282 */
283DEFPY (rip_network_prefix,
284 rip_network_prefix_cmd,
285 "[no] network A.B.C.D/M",
286 NO_STR
287 "Enable routing on an IP network\n"
288 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
289{
a6233bfc 290 nb_cli_enqueue_change(vty, "./network",
95ce849b 291 no ? NB_OP_DESTROY : NB_OP_CREATE, network_str);
a6233bfc
RW
292
293 return nb_cli_apply_changes(vty, NULL);
3d7a1be8
RW
294}
295
296void cli_show_rip_network_prefix(struct vty *vty, struct lyd_node *dnode,
297 bool show_defaults)
298{
299 vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL));
300}
301
302/*
303 * XPath: /frr-ripd:ripd/instance/interface
304 */
305DEFPY (rip_network_if,
306 rip_network_if_cmd,
307 "[no] network WORD",
308 NO_STR
309 "Enable routing on an IP network\n"
310 "Interface name\n")
311{
a6233bfc 312 nb_cli_enqueue_change(vty, "./interface",
95ce849b 313 no ? NB_OP_DESTROY : NB_OP_CREATE, network);
a6233bfc
RW
314
315 return nb_cli_apply_changes(vty, NULL);
3d7a1be8
RW
316}
317
318void cli_show_rip_network_interface(struct vty *vty, struct lyd_node *dnode,
319 bool show_defaults)
320{
321 vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL));
322}
323
8c942f65
RW
324/*
325 * XPath: /frr-ripd:ripd/instance/offset-list
326 */
327DEFPY (rip_offset_list,
328 rip_offset_list_cmd,
a6233bfc 329 "[no] offset-list WORD$acl <in|out>$direction (0-16)$metric [IFNAME]",
8c942f65
RW
330 NO_STR
331 "Modify RIP metric\n"
332 "Access-list name\n"
333 "For incoming updates\n"
334 "For outgoing updates\n"
335 "Metric value\n"
336 "Interface to match\n")
337{
a6233bfc
RW
338 if (!no) {
339 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
340 nb_cli_enqueue_change(vty, "./access-list", NB_OP_MODIFY, acl);
341 nb_cli_enqueue_change(vty, "./metric", NB_OP_MODIFY,
342 metric_str);
343 } else
95ce849b 344 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
a6233bfc
RW
345
346 return nb_cli_apply_changes(
347 vty, "./offset-list[interface='%s'][direction='%s']",
348 ifname ? ifname : "*", direction);
8c942f65
RW
349}
350
351void cli_show_rip_offset_list(struct vty *vty, struct lyd_node *dnode,
352 bool show_defaults)
353{
354 const char *interface;
355
356 interface = yang_dnode_get_string(dnode, "./interface");
357
358 vty_out(vty, " offset-list %s %s %s",
359 yang_dnode_get_string(dnode, "./access-list"),
360 yang_dnode_get_string(dnode, "./direction"),
361 yang_dnode_get_string(dnode, "./metric"));
362 if (!strmatch(interface, "*"))
363 vty_out(vty, " %s", interface);
364 vty_out(vty, "\n");
365}
366
44f2f852
RW
367/*
368 * XPath: /frr-ripd:ripd/instance/passive-default
369 */
370DEFPY (rip_passive_default,
371 rip_passive_default_cmd,
372 "[no] passive-interface default",
373 NO_STR
374 "Suppress routing updates on an interface\n"
375 "default for all interfaces\n")
376{
a6233bfc
RW
377 nb_cli_enqueue_change(vty, "./passive-default", NB_OP_MODIFY,
378 no ? "false" : "true");
379
380 return nb_cli_apply_changes(vty, NULL);
44f2f852
RW
381}
382
383void cli_show_rip_passive_default(struct vty *vty, struct lyd_node *dnode,
384 bool show_defaults)
385{
386 if (!yang_dnode_get_bool(dnode, NULL))
387 vty_out(vty, " no");
388
389 vty_out(vty, " passive-interface default\n");
390}
391
392/*
393 * XPath: /frr-ripd:ripd/instance/passive-interface
394 * /frr-ripd:ripd/instance/non-passive-interface
395 */
396DEFPY (rip_passive_interface,
397 rip_passive_interface_cmd,
398 "[no] passive-interface IFNAME",
399 NO_STR
400 "Suppress routing updates on an interface\n"
401 "Interface name\n")
402{
58e39d52
RW
403 bool passive_default =
404 yang_dnode_get_bool(vty->candidate_config->dnode, "%s%s",
405 VTY_CURR_XPATH, "/passive-default");
406
407 if (passive_default) {
408 nb_cli_enqueue_change(vty, "./non-passive-interface",
409 no ? NB_OP_CREATE : NB_OP_DESTROY,
410 ifname);
411 } else {
412 nb_cli_enqueue_change(vty, "./passive-interface",
413 no ? NB_OP_DESTROY : NB_OP_CREATE,
414 ifname);
415 }
a6233bfc
RW
416
417 return nb_cli_apply_changes(vty, NULL);
44f2f852
RW
418}
419
420void cli_show_rip_passive_interface(struct vty *vty, struct lyd_node *dnode,
421 bool show_defaults)
422{
423 vty_out(vty, " passive-interface %s\n",
424 yang_dnode_get_string(dnode, NULL));
425}
426
427void cli_show_rip_non_passive_interface(struct vty *vty, struct lyd_node *dnode,
428 bool show_defaults)
429{
430 vty_out(vty, " no passive-interface %s\n",
431 yang_dnode_get_string(dnode, NULL));
432}
433
908f0020
RW
434/*
435 * XPath: /frr-ripd:ripd/instance/redistribute
436 */
437DEFPY (rip_redistribute,
438 rip_redistribute_cmd,
a6233bfc 439 "[no] redistribute " FRR_REDIST_STR_RIPD "$protocol [{metric (0-16)|route-map WORD}]",
908f0020
RW
440 NO_STR
441 REDIST_STR
442 FRR_REDIST_HELP_STR_RIPD
443 "Metric\n"
444 "Metric value\n"
445 "Route map reference\n"
446 "Pointer to route-map entries\n")
447{
a6233bfc
RW
448 if (!no) {
449 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
450 nb_cli_enqueue_change(vty, "./route-map",
95ce849b 451 route_map ? NB_OP_MODIFY : NB_OP_DESTROY,
a6233bfc
RW
452 route_map);
453 nb_cli_enqueue_change(vty, "./metric",
95ce849b 454 metric_str ? NB_OP_MODIFY : NB_OP_DESTROY,
a6233bfc
RW
455 metric_str);
456 } else
95ce849b 457 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
a6233bfc
RW
458
459 return nb_cli_apply_changes(vty, "./redistribute[protocol='%s']",
460 protocol);
908f0020
RW
461}
462
463void cli_show_rip_redistribute(struct vty *vty, struct lyd_node *dnode,
464 bool show_defaults)
465{
466 vty_out(vty, " redistribute %s",
467 yang_dnode_get_string(dnode, "./protocol"));
468 if (yang_dnode_exists(dnode, "./metric"))
469 vty_out(vty, " metric %s",
470 yang_dnode_get_string(dnode, "./metric"));
471 if (yang_dnode_exists(dnode, "./route-map"))
472 vty_out(vty, " route-map %s",
473 yang_dnode_get_string(dnode, "./route-map"));
474 vty_out(vty, "\n");
475}
476
40687878
RW
477/*
478 * XPath: /frr-ripd:ripd/instance/static-route
479 */
480DEFPY (rip_route,
481 rip_route_cmd,
482 "[no] route A.B.C.D/M",
483 NO_STR
484 "RIP static route configuration\n"
485 "IP prefix <network>/<length>\n")
486{
a6233bfc 487 nb_cli_enqueue_change(vty, "./static-route",
95ce849b 488 no ? NB_OP_DESTROY : NB_OP_CREATE, route_str);
a6233bfc
RW
489
490 return nb_cli_apply_changes(vty, NULL);
40687878
RW
491}
492
493void cli_show_rip_route(struct vty *vty, struct lyd_node *dnode,
494 bool show_defaults)
495{
496 vty_out(vty, " route %s\n", yang_dnode_get_string(dnode, NULL));
497}
498
b745780b
RW
499/*
500 * XPath: /frr-ripd:ripd/instance/timers
501 */
502DEFPY (rip_timers,
503 rip_timers_cmd,
504 "timers basic (5-2147483647)$update (5-2147483647)$timeout (5-2147483647)$garbage",
505 "Adjust routing timers\n"
506 "Basic routing protocol update timers\n"
507 "Routing table update timer value in second. Default is 30.\n"
508 "Routing information timeout timer. Default is 180.\n"
509 "Garbage collection timer. Default is 120.\n")
510{
a6233bfc
RW
511 nb_cli_enqueue_change(vty, "./update-interval", NB_OP_MODIFY,
512 update_str);
513 nb_cli_enqueue_change(vty, "./holddown-interval", NB_OP_MODIFY,
514 timeout_str);
515 nb_cli_enqueue_change(vty, "./flush-interval", NB_OP_MODIFY,
516 garbage_str);
517
518 return nb_cli_apply_changes(vty, "./timers");
b745780b
RW
519}
520
521DEFPY (no_rip_timers,
522 no_rip_timers_cmd,
523 "no timers basic [(5-2147483647) (5-2147483647) (5-2147483647)]",
524 NO_STR
525 "Adjust routing timers\n"
526 "Basic routing protocol update timers\n"
527 "Routing table update timer value in second. Default is 30.\n"
528 "Routing information timeout timer. Default is 180.\n"
529 "Garbage collection timer. Default is 120.\n")
530{
a6233bfc
RW
531 nb_cli_enqueue_change(vty, "./update-interval", NB_OP_MODIFY, NULL);
532 nb_cli_enqueue_change(vty, "./holddown-interval", NB_OP_MODIFY, NULL);
533 nb_cli_enqueue_change(vty, "./flush-interval", NB_OP_MODIFY, NULL);
534
535 return nb_cli_apply_changes(vty, "./timers");
b745780b
RW
536}
537
538void cli_show_rip_timers(struct vty *vty, struct lyd_node *dnode,
539 bool show_defaults)
540{
541 vty_out(vty, " timers basic %s %s %s\n",
542 yang_dnode_get_string(dnode, "./update-interval"),
543 yang_dnode_get_string(dnode, "./holddown-interval"),
544 yang_dnode_get_string(dnode, "./flush-interval"));
545}
546
90eff9da
RW
547/*
548 * XPath: /frr-ripd:ripd/instance/version
549 */
550DEFPY (rip_version,
551 rip_version_cmd,
552 "version (1-2)",
553 "Set routing protocol version\n"
554 "version\n")
555{
a6233bfc
RW
556 nb_cli_enqueue_change(vty, "./version/receive", NB_OP_MODIFY,
557 version_str);
558 nb_cli_enqueue_change(vty, "./version/send", NB_OP_MODIFY, version_str);
559
560 return nb_cli_apply_changes(vty, NULL);
90eff9da
RW
561}
562
563DEFPY (no_rip_version,
564 no_rip_version_cmd,
565 "no version [(1-2)]",
566 NO_STR
567 "Set routing protocol version\n"
568 "version\n")
569{
a6233bfc
RW
570 nb_cli_enqueue_change(vty, "./version/receive", NB_OP_MODIFY, NULL);
571 nb_cli_enqueue_change(vty, "./version/send", NB_OP_MODIFY, NULL);
572
573 return nb_cli_apply_changes(vty, NULL);
90eff9da
RW
574}
575
576void cli_show_rip_version(struct vty *vty, struct lyd_node *dnode,
577 bool show_defaults)
578{
579 /*
580 * We have only one "version" command and three possible combinations of
581 * send/receive values.
582 */
583 switch (yang_dnode_get_enum(dnode, "./receive")) {
584 case RI_RIP_VERSION_1:
585 vty_out(vty, " version 1\n");
586 break;
587 case RI_RIP_VERSION_2:
588 vty_out(vty, " version 2\n");
589 break;
590 case RI_RIP_VERSION_1_AND_2:
591 vty_out(vty, " no version\n");
592 break;
593 }
594}
595
94b117b2
RW
596/*
597 * XPath: /frr-interface:lib/interface/frr-ripd:rip/split-horizon
598 */
599DEFPY (ip_rip_split_horizon,
600 ip_rip_split_horizon_cmd,
601 "[no] ip rip split-horizon [poisoned-reverse$poisoned_reverse]",
602 NO_STR
603 IP_STR
604 "Routing Information Protocol\n"
605 "Perform split horizon\n"
606 "With poisoned-reverse\n")
607{
a6233bfc 608 const char *value;
94b117b2
RW
609
610 if (no)
a6233bfc 611 value = "disabled";
94b117b2 612 else if (poisoned_reverse)
a6233bfc 613 value = "poison-reverse";
94b117b2 614 else
a6233bfc
RW
615 value = "simple";
616
617 nb_cli_enqueue_change(vty, "./split-horizon", NB_OP_MODIFY, value);
94b117b2 618
a6233bfc 619 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
620}
621
622void cli_show_ip_rip_split_horizon(struct vty *vty, struct lyd_node *dnode,
623 bool show_defaults)
624{
625 int value;
626
627 value = yang_dnode_get_enum(dnode, NULL);
628 switch (value) {
629 case RIP_NO_SPLIT_HORIZON:
630 vty_out(vty, " no ip rip split-horizon\n");
631 break;
632 case RIP_SPLIT_HORIZON:
633 vty_out(vty, " ip rip split-horizon\n");
634 break;
635 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
636 vty_out(vty, " ip rip split-horizon poisoned-reverse\n");
637 break;
638 }
639}
640
641/*
642 * XPath: /frr-interface:lib/interface/frr-ripd:rip/v2-broadcast
643 */
644DEFPY (ip_rip_v2_broadcast,
645 ip_rip_v2_broadcast_cmd,
646 "[no] ip rip v2-broadcast",
647 NO_STR
648 IP_STR
649 "Routing Information Protocol\n"
650 "Send ip broadcast v2 update\n")
651{
a6233bfc
RW
652 nb_cli_enqueue_change(vty, "./v2-broadcast", NB_OP_MODIFY,
653 no ? "false" : "true");
654
655 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
656}
657
658void cli_show_ip_rip_v2_broadcast(struct vty *vty, struct lyd_node *dnode,
659 bool show_defaults)
660{
661 if (!yang_dnode_get_bool(dnode, NULL))
662 vty_out(vty, " no");
663
664 vty_out(vty, " ip rip v2-broadcast\n");
665}
666
667/*
668 * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-receive
669 */
670DEFPY (ip_rip_receive_version,
671 ip_rip_receive_version_cmd,
672 "ip rip receive version <{1$v1|2$v2}|none>",
673 IP_STR
674 "Routing Information Protocol\n"
675 "Advertisement reception\n"
676 "Version control\n"
677 "RIP version 1\n"
678 "RIP version 2\n"
679 "None\n")
680{
a6233bfc 681 const char *value;
94b117b2
RW
682
683 if (v1 && v2)
a6233bfc 684 value = "both";
94b117b2 685 else if (v1)
a6233bfc 686 value = "1";
94b117b2 687 else if (v2)
a6233bfc 688 value = "2";
94b117b2 689 else
a6233bfc
RW
690 value = "none";
691
692 nb_cli_enqueue_change(vty, "./version-receive", NB_OP_MODIFY, value);
94b117b2 693
a6233bfc 694 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
695}
696
697DEFPY (no_ip_rip_receive_version,
698 no_ip_rip_receive_version_cmd,
699 "no ip rip receive version [<{1|2}|none>]",
700 NO_STR
701 IP_STR
702 "Routing Information Protocol\n"
703 "Advertisement reception\n"
704 "Version control\n"
705 "RIP version 1\n"
706 "RIP version 2\n"
707 "None\n")
708{
a6233bfc
RW
709 nb_cli_enqueue_change(vty, "./version-receive", NB_OP_MODIFY, NULL);
710
711 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
712}
713
714void cli_show_ip_rip_receive_version(struct vty *vty, struct lyd_node *dnode,
715 bool show_defaults)
716{
717 switch (yang_dnode_get_enum(dnode, NULL)) {
718 case RI_RIP_UNSPEC:
719 vty_out(vty, " no ip rip receive version\n");
720 break;
721 case RI_RIP_VERSION_1:
722 vty_out(vty, " ip rip receive version 1\n");
723 break;
724 case RI_RIP_VERSION_2:
725 vty_out(vty, " ip rip receive version 2\n");
726 break;
727 case RI_RIP_VERSION_1_AND_2:
728 vty_out(vty, " ip rip receive version 1 2\n");
729 break;
730 case RI_RIP_VERSION_NONE:
731 vty_out(vty, " ip rip receive version none\n");
732 break;
733 }
734}
735
736/*
737 * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-send
738 */
739DEFPY (ip_rip_send_version,
740 ip_rip_send_version_cmd,
741 "ip rip send version <{1$v1|2$v2}|none>",
742 IP_STR
743 "Routing Information Protocol\n"
744 "Advertisement transmission\n"
745 "Version control\n"
746 "RIP version 1\n"
747 "RIP version 2\n"
748 "None\n")
749{
a6233bfc 750 const char *value;
94b117b2
RW
751
752 if (v1 && v2)
a6233bfc 753 value = "both";
94b117b2 754 else if (v1)
a6233bfc 755 value = "1";
94b117b2 756 else if (v2)
a6233bfc 757 value = "2";
94b117b2 758 else
a6233bfc
RW
759 value = "none";
760
761 nb_cli_enqueue_change(vty, "./version-send", NB_OP_MODIFY, value);
94b117b2 762
a6233bfc 763 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
764}
765
766DEFPY (no_ip_rip_send_version,
767 no_ip_rip_send_version_cmd,
768 "no ip rip send version [<{1|2}|none>]",
769 NO_STR
770 IP_STR
771 "Routing Information Protocol\n"
772 "Advertisement transmission\n"
773 "Version control\n"
774 "RIP version 1\n"
775 "RIP version 2\n"
776 "None\n")
777{
a6233bfc
RW
778 nb_cli_enqueue_change(vty, "./version-send", NB_OP_MODIFY, NULL);
779
780 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
781}
782
783void cli_show_ip_rip_send_version(struct vty *vty, struct lyd_node *dnode,
784 bool show_defaults)
785{
786 switch (yang_dnode_get_enum(dnode, NULL)) {
787 case RI_RIP_UNSPEC:
788 vty_out(vty, " no ip rip send version\n");
789 break;
790 case RI_RIP_VERSION_1:
791 vty_out(vty, " ip rip send version 1\n");
792 break;
793 case RI_RIP_VERSION_2:
794 vty_out(vty, " ip rip send version 2\n");
795 break;
796 case RI_RIP_VERSION_1_AND_2:
797 vty_out(vty, " ip rip send version 1 2\n");
798 break;
799 case RI_RIP_VERSION_NONE:
800 vty_out(vty, " ip rip send version none\n");
801 break;
802 }
803}
804
805/*
806 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme
807 */
808DEFPY (ip_rip_authentication_mode,
809 ip_rip_authentication_mode_cmd,
810 "ip rip authentication mode <md5$mode [auth-length <rfc|old-ripd>$auth_length]|text$mode>",
811 IP_STR
812 "Routing Information Protocol\n"
813 "Authentication control\n"
814 "Authentication mode\n"
815 "Keyed message digest\n"
816 "MD5 authentication data length\n"
817 "RFC compatible\n"
818 "Old ripd compatible\n"
819 "Clear text authentication\n")
820{
a6233bfc 821 const char *value = NULL;
94b117b2
RW
822
823 if (auth_length) {
824 if (strmatch(auth_length, "rfc"))
a6233bfc 825 value = "16";
94b117b2 826 else
a6233bfc 827 value = "20";
94b117b2
RW
828 }
829
a6233bfc
RW
830 nb_cli_enqueue_change(vty, "./authentication-scheme/mode", NB_OP_MODIFY,
831 strmatch(mode, "md5") ? "md5" : "plain-text");
94b7ff46
RW
832 if (strmatch(mode, "md5"))
833 nb_cli_enqueue_change(vty,
834 "./authentication-scheme/md5-auth-length",
835 NB_OP_MODIFY, value);
a6233bfc
RW
836
837 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
838}
839
840DEFPY (no_ip_rip_authentication_mode,
841 no_ip_rip_authentication_mode_cmd,
842 "no ip rip authentication mode [<md5 [auth-length <rfc|old-ripd>]|text>]",
843 NO_STR
844 IP_STR
845 "Routing Information Protocol\n"
846 "Authentication control\n"
847 "Authentication mode\n"
848 "Keyed message digest\n"
849 "MD5 authentication data length\n"
850 "RFC compatible\n"
851 "Old ripd compatible\n"
852 "Clear text authentication\n")
853{
a6233bfc
RW
854 nb_cli_enqueue_change(vty, "./authentication-scheme/mode", NB_OP_MODIFY,
855 NULL);
856 nb_cli_enqueue_change(vty, "./authentication-scheme/md5-auth-length",
94b7ff46 857 NB_OP_DESTROY, NULL);
a6233bfc
RW
858
859 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
860}
861
862void cli_show_ip_rip_authentication_scheme(struct vty *vty,
863 struct lyd_node *dnode,
864 bool show_defaults)
865{
866 switch (yang_dnode_get_enum(dnode, "./mode")) {
867 case RIP_NO_AUTH:
868 vty_out(vty, " no ip rip authentication mode\n");
869 break;
870 case RIP_AUTH_SIMPLE_PASSWORD:
871 vty_out(vty, " ip rip authentication mode text\n");
872 break;
873 case RIP_AUTH_MD5:
874 vty_out(vty, " ip rip authentication mode md5");
875 if (show_defaults
876 || !yang_dnode_is_default(dnode, "./md5-auth-length")) {
877 if (yang_dnode_get_enum(dnode, "./md5-auth-length")
878 == RIP_AUTH_MD5_SIZE)
879 vty_out(vty, " auth-length rfc");
880 else
881 vty_out(vty, " auth-length old-ripd");
882 }
883 vty_out(vty, "\n");
884 break;
885 }
886}
887
888/*
889 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-password
890 */
891DEFPY (ip_rip_authentication_string,
892 ip_rip_authentication_string_cmd,
893 "ip rip authentication string LINE$password",
894 IP_STR
895 "Routing Information Protocol\n"
896 "Authentication control\n"
897 "Authentication string\n"
898 "Authentication string\n")
899{
94b117b2
RW
900 if (strlen(password) > 16) {
901 vty_out(vty,
902 "%% RIPv2 authentication string must be shorter than 16\n");
903 return CMD_WARNING_CONFIG_FAILED;
904 }
905
906 if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s",
907 VTY_CURR_XPATH,
908 "/frr-ripd:rip/authentication-key-chain")) {
909 vty_out(vty, "%% key-chain configuration exists\n");
910 return CMD_WARNING_CONFIG_FAILED;
911 }
912
a6233bfc
RW
913 nb_cli_enqueue_change(vty, "./authentication-password", NB_OP_MODIFY,
914 password);
915
916 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
917}
918
919DEFPY (no_ip_rip_authentication_string,
920 no_ip_rip_authentication_string_cmd,
921 "no ip rip authentication string [LINE]",
922 NO_STR
923 IP_STR
924 "Routing Information Protocol\n"
925 "Authentication control\n"
926 "Authentication string\n"
927 "Authentication string\n")
928{
8f88441d 929 nb_cli_enqueue_change(vty, "./authentication-password", NB_OP_DESTROY,
a6233bfc
RW
930 NULL);
931
932 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
933}
934
935void cli_show_ip_rip_authentication_string(struct vty *vty,
936 struct lyd_node *dnode,
937 bool show_defaults)
938{
939 vty_out(vty, " ip rip authentication string %s\n",
940 yang_dnode_get_string(dnode, NULL));
941}
942
943/*
944 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain
945 */
946DEFPY (ip_rip_authentication_key_chain,
947 ip_rip_authentication_key_chain_cmd,
948 "ip rip authentication key-chain LINE$keychain",
949 IP_STR
950 "Routing Information Protocol\n"
951 "Authentication control\n"
952 "Authentication key-chain\n"
953 "name of key-chain\n")
954{
94b117b2
RW
955 if (yang_dnode_exists(vty->candidate_config->dnode, "%s%s",
956 VTY_CURR_XPATH,
957 "/frr-ripd:rip/authentication-password")) {
958 vty_out(vty, "%% authentication string configuration exists\n");
959 return CMD_WARNING_CONFIG_FAILED;
960 }
961
a6233bfc
RW
962 nb_cli_enqueue_change(vty, "./authentication-key-chain", NB_OP_MODIFY,
963 keychain);
964
965 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
966}
967
968DEFPY (no_ip_rip_authentication_key_chain,
969 no_ip_rip_authentication_key_chain_cmd,
970 "no ip rip authentication key-chain [LINE]",
971 NO_STR
972 IP_STR
973 "Routing Information Protocol\n"
974 "Authentication control\n"
975 "Authentication key-chain\n"
976 "name of key-chain\n")
977{
95ce849b 978 nb_cli_enqueue_change(vty, "./authentication-key-chain", NB_OP_DESTROY,
a6233bfc
RW
979 NULL);
980
981 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
982}
983
984void cli_show_ip_rip_authentication_key_chain(struct vty *vty,
985 struct lyd_node *dnode,
986 bool show_defaults)
987{
988 vty_out(vty, " ip rip authentication key-chain %s\n",
989 yang_dnode_get_string(dnode, NULL));
990}
991
1137aef4
RW
992/*
993 * XPath: /frr-ripd:clear-rip-route
994 */
995DEFPY (clear_ip_rip,
996 clear_ip_rip_cmd,
14f17e63 997 "clear ip rip [vrf WORD]",
1137aef4
RW
998 CLEAR_STR
999 IP_STR
14f17e63
RW
1000 "Clear IP RIP database\n"
1001 VRF_CMD_HELP_STR)
1137aef4 1002{
14f17e63 1003 struct list *input;
0783b36d 1004 int ret;
14f17e63
RW
1005
1006 input = list_new();
1007 if (vrf) {
1008 struct yang_data *yang_vrf;
1009
1010 yang_vrf = yang_data_new("/frr-ripd:clear-rip-route/input/vrf",
1011 vrf);
1012 listnode_add(input, yang_vrf);
1013 }
1014
0783b36d
DS
1015 ret = nb_cli_rpc("/frr-ripd:clear-rip-route", input, NULL);
1016
1017 list_delete(&input);
1018
1019 return ret;
1137aef4
RW
1020}
1021
707656ec
RW
1022void rip_cli_init(void)
1023{
8c9226c2
RW
1024 install_element(CONFIG_NODE, &router_rip_cmd);
1025 install_element(CONFIG_NODE, &no_router_rip_cmd);
edbf59d2
RW
1026
1027 install_element(RIP_NODE, &rip_allow_ecmp_cmd);
0b0609ba 1028 install_element(RIP_NODE, &rip_default_information_originate_cmd);
282ae30c
RW
1029 install_element(RIP_NODE, &rip_default_metric_cmd);
1030 install_element(RIP_NODE, &no_rip_default_metric_cmd);
7f8a9cba
RW
1031 install_element(RIP_NODE, &rip_distance_cmd);
1032 install_element(RIP_NODE, &no_rip_distance_cmd);
23b23d8c 1033 install_element(RIP_NODE, &rip_distance_source_cmd);
f0ab22fb 1034 install_element(RIP_NODE, &rip_neighbor_cmd);
3d7a1be8
RW
1035 install_element(RIP_NODE, &rip_network_prefix_cmd);
1036 install_element(RIP_NODE, &rip_network_if_cmd);
8c942f65 1037 install_element(RIP_NODE, &rip_offset_list_cmd);
44f2f852
RW
1038 install_element(RIP_NODE, &rip_passive_default_cmd);
1039 install_element(RIP_NODE, &rip_passive_interface_cmd);
908f0020 1040 install_element(RIP_NODE, &rip_redistribute_cmd);
40687878 1041 install_element(RIP_NODE, &rip_route_cmd);
b745780b
RW
1042 install_element(RIP_NODE, &rip_timers_cmd);
1043 install_element(RIP_NODE, &no_rip_timers_cmd);
90eff9da
RW
1044 install_element(RIP_NODE, &rip_version_cmd);
1045 install_element(RIP_NODE, &no_rip_version_cmd);
94b117b2
RW
1046
1047 install_element(INTERFACE_NODE, &ip_rip_split_horizon_cmd);
1048 install_element(INTERFACE_NODE, &ip_rip_v2_broadcast_cmd);
1049 install_element(INTERFACE_NODE, &ip_rip_receive_version_cmd);
1050 install_element(INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
1051 install_element(INTERFACE_NODE, &ip_rip_send_version_cmd);
1052 install_element(INTERFACE_NODE, &no_ip_rip_send_version_cmd);
1053 install_element(INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
1054 install_element(INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
1055 install_element(INTERFACE_NODE, &ip_rip_authentication_string_cmd);
1056 install_element(INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
1057 install_element(INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
1058 install_element(INTERFACE_NODE,
1059 &no_ip_rip_authentication_key_chain_cmd);
1060
1137aef4 1061 install_element(ENABLE_NODE, &clear_ip_rip_cmd);
707656ec 1062}