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