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