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