]> git.proxmox.com Git - mirror_frr.git/blob - ripd/rip_cli.c
Merge pull request #13428 from opensourcerouting/ripd-bfd-fixes
[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-ripd:ripd/instance/default-bfd-profile
586 */
587 DEFPY_YANG(rip_bfd_default_profile, rip_bfd_default_profile_cmd,
588 "bfd default-profile BFDPROF$profile",
589 "Bidirectional Forwarding Detection\n"
590 "BFD default profile\n"
591 "Profile name\n")
592 {
593 nb_cli_enqueue_change(vty, "./default-bfd-profile", NB_OP_MODIFY,
594 profile);
595
596 return nb_cli_apply_changes(vty, NULL);
597 }
598
599 DEFPY_YANG(no_rip_bfd_default_profile, no_rip_bfd_default_profile_cmd,
600 "no bfd default-profile [BFDPROF]",
601 NO_STR
602 "Bidirectional Forwarding Detection\n"
603 "BFD default profile\n"
604 "Profile name\n")
605 {
606 nb_cli_enqueue_change(vty, "./default-bfd-profile", NB_OP_DESTROY,
607 NULL);
608
609 return nb_cli_apply_changes(vty, NULL);
610 }
611
612 void cli_show_ripd_instance_default_bfd_profile(struct vty *vty,
613 const struct lyd_node *dnode,
614 bool show_defaults)
615 {
616 vty_out(vty, " bfd default-profile %s\n",
617 yang_dnode_get_string(dnode, NULL));
618 }
619
620 /*
621 * XPath: /frr-interface:lib/interface/frr-ripd:rip/split-horizon
622 */
623 DEFPY_YANG (ip_rip_split_horizon,
624 ip_rip_split_horizon_cmd,
625 "[no] ip rip split-horizon [poisoned-reverse$poisoned_reverse]",
626 NO_STR
627 IP_STR
628 "Routing Information Protocol\n"
629 "Perform split horizon\n"
630 "With poisoned-reverse\n")
631 {
632 const char *value;
633
634 if (no)
635 value = "disabled";
636 else if (poisoned_reverse)
637 value = "poison-reverse";
638 else
639 value = "simple";
640
641 nb_cli_enqueue_change(vty, "./split-horizon", NB_OP_MODIFY, value);
642
643 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
644 }
645
646 void cli_show_ip_rip_split_horizon(struct vty *vty,
647 const struct lyd_node *dnode,
648 bool show_defaults)
649 {
650 int value;
651
652 value = yang_dnode_get_enum(dnode, NULL);
653 switch (value) {
654 case RIP_NO_SPLIT_HORIZON:
655 vty_out(vty, " no ip rip split-horizon\n");
656 break;
657 case RIP_SPLIT_HORIZON:
658 vty_out(vty, " ip rip split-horizon\n");
659 break;
660 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
661 vty_out(vty, " ip rip split-horizon poisoned-reverse\n");
662 break;
663 }
664 }
665
666 /*
667 * XPath: /frr-interface:lib/interface/frr-ripd:rip/v2-broadcast
668 */
669 DEFPY_YANG (ip_rip_v2_broadcast,
670 ip_rip_v2_broadcast_cmd,
671 "[no] ip rip v2-broadcast",
672 NO_STR
673 IP_STR
674 "Routing Information Protocol\n"
675 "Send ip broadcast v2 update\n")
676 {
677 nb_cli_enqueue_change(vty, "./v2-broadcast", NB_OP_MODIFY,
678 no ? "false" : "true");
679
680 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
681 }
682
683 void cli_show_ip_rip_v2_broadcast(struct vty *vty, const struct lyd_node *dnode,
684 bool show_defaults)
685 {
686 if (!yang_dnode_get_bool(dnode, NULL))
687 vty_out(vty, " no");
688
689 vty_out(vty, " ip rip v2-broadcast\n");
690 }
691
692 /*
693 * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-receive
694 */
695 DEFPY_YANG (ip_rip_receive_version,
696 ip_rip_receive_version_cmd,
697 "ip rip receive version <{1$v1|2$v2}|none>",
698 IP_STR
699 "Routing Information Protocol\n"
700 "Advertisement reception\n"
701 "Version control\n"
702 "RIP version 1\n"
703 "RIP version 2\n"
704 "None\n")
705 {
706 const char *value;
707
708 if (v1 && v2)
709 value = "both";
710 else if (v1)
711 value = "1";
712 else if (v2)
713 value = "2";
714 else
715 value = "none";
716
717 nb_cli_enqueue_change(vty, "./version-receive", NB_OP_MODIFY, value);
718
719 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
720 }
721
722 DEFPY_YANG (no_ip_rip_receive_version,
723 no_ip_rip_receive_version_cmd,
724 "no ip rip receive version [<{1|2}|none>]",
725 NO_STR
726 IP_STR
727 "Routing Information Protocol\n"
728 "Advertisement reception\n"
729 "Version control\n"
730 "RIP version 1\n"
731 "RIP version 2\n"
732 "None\n")
733 {
734 nb_cli_enqueue_change(vty, "./version-receive", NB_OP_MODIFY, NULL);
735
736 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
737 }
738
739 void cli_show_ip_rip_receive_version(struct vty *vty,
740 const struct lyd_node *dnode,
741 bool show_defaults)
742 {
743 switch (yang_dnode_get_enum(dnode, NULL)) {
744 case RI_RIP_UNSPEC:
745 vty_out(vty, " no ip rip receive version\n");
746 break;
747 case RI_RIP_VERSION_1:
748 vty_out(vty, " ip rip receive version 1\n");
749 break;
750 case RI_RIP_VERSION_2:
751 vty_out(vty, " ip rip receive version 2\n");
752 break;
753 case RI_RIP_VERSION_1_AND_2:
754 vty_out(vty, " ip rip receive version 1 2\n");
755 break;
756 case RI_RIP_VERSION_NONE:
757 vty_out(vty, " ip rip receive version none\n");
758 break;
759 }
760 }
761
762 /*
763 * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-send
764 */
765 DEFPY_YANG (ip_rip_send_version,
766 ip_rip_send_version_cmd,
767 "ip rip send version <{1$v1|2$v2}|none>",
768 IP_STR
769 "Routing Information Protocol\n"
770 "Advertisement transmission\n"
771 "Version control\n"
772 "RIP version 1\n"
773 "RIP version 2\n"
774 "None\n")
775 {
776 const char *value;
777
778 if (v1 && v2)
779 value = "both";
780 else if (v1)
781 value = "1";
782 else if (v2)
783 value = "2";
784 else
785 value = "none";
786
787 nb_cli_enqueue_change(vty, "./version-send", NB_OP_MODIFY, value);
788
789 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
790 }
791
792 DEFPY_YANG (no_ip_rip_send_version,
793 no_ip_rip_send_version_cmd,
794 "no ip rip send version [<{1|2}|none>]",
795 NO_STR
796 IP_STR
797 "Routing Information Protocol\n"
798 "Advertisement transmission\n"
799 "Version control\n"
800 "RIP version 1\n"
801 "RIP version 2\n"
802 "None\n")
803 {
804 nb_cli_enqueue_change(vty, "./version-send", NB_OP_MODIFY, NULL);
805
806 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
807 }
808
809 void cli_show_ip_rip_send_version(struct vty *vty, const struct lyd_node *dnode,
810 bool show_defaults)
811 {
812 switch (yang_dnode_get_enum(dnode, NULL)) {
813 case RI_RIP_UNSPEC:
814 vty_out(vty, " no ip rip send version\n");
815 break;
816 case RI_RIP_VERSION_1:
817 vty_out(vty, " ip rip send version 1\n");
818 break;
819 case RI_RIP_VERSION_2:
820 vty_out(vty, " ip rip send version 2\n");
821 break;
822 case RI_RIP_VERSION_1_AND_2:
823 vty_out(vty, " ip rip send version 1 2\n");
824 break;
825 case RI_RIP_VERSION_NONE:
826 vty_out(vty, " ip rip send version none\n");
827 break;
828 }
829 }
830
831 /*
832 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme
833 */
834 DEFPY_YANG (ip_rip_authentication_mode,
835 ip_rip_authentication_mode_cmd,
836 "ip rip authentication mode <md5$mode [auth-length <rfc|old-ripd>$auth_length]|text$mode>",
837 IP_STR
838 "Routing Information Protocol\n"
839 "Authentication control\n"
840 "Authentication mode\n"
841 "Keyed message digest\n"
842 "MD5 authentication data length\n"
843 "RFC compatible\n"
844 "Old ripd compatible\n"
845 "Clear text authentication\n")
846 {
847 const char *value = NULL;
848
849 if (auth_length) {
850 if (strmatch(auth_length, "rfc"))
851 value = "16";
852 else
853 value = "20";
854 }
855
856 nb_cli_enqueue_change(vty, "./authentication-scheme/mode", NB_OP_MODIFY,
857 strmatch(mode, "md5") ? "md5" : "plain-text");
858 if (strmatch(mode, "md5"))
859 nb_cli_enqueue_change(vty,
860 "./authentication-scheme/md5-auth-length",
861 NB_OP_MODIFY, value);
862
863 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
864 }
865
866 DEFPY_YANG (no_ip_rip_authentication_mode,
867 no_ip_rip_authentication_mode_cmd,
868 "no ip rip authentication mode [<md5 [auth-length <rfc|old-ripd>]|text>]",
869 NO_STR
870 IP_STR
871 "Routing Information Protocol\n"
872 "Authentication control\n"
873 "Authentication mode\n"
874 "Keyed message digest\n"
875 "MD5 authentication data length\n"
876 "RFC compatible\n"
877 "Old ripd compatible\n"
878 "Clear text authentication\n")
879 {
880 nb_cli_enqueue_change(vty, "./authentication-scheme/mode", NB_OP_MODIFY,
881 NULL);
882 nb_cli_enqueue_change(vty, "./authentication-scheme/md5-auth-length",
883 NB_OP_DESTROY, NULL);
884
885 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
886 }
887
888 void cli_show_ip_rip_authentication_scheme(struct vty *vty,
889 const struct lyd_node *dnode,
890 bool show_defaults)
891 {
892 switch (yang_dnode_get_enum(dnode, "./mode")) {
893 case RIP_NO_AUTH:
894 vty_out(vty, " no ip rip authentication mode\n");
895 break;
896 case RIP_AUTH_SIMPLE_PASSWORD:
897 vty_out(vty, " ip rip authentication mode text\n");
898 break;
899 case RIP_AUTH_MD5:
900 vty_out(vty, " ip rip authentication mode md5");
901 if (show_defaults
902 || !yang_dnode_is_default(dnode, "./md5-auth-length")) {
903 if (yang_dnode_get_enum(dnode, "./md5-auth-length")
904 == RIP_AUTH_MD5_SIZE)
905 vty_out(vty, " auth-length rfc");
906 else
907 vty_out(vty, " auth-length old-ripd");
908 }
909 vty_out(vty, "\n");
910 break;
911 }
912 }
913
914 /*
915 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-password
916 */
917 DEFPY_YANG (ip_rip_authentication_string,
918 ip_rip_authentication_string_cmd,
919 "ip rip authentication string LINE$password",
920 IP_STR
921 "Routing Information Protocol\n"
922 "Authentication control\n"
923 "Authentication string\n"
924 "Authentication string\n")
925 {
926 if (strlen(password) > 16) {
927 vty_out(vty,
928 "%% RIPv2 authentication string must be shorter than 16\n");
929 return CMD_WARNING_CONFIG_FAILED;
930 }
931
932 if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
933 VTY_CURR_XPATH,
934 "/frr-ripd:rip/authentication-key-chain")) {
935 vty_out(vty, "%% key-chain configuration exists\n");
936 return CMD_WARNING_CONFIG_FAILED;
937 }
938
939 nb_cli_enqueue_change(vty, "./authentication-password", NB_OP_MODIFY,
940 password);
941
942 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
943 }
944
945 DEFPY_YANG (no_ip_rip_authentication_string,
946 no_ip_rip_authentication_string_cmd,
947 "no ip rip authentication string [LINE]",
948 NO_STR
949 IP_STR
950 "Routing Information Protocol\n"
951 "Authentication control\n"
952 "Authentication string\n"
953 "Authentication string\n")
954 {
955 nb_cli_enqueue_change(vty, "./authentication-password", NB_OP_DESTROY,
956 NULL);
957
958 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
959 }
960
961 void cli_show_ip_rip_authentication_string(struct vty *vty,
962 const struct lyd_node *dnode,
963 bool show_defaults)
964 {
965 vty_out(vty, " ip rip authentication string %s\n",
966 yang_dnode_get_string(dnode, NULL));
967 }
968
969 /*
970 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain
971 */
972 DEFPY_YANG (ip_rip_authentication_key_chain,
973 ip_rip_authentication_key_chain_cmd,
974 "ip rip authentication key-chain LINE$keychain",
975 IP_STR
976 "Routing Information Protocol\n"
977 "Authentication control\n"
978 "Authentication key-chain\n"
979 "name of key-chain\n")
980 {
981 if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
982 VTY_CURR_XPATH,
983 "/frr-ripd:rip/authentication-password")) {
984 vty_out(vty, "%% authentication string configuration exists\n");
985 return CMD_WARNING_CONFIG_FAILED;
986 }
987
988 nb_cli_enqueue_change(vty, "./authentication-key-chain", NB_OP_MODIFY,
989 keychain);
990
991 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
992 }
993
994 DEFPY_YANG (no_ip_rip_authentication_key_chain,
995 no_ip_rip_authentication_key_chain_cmd,
996 "no ip rip authentication key-chain [LINE]",
997 NO_STR
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 nb_cli_enqueue_change(vty, "./authentication-key-chain", NB_OP_DESTROY,
1005 NULL);
1006
1007 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
1008 }
1009
1010 void cli_show_ip_rip_authentication_key_chain(struct vty *vty,
1011 const struct lyd_node *dnode,
1012 bool show_defaults)
1013 {
1014 vty_out(vty, " ip rip authentication key-chain %s\n",
1015 yang_dnode_get_string(dnode, NULL));
1016 }
1017
1018 /*
1019 * XPath: /frr-interface:lib/interface/frr-ripd:rip/bfd-monitoring/enable
1020 */
1021 DEFPY_YANG(ip_rip_bfd, ip_rip_bfd_cmd, "[no] ip rip bfd",
1022 NO_STR IP_STR
1023 "Routing Information Protocol\n"
1024 "Enable BFD support\n")
1025 {
1026 nb_cli_enqueue_change(vty, "./bfd-monitoring/enable", NB_OP_MODIFY,
1027 no ? "false" : "true");
1028
1029 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
1030 }
1031
1032 void cli_show_ip_rip_bfd_enable(struct vty *vty, const struct lyd_node *dnode,
1033 bool show_defaults)
1034 {
1035 vty_out(vty, " ip rip bfd\n");
1036 }
1037
1038 /*
1039 * XPath: /frr-interface:lib/interface/frr-ripd:rip/bfd/profile
1040 */
1041 DEFPY_YANG(ip_rip_bfd_profile, ip_rip_bfd_profile_cmd,
1042 "[no] ip rip bfd profile BFDPROF$profile",
1043 NO_STR IP_STR
1044 "Routing Information Protocol\n"
1045 "Enable BFD support\n"
1046 "Use a pre-configured profile\n"
1047 "Profile name\n")
1048 {
1049 if (no)
1050 nb_cli_enqueue_change(vty, "./bfd-monitoring/profile",
1051 NB_OP_DESTROY, NULL);
1052 else
1053 nb_cli_enqueue_change(vty, "./bfd-monitoring/profile",
1054 NB_OP_MODIFY, profile);
1055
1056 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
1057 }
1058
1059 DEFPY_YANG(no_ip_rip_bfd_profile, no_ip_rip_bfd_profile_cmd,
1060 "no ip rip bfd profile",
1061 NO_STR IP_STR
1062 "Routing Information Protocol\n"
1063 "Enable BFD support\n"
1064 "Use a pre-configured profile\n")
1065 {
1066 nb_cli_enqueue_change(vty, "./bfd-monitoring/profile", NB_OP_DESTROY,
1067 NULL);
1068 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
1069 }
1070
1071 void cli_show_ip_rip_bfd_profile(struct vty *vty, const struct lyd_node *dnode,
1072 bool show_defaults)
1073 {
1074 vty_out(vty, " ip rip bfd profile %s\n",
1075 yang_dnode_get_string(dnode, NULL));
1076 }
1077
1078 /*
1079 * XPath: /frr-ripd:clear-rip-route
1080 */
1081 DEFPY_YANG (clear_ip_rip,
1082 clear_ip_rip_cmd,
1083 "clear ip rip [vrf WORD]",
1084 CLEAR_STR
1085 IP_STR
1086 "Clear IP RIP database\n"
1087 VRF_CMD_HELP_STR)
1088 {
1089 struct list *input;
1090 int ret;
1091
1092 input = list_new();
1093 if (vrf) {
1094 struct yang_data *yang_vrf;
1095
1096 yang_vrf = yang_data_new("/frr-ripd:clear-rip-route/input/vrf",
1097 vrf);
1098 listnode_add(input, yang_vrf);
1099 }
1100
1101 ret = nb_cli_rpc(vty, "/frr-ripd:clear-rip-route", input, NULL);
1102
1103 list_delete(&input);
1104
1105 return ret;
1106 }
1107
1108 DEFUN (rip_distribute_list,
1109 rip_distribute_list_cmd,
1110 "distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]",
1111 "Filter networks in routing updates\n"
1112 "Specify a prefix\n"
1113 "Access-list name\n"
1114 "Filter incoming routing updates\n"
1115 "Filter outgoing routing updates\n"
1116 "Interface name\n")
1117 {
1118 const char *ifname = NULL;
1119 int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0;
1120
1121 if (argv[argc - 1]->type == VARIABLE_TKN)
1122 ifname = argv[argc - 1]->arg;
1123
1124 return distribute_list_parser(prefix, true, argv[2 + prefix]->text,
1125 argv[1 + prefix]->arg, ifname);
1126 }
1127
1128 DEFUN (rip_no_distribute_list,
1129 rip_no_distribute_list_cmd,
1130 "no distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]",
1131 NO_STR
1132 "Filter networks in routing updates\n"
1133 "Specify a prefix\n"
1134 "Access-list name\n"
1135 "Filter incoming routing updates\n"
1136 "Filter outgoing routing updates\n"
1137 "Interface name\n")
1138 {
1139 const char *ifname = NULL;
1140 int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
1141
1142 if (argv[argc - 1]->type == VARIABLE_TKN)
1143 ifname = argv[argc - 1]->arg;
1144
1145 return distribute_list_no_parser(vty, prefix, true,
1146 argv[3 + prefix]->text,
1147 argv[2 + prefix]->arg, ifname);
1148 }
1149
1150 void rip_cli_init(void)
1151 {
1152 install_element(CONFIG_NODE, &router_rip_cmd);
1153 install_element(CONFIG_NODE, &no_router_rip_cmd);
1154
1155 install_element(RIP_NODE, &rip_distribute_list_cmd);
1156 install_element(RIP_NODE, &rip_no_distribute_list_cmd);
1157
1158 install_element(RIP_NODE, &rip_allow_ecmp_cmd);
1159 install_element(RIP_NODE, &rip_default_information_originate_cmd);
1160 install_element(RIP_NODE, &rip_default_metric_cmd);
1161 install_element(RIP_NODE, &no_rip_default_metric_cmd);
1162 install_element(RIP_NODE, &rip_distance_cmd);
1163 install_element(RIP_NODE, &no_rip_distance_cmd);
1164 install_element(RIP_NODE, &rip_distance_source_cmd);
1165 install_element(RIP_NODE, &rip_neighbor_cmd);
1166 install_element(RIP_NODE, &rip_network_prefix_cmd);
1167 install_element(RIP_NODE, &rip_network_if_cmd);
1168 install_element(RIP_NODE, &rip_offset_list_cmd);
1169 install_element(RIP_NODE, &rip_passive_default_cmd);
1170 install_element(RIP_NODE, &rip_passive_interface_cmd);
1171 install_element(RIP_NODE, &rip_redistribute_cmd);
1172 install_element(RIP_NODE, &rip_route_cmd);
1173 install_element(RIP_NODE, &rip_timers_cmd);
1174 install_element(RIP_NODE, &no_rip_timers_cmd);
1175 install_element(RIP_NODE, &rip_version_cmd);
1176 install_element(RIP_NODE, &no_rip_version_cmd);
1177 install_element(RIP_NODE, &rip_bfd_default_profile_cmd);
1178 install_element(RIP_NODE, &no_rip_bfd_default_profile_cmd);
1179
1180 install_element(INTERFACE_NODE, &ip_rip_split_horizon_cmd);
1181 install_element(INTERFACE_NODE, &ip_rip_v2_broadcast_cmd);
1182 install_element(INTERFACE_NODE, &ip_rip_receive_version_cmd);
1183 install_element(INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
1184 install_element(INTERFACE_NODE, &ip_rip_send_version_cmd);
1185 install_element(INTERFACE_NODE, &no_ip_rip_send_version_cmd);
1186 install_element(INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
1187 install_element(INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
1188 install_element(INTERFACE_NODE, &ip_rip_authentication_string_cmd);
1189 install_element(INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
1190 install_element(INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
1191 install_element(INTERFACE_NODE,
1192 &no_ip_rip_authentication_key_chain_cmd);
1193 install_element(INTERFACE_NODE, &ip_rip_bfd_cmd);
1194 install_element(INTERFACE_NODE, &ip_rip_bfd_profile_cmd);
1195 install_element(INTERFACE_NODE, &no_ip_rip_bfd_profile_cmd);
1196
1197 install_element(ENABLE_NODE, &clear_ip_rip_cmd);
1198 }