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