Line data Source code
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 4 : 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 4 : char xpath[XPATH_MAXLEN];
46 4 : int ret;
47 :
48 : /* Build RIP instance XPath. */
49 4 : if (!vrf)
50 4 : vrf = VRF_DEFAULT_NAME;
51 4 : snprintf(xpath, sizeof(xpath), "/frr-ripd:ripd/instance[vrf='%s']",
52 : vrf);
53 :
54 4 : nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
55 :
56 4 : ret = nb_cli_apply_changes(vty, NULL);
57 4 : if (ret == CMD_SUCCESS)
58 4 : VTY_PUSH_XPATH(RIP_NODE, xpath);
59 :
60 : return ret;
61 : }
62 :
63 0 : 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 0 : char xpath[XPATH_MAXLEN];
72 :
73 : /* Build RIP instance XPath. */
74 0 : if (!vrf)
75 0 : vrf = VRF_DEFAULT_NAME;
76 0 : snprintf(xpath, sizeof(xpath), "/frr-ripd:ripd/instance[vrf='%s']",
77 : vrf);
78 :
79 0 : nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
80 :
81 0 : return nb_cli_apply_changes_clear_pending(vty, NULL);
82 : }
83 :
84 0 : void cli_show_router_rip(struct vty *vty, const struct lyd_node *dnode,
85 : bool show_defaults)
86 : {
87 0 : const char *vrf_name;
88 :
89 0 : vrf_name = yang_dnode_get_string(dnode, "./vrf");
90 :
91 0 : vty_out(vty, "!\n");
92 0 : vty_out(vty, "router rip");
93 0 : if (!strmatch(vrf_name, VRF_DEFAULT_NAME))
94 0 : vty_out(vty, " vrf %s", vrf_name);
95 0 : vty_out(vty, "\n");
96 0 : }
97 :
98 : /*
99 : * XPath: /frr-ripd:ripd/instance/allow-ecmp
100 : */
101 0 : 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 0 : nb_cli_enqueue_change(vty, "./allow-ecmp", NB_OP_MODIFY,
108 : no ? "false" : "true");
109 :
110 0 : return nb_cli_apply_changes(vty, NULL);
111 : }
112 :
113 0 : void cli_show_rip_allow_ecmp(struct vty *vty, const struct lyd_node *dnode,
114 : bool show_defaults)
115 : {
116 0 : if (!yang_dnode_get_bool(dnode, NULL))
117 0 : vty_out(vty, " no");
118 :
119 0 : vty_out(vty, " allow-ecmp\n");
120 0 : }
121 :
122 : /*
123 : * XPath: /frr-ripd:ripd/instance/default-information-originate
124 : */
125 0 : 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 0 : nb_cli_enqueue_change(vty, "./default-information-originate",
133 : NB_OP_MODIFY, no ? "false" : "true");
134 :
135 0 : return nb_cli_apply_changes(vty, NULL);
136 : }
137 :
138 0 : void cli_show_rip_default_information_originate(struct vty *vty,
139 : const struct lyd_node *dnode,
140 : bool show_defaults)
141 : {
142 0 : if (!yang_dnode_get_bool(dnode, NULL))
143 0 : vty_out(vty, " no");
144 :
145 0 : vty_out(vty, " default-information originate\n");
146 0 : }
147 :
148 : /*
149 : * XPath: /frr-ripd:ripd/instance/default-metric
150 : */
151 0 : 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 0 : nb_cli_enqueue_change(vty, "./default-metric", NB_OP_MODIFY,
158 : default_metric_str);
159 :
160 0 : return nb_cli_apply_changes(vty, NULL);
161 : }
162 :
163 0 : 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 0 : nb_cli_enqueue_change(vty, "./default-metric", NB_OP_MODIFY, NULL);
171 :
172 0 : return nb_cli_apply_changes(vty, NULL);
173 : }
174 :
175 0 : void cli_show_rip_default_metric(struct vty *vty, const struct lyd_node *dnode,
176 : bool show_defaults)
177 : {
178 0 : vty_out(vty, " default-metric %s\n",
179 : yang_dnode_get_string(dnode, NULL));
180 0 : }
181 :
182 : /*
183 : * XPath: /frr-ripd:ripd/instance/distance/default
184 : */
185 0 : DEFPY_YANG (rip_distance,
186 : rip_distance_cmd,
187 : "distance (1-255)",
188 : "Administrative distance\n"
189 : "Distance value\n")
190 : {
191 0 : nb_cli_enqueue_change(vty, "./distance/default", NB_OP_MODIFY,
192 : distance_str);
193 :
194 0 : return nb_cli_apply_changes(vty, NULL);
195 : }
196 :
197 0 : 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 0 : nb_cli_enqueue_change(vty, "./distance/default", NB_OP_MODIFY, NULL);
205 :
206 0 : return nb_cli_apply_changes(vty, NULL);
207 : }
208 :
209 0 : void cli_show_rip_distance(struct vty *vty, const struct lyd_node *dnode,
210 : bool show_defaults)
211 : {
212 0 : if (yang_dnode_is_default(dnode, NULL))
213 0 : vty_out(vty, " no distance\n");
214 : else
215 0 : vty_out(vty, " distance %s\n",
216 : yang_dnode_get_string(dnode, NULL));
217 0 : }
218 :
219 : /*
220 : * XPath: /frr-ripd:ripd/instance/distance/source
221 : */
222 0 : 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 0 : if (!no) {
232 0 : nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
233 0 : nb_cli_enqueue_change(vty, "./distance", NB_OP_MODIFY,
234 : distance_str);
235 0 : nb_cli_enqueue_change(vty, "./access-list",
236 : acl ? NB_OP_MODIFY : NB_OP_DESTROY, acl);
237 : } else
238 0 : nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
239 :
240 0 : return nb_cli_apply_changes(vty, "./distance/source[prefix='%s']",
241 : prefix_str);
242 : }
243 :
244 0 : void cli_show_rip_distance_source(struct vty *vty, const struct lyd_node *dnode,
245 : bool show_defaults)
246 : {
247 0 : vty_out(vty, " distance %s %s",
248 : yang_dnode_get_string(dnode, "./distance"),
249 : yang_dnode_get_string(dnode, "./prefix"));
250 0 : if (yang_dnode_exists(dnode, "./access-list"))
251 0 : vty_out(vty, " %s",
252 : yang_dnode_get_string(dnode, "./access-list"));
253 0 : vty_out(vty, "\n");
254 0 : }
255 :
256 : /*
257 : * XPath: /frr-ripd:ripd/instance/explicit-neighbor
258 : */
259 0 : 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 0 : nb_cli_enqueue_change(vty, "./explicit-neighbor",
267 : no ? NB_OP_DESTROY : NB_OP_CREATE, neighbor_str);
268 :
269 0 : return nb_cli_apply_changes(vty, NULL);
270 : }
271 :
272 0 : void cli_show_rip_neighbor(struct vty *vty, const struct lyd_node *dnode,
273 : bool show_defaults)
274 : {
275 0 : vty_out(vty, " neighbor %s\n", yang_dnode_get_string(dnode, NULL));
276 0 : }
277 :
278 : /*
279 : * XPath: /frr-ripd:ripd/instance/network
280 : */
281 4 : 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 8 : nb_cli_enqueue_change(vty, "./network",
289 : no ? NB_OP_DESTROY : NB_OP_CREATE, network_str);
290 :
291 4 : return nb_cli_apply_changes(vty, NULL);
292 : }
293 :
294 0 : void cli_show_rip_network_prefix(struct vty *vty, const struct lyd_node *dnode,
295 : bool show_defaults)
296 : {
297 0 : vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL));
298 0 : }
299 :
300 : /*
301 : * XPath: /frr-ripd:ripd/instance/interface
302 : */
303 2 : 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 4 : nb_cli_enqueue_change(vty, "./interface",
311 : no ? NB_OP_DESTROY : NB_OP_CREATE, network);
312 :
313 2 : return nb_cli_apply_changes(vty, NULL);
314 : }
315 :
316 0 : void cli_show_rip_network_interface(struct vty *vty,
317 : const struct lyd_node *dnode,
318 : bool show_defaults)
319 : {
320 0 : vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL));
321 0 : }
322 :
323 : /*
324 : * XPath: /frr-ripd:ripd/instance/offset-list
325 : */
326 0 : 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 0 : if (!no) {
338 0 : nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
339 0 : nb_cli_enqueue_change(vty, "./access-list", NB_OP_MODIFY, acl);
340 0 : nb_cli_enqueue_change(vty, "./metric", NB_OP_MODIFY,
341 : metric_str);
342 : } else
343 0 : nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
344 :
345 0 : return nb_cli_apply_changes(
346 : vty, "./offset-list[interface='%s'][direction='%s']",
347 : ifname ? ifname : "*", direction);
348 : }
349 :
350 0 : void cli_show_rip_offset_list(struct vty *vty, const struct lyd_node *dnode,
351 : bool show_defaults)
352 : {
353 0 : const char *interface;
354 :
355 0 : interface = yang_dnode_get_string(dnode, "./interface");
356 :
357 0 : 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 0 : if (!strmatch(interface, "*"))
362 0 : vty_out(vty, " %s", interface);
363 0 : vty_out(vty, "\n");
364 0 : }
365 :
366 : /*
367 : * XPath: /frr-ripd:ripd/instance/passive-default
368 : */
369 0 : 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 0 : nb_cli_enqueue_change(vty, "./passive-default", NB_OP_MODIFY,
377 : no ? "false" : "true");
378 :
379 0 : return nb_cli_apply_changes(vty, NULL);
380 : }
381 :
382 0 : void cli_show_rip_passive_default(struct vty *vty, const struct lyd_node *dnode,
383 : bool show_defaults)
384 : {
385 0 : if (!yang_dnode_get_bool(dnode, NULL))
386 0 : vty_out(vty, " no");
387 :
388 0 : vty_out(vty, " passive-interface default\n");
389 0 : }
390 :
391 : /*
392 : * XPath: /frr-ripd:ripd/instance/passive-interface
393 : * /frr-ripd:ripd/instance/non-passive-interface
394 : */
395 1 : 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 1 : bool passive_default =
403 2 : yang_dnode_get_bool(vty->candidate_config->dnode, "%s%s",
404 1 : VTY_CURR_XPATH, "/passive-default");
405 :
406 1 : if (passive_default) {
407 0 : nb_cli_enqueue_change(vty, "./non-passive-interface",
408 : no ? NB_OP_CREATE : NB_OP_DESTROY,
409 : ifname);
410 : } else {
411 2 : nb_cli_enqueue_change(vty, "./passive-interface",
412 : no ? NB_OP_DESTROY : NB_OP_CREATE,
413 : ifname);
414 : }
415 :
416 1 : return nb_cli_apply_changes(vty, NULL);
417 : }
418 :
419 0 : void cli_show_rip_passive_interface(struct vty *vty,
420 : const struct lyd_node *dnode,
421 : bool show_defaults)
422 : {
423 0 : vty_out(vty, " passive-interface %s\n",
424 : yang_dnode_get_string(dnode, NULL));
425 0 : }
426 :
427 0 : void cli_show_rip_non_passive_interface(struct vty *vty,
428 : const struct lyd_node *dnode,
429 : bool show_defaults)
430 : {
431 0 : vty_out(vty, " no passive-interface %s\n",
432 : yang_dnode_get_string(dnode, NULL));
433 0 : }
434 :
435 : /*
436 : * XPath: /frr-ripd:ripd/instance/redistribute
437 : */
438 2 : 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 2 : if (!no) {
450 2 : nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
451 4 : nb_cli_enqueue_change(vty, "./route-map",
452 : route_map ? NB_OP_MODIFY : NB_OP_DESTROY,
453 : route_map);
454 4 : nb_cli_enqueue_change(vty, "./metric",
455 : metric_str ? NB_OP_MODIFY : NB_OP_DESTROY,
456 : metric_str);
457 : } else
458 0 : nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
459 :
460 2 : return nb_cli_apply_changes(vty, "./redistribute[protocol='%s']",
461 : protocol);
462 : }
463 :
464 0 : void cli_show_rip_redistribute(struct vty *vty, const struct lyd_node *dnode,
465 : bool show_defaults)
466 : {
467 0 : vty_out(vty, " redistribute %s",
468 : yang_dnode_get_string(dnode, "./protocol"));
469 0 : if (yang_dnode_exists(dnode, "./metric"))
470 0 : vty_out(vty, " metric %s",
471 : yang_dnode_get_string(dnode, "./metric"));
472 0 : if (yang_dnode_exists(dnode, "./route-map"))
473 0 : vty_out(vty, " route-map %s",
474 : yang_dnode_get_string(dnode, "./route-map"));
475 0 : vty_out(vty, "\n");
476 0 : }
477 :
478 : /*
479 : * XPath: /frr-ripd:ripd/instance/static-route
480 : */
481 0 : 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 0 : nb_cli_enqueue_change(vty, "./static-route",
489 : no ? NB_OP_DESTROY : NB_OP_CREATE, route_str);
490 :
491 0 : return nb_cli_apply_changes(vty, NULL);
492 : }
493 :
494 0 : void cli_show_rip_route(struct vty *vty, const struct lyd_node *dnode,
495 : bool show_defaults)
496 : {
497 0 : vty_out(vty, " route %s\n", yang_dnode_get_string(dnode, NULL));
498 0 : }
499 :
500 : /*
501 : * XPath: /frr-ripd:ripd/instance/timers
502 : */
503 4 : 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 4 : nb_cli_enqueue_change(vty, "./update-interval", NB_OP_MODIFY,
513 : update_str);
514 4 : nb_cli_enqueue_change(vty, "./holddown-interval", NB_OP_MODIFY,
515 : timeout_str);
516 4 : nb_cli_enqueue_change(vty, "./flush-interval", NB_OP_MODIFY,
517 : garbage_str);
518 :
519 4 : return nb_cli_apply_changes(vty, "./timers");
520 : }
521 :
522 0 : 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 0 : nb_cli_enqueue_change(vty, "./update-interval", NB_OP_MODIFY, NULL);
533 0 : nb_cli_enqueue_change(vty, "./holddown-interval", NB_OP_MODIFY, NULL);
534 0 : nb_cli_enqueue_change(vty, "./flush-interval", NB_OP_MODIFY, NULL);
535 :
536 0 : return nb_cli_apply_changes(vty, "./timers");
537 : }
538 :
539 0 : void cli_show_rip_timers(struct vty *vty, const struct lyd_node *dnode,
540 : bool show_defaults)
541 : {
542 0 : 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 0 : }
547 :
548 : /*
549 : * XPath: /frr-ripd:ripd/instance/version
550 : */
551 4 : DEFPY_YANG (rip_version,
552 : rip_version_cmd,
553 : "version (1-2)",
554 : "Set routing protocol version\n"
555 : "version\n")
556 : {
557 4 : nb_cli_enqueue_change(vty, "./version/receive", NB_OP_MODIFY,
558 : version_str);
559 4 : nb_cli_enqueue_change(vty, "./version/send", NB_OP_MODIFY, version_str);
560 :
561 4 : return nb_cli_apply_changes(vty, NULL);
562 : }
563 :
564 0 : 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 0 : nb_cli_enqueue_change(vty, "./version/receive", NB_OP_MODIFY, NULL);
572 0 : nb_cli_enqueue_change(vty, "./version/send", NB_OP_MODIFY, NULL);
573 :
574 0 : return nb_cli_apply_changes(vty, NULL);
575 : }
576 :
577 0 : 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 0 : switch (yang_dnode_get_enum(dnode, "./receive")) {
585 0 : case RI_RIP_VERSION_1:
586 0 : vty_out(vty, " version 1\n");
587 0 : break;
588 0 : case RI_RIP_VERSION_2:
589 0 : vty_out(vty, " version 2\n");
590 0 : break;
591 0 : case RI_RIP_VERSION_1_AND_2:
592 0 : vty_out(vty, " no version\n");
593 0 : break;
594 : }
595 0 : }
596 :
597 : /*
598 : * XPath: /frr-interface:lib/interface/frr-ripd:rip/split-horizon
599 : */
600 0 : 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 0 : const char *value;
610 :
611 0 : if (no)
612 : value = "disabled";
613 0 : else if (poisoned_reverse)
614 : value = "poison-reverse";
615 : else
616 0 : value = "simple";
617 :
618 0 : nb_cli_enqueue_change(vty, "./split-horizon", NB_OP_MODIFY, value);
619 :
620 0 : return nb_cli_apply_changes(vty, "./frr-ripd:rip");
621 : }
622 :
623 0 : void cli_show_ip_rip_split_horizon(struct vty *vty,
624 : const struct lyd_node *dnode,
625 : bool show_defaults)
626 : {
627 0 : int value;
628 :
629 0 : value = yang_dnode_get_enum(dnode, NULL);
630 0 : switch (value) {
631 0 : case RIP_NO_SPLIT_HORIZON:
632 0 : vty_out(vty, " no ip rip split-horizon\n");
633 0 : break;
634 0 : case RIP_SPLIT_HORIZON:
635 0 : vty_out(vty, " ip rip split-horizon\n");
636 0 : break;
637 0 : case RIP_SPLIT_HORIZON_POISONED_REVERSE:
638 0 : vty_out(vty, " ip rip split-horizon poisoned-reverse\n");
639 0 : break;
640 : }
641 0 : }
642 :
643 : /*
644 : * XPath: /frr-interface:lib/interface/frr-ripd:rip/v2-broadcast
645 : */
646 0 : 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 0 : nb_cli_enqueue_change(vty, "./v2-broadcast", NB_OP_MODIFY,
655 : no ? "false" : "true");
656 :
657 0 : return nb_cli_apply_changes(vty, "./frr-ripd:rip");
658 : }
659 :
660 0 : void cli_show_ip_rip_v2_broadcast(struct vty *vty, const struct lyd_node *dnode,
661 : bool show_defaults)
662 : {
663 0 : if (!yang_dnode_get_bool(dnode, NULL))
664 0 : vty_out(vty, " no");
665 :
666 0 : vty_out(vty, " ip rip v2-broadcast\n");
667 0 : }
668 :
669 : /*
670 : * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-receive
671 : */
672 0 : 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 0 : const char *value;
684 :
685 0 : if (v1 && v2)
686 : value = "both";
687 0 : else if (v1)
688 : value = "1";
689 0 : else if (v2)
690 : value = "2";
691 : else
692 0 : value = "none";
693 :
694 0 : nb_cli_enqueue_change(vty, "./version-receive", NB_OP_MODIFY, value);
695 :
696 0 : return nb_cli_apply_changes(vty, "./frr-ripd:rip");
697 : }
698 :
699 0 : 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 0 : nb_cli_enqueue_change(vty, "./version-receive", NB_OP_MODIFY, NULL);
712 :
713 0 : return nb_cli_apply_changes(vty, "./frr-ripd:rip");
714 : }
715 :
716 0 : void cli_show_ip_rip_receive_version(struct vty *vty,
717 : const struct lyd_node *dnode,
718 : bool show_defaults)
719 : {
720 0 : switch (yang_dnode_get_enum(dnode, NULL)) {
721 0 : case RI_RIP_UNSPEC:
722 0 : vty_out(vty, " no ip rip receive version\n");
723 0 : break;
724 0 : case RI_RIP_VERSION_1:
725 0 : vty_out(vty, " ip rip receive version 1\n");
726 0 : break;
727 0 : case RI_RIP_VERSION_2:
728 0 : vty_out(vty, " ip rip receive version 2\n");
729 0 : break;
730 0 : case RI_RIP_VERSION_1_AND_2:
731 0 : vty_out(vty, " ip rip receive version 1 2\n");
732 0 : break;
733 0 : case RI_RIP_VERSION_NONE:
734 0 : vty_out(vty, " ip rip receive version none\n");
735 0 : break;
736 : }
737 0 : }
738 :
739 : /*
740 : * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-send
741 : */
742 0 : 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 0 : const char *value;
754 :
755 0 : if (v1 && v2)
756 : value = "both";
757 0 : else if (v1)
758 : value = "1";
759 0 : else if (v2)
760 : value = "2";
761 : else
762 0 : value = "none";
763 :
764 0 : nb_cli_enqueue_change(vty, "./version-send", NB_OP_MODIFY, value);
765 :
766 0 : return nb_cli_apply_changes(vty, "./frr-ripd:rip");
767 : }
768 :
769 0 : 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 0 : nb_cli_enqueue_change(vty, "./version-send", NB_OP_MODIFY, NULL);
782 :
783 0 : return nb_cli_apply_changes(vty, "./frr-ripd:rip");
784 : }
785 :
786 0 : void cli_show_ip_rip_send_version(struct vty *vty, const struct lyd_node *dnode,
787 : bool show_defaults)
788 : {
789 0 : switch (yang_dnode_get_enum(dnode, NULL)) {
790 0 : case RI_RIP_UNSPEC:
791 0 : vty_out(vty, " no ip rip send version\n");
792 0 : break;
793 0 : case RI_RIP_VERSION_1:
794 0 : vty_out(vty, " ip rip send version 1\n");
795 0 : break;
796 0 : case RI_RIP_VERSION_2:
797 0 : vty_out(vty, " ip rip send version 2\n");
798 0 : break;
799 0 : case RI_RIP_VERSION_1_AND_2:
800 0 : vty_out(vty, " ip rip send version 1 2\n");
801 0 : break;
802 0 : case RI_RIP_VERSION_NONE:
803 0 : vty_out(vty, " ip rip send version none\n");
804 0 : break;
805 : }
806 0 : }
807 :
808 : /*
809 : * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme
810 : */
811 0 : 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 0 : const char *value = NULL;
825 :
826 0 : if (auth_length) {
827 0 : if (strmatch(auth_length, "rfc"))
828 : value = "16";
829 : else
830 0 : value = "20";
831 : }
832 :
833 0 : nb_cli_enqueue_change(vty, "./authentication-scheme/mode", NB_OP_MODIFY,
834 0 : strmatch(mode, "md5") ? "md5" : "plain-text");
835 0 : if (strmatch(mode, "md5"))
836 0 : nb_cli_enqueue_change(vty,
837 : "./authentication-scheme/md5-auth-length",
838 : NB_OP_MODIFY, value);
839 :
840 0 : return nb_cli_apply_changes(vty, "./frr-ripd:rip");
841 : }
842 :
843 0 : 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 0 : nb_cli_enqueue_change(vty, "./authentication-scheme/mode", NB_OP_MODIFY,
858 : NULL);
859 0 : nb_cli_enqueue_change(vty, "./authentication-scheme/md5-auth-length",
860 : NB_OP_DESTROY, NULL);
861 :
862 0 : return nb_cli_apply_changes(vty, "./frr-ripd:rip");
863 : }
864 :
865 0 : void cli_show_ip_rip_authentication_scheme(struct vty *vty,
866 : const struct lyd_node *dnode,
867 : bool show_defaults)
868 : {
869 0 : switch (yang_dnode_get_enum(dnode, "./mode")) {
870 0 : case RIP_NO_AUTH:
871 0 : vty_out(vty, " no ip rip authentication mode\n");
872 0 : break;
873 0 : case RIP_AUTH_SIMPLE_PASSWORD:
874 0 : vty_out(vty, " ip rip authentication mode text\n");
875 0 : break;
876 0 : case RIP_AUTH_MD5:
877 0 : vty_out(vty, " ip rip authentication mode md5");
878 0 : if (show_defaults
879 0 : || !yang_dnode_is_default(dnode, "./md5-auth-length")) {
880 0 : if (yang_dnode_get_enum(dnode, "./md5-auth-length")
881 : == RIP_AUTH_MD5_SIZE)
882 0 : vty_out(vty, " auth-length rfc");
883 : else
884 0 : vty_out(vty, " auth-length old-ripd");
885 : }
886 0 : vty_out(vty, "\n");
887 0 : break;
888 : }
889 0 : }
890 :
891 : /*
892 : * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-password
893 : */
894 0 : 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 0 : if (strlen(password) > 16) {
904 0 : vty_out(vty,
905 : "%% RIPv2 authentication string must be shorter than 16\n");
906 0 : return CMD_WARNING_CONFIG_FAILED;
907 : }
908 :
909 0 : if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
910 0 : VTY_CURR_XPATH,
911 : "/frr-ripd:rip/authentication-key-chain")) {
912 0 : vty_out(vty, "%% key-chain configuration exists\n");
913 0 : return CMD_WARNING_CONFIG_FAILED;
914 : }
915 :
916 0 : nb_cli_enqueue_change(vty, "./authentication-password", NB_OP_MODIFY,
917 : password);
918 :
919 0 : return nb_cli_apply_changes(vty, "./frr-ripd:rip");
920 : }
921 :
922 0 : 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 0 : nb_cli_enqueue_change(vty, "./authentication-password", NB_OP_DESTROY,
933 : NULL);
934 :
935 0 : return nb_cli_apply_changes(vty, "./frr-ripd:rip");
936 : }
937 :
938 0 : void cli_show_ip_rip_authentication_string(struct vty *vty,
939 : const struct lyd_node *dnode,
940 : bool show_defaults)
941 : {
942 0 : vty_out(vty, " ip rip authentication string %s\n",
943 : yang_dnode_get_string(dnode, NULL));
944 0 : }
945 :
946 : /*
947 : * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain
948 : */
949 0 : 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 0 : if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
959 0 : VTY_CURR_XPATH,
960 : "/frr-ripd:rip/authentication-password")) {
961 0 : vty_out(vty, "%% authentication string configuration exists\n");
962 0 : return CMD_WARNING_CONFIG_FAILED;
963 : }
964 :
965 0 : nb_cli_enqueue_change(vty, "./authentication-key-chain", NB_OP_MODIFY,
966 : keychain);
967 :
968 0 : return nb_cli_apply_changes(vty, "./frr-ripd:rip");
969 : }
970 :
971 0 : 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 0 : nb_cli_enqueue_change(vty, "./authentication-key-chain", NB_OP_DESTROY,
982 : NULL);
983 :
984 0 : return nb_cli_apply_changes(vty, "./frr-ripd:rip");
985 : }
986 :
987 0 : void cli_show_ip_rip_authentication_key_chain(struct vty *vty,
988 : const struct lyd_node *dnode,
989 : bool show_defaults)
990 : {
991 0 : vty_out(vty, " ip rip authentication key-chain %s\n",
992 : yang_dnode_get_string(dnode, NULL));
993 0 : }
994 :
995 : /*
996 : * XPath: /frr-ripd:clear-rip-route
997 : */
998 0 : 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 0 : struct list *input;
1007 0 : int ret;
1008 :
1009 0 : input = list_new();
1010 0 : if (vrf) {
1011 0 : struct yang_data *yang_vrf;
1012 :
1013 0 : yang_vrf = yang_data_new("/frr-ripd:clear-rip-route/input/vrf",
1014 : vrf);
1015 0 : listnode_add(input, yang_vrf);
1016 : }
1017 :
1018 0 : ret = nb_cli_rpc(vty, "/frr-ripd:clear-rip-route", input, NULL);
1019 :
1020 0 : list_delete(&input);
1021 :
1022 0 : return ret;
1023 : }
1024 :
1025 0 : 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 0 : const char *ifname = NULL;
1036 0 : int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0;
1037 :
1038 0 : if (argv[argc - 1]->type == VARIABLE_TKN)
1039 0 : ifname = argv[argc - 1]->arg;
1040 :
1041 0 : return distribute_list_parser(prefix, true, argv[2 + prefix]->text,
1042 0 : argv[1 + prefix]->arg, ifname);
1043 : }
1044 :
1045 0 : 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 0 : const char *ifname = NULL;
1057 0 : int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
1058 :
1059 0 : if (argv[argc - 1]->type == VARIABLE_TKN)
1060 0 : ifname = argv[argc - 1]->arg;
1061 :
1062 0 : return distribute_list_no_parser(vty, prefix, true,
1063 0 : argv[3 + prefix]->text,
1064 0 : argv[2 + prefix]->arg, ifname);
1065 : }
1066 :
1067 4 : void rip_cli_init(void)
1068 : {
1069 4 : install_element(CONFIG_NODE, &router_rip_cmd);
1070 4 : install_element(CONFIG_NODE, &no_router_rip_cmd);
1071 :
1072 4 : install_element(RIP_NODE, &rip_distribute_list_cmd);
1073 4 : install_element(RIP_NODE, &rip_no_distribute_list_cmd);
1074 :
1075 4 : install_element(RIP_NODE, &rip_allow_ecmp_cmd);
1076 4 : install_element(RIP_NODE, &rip_default_information_originate_cmd);
1077 4 : install_element(RIP_NODE, &rip_default_metric_cmd);
1078 4 : install_element(RIP_NODE, &no_rip_default_metric_cmd);
1079 4 : install_element(RIP_NODE, &rip_distance_cmd);
1080 4 : install_element(RIP_NODE, &no_rip_distance_cmd);
1081 4 : install_element(RIP_NODE, &rip_distance_source_cmd);
1082 4 : install_element(RIP_NODE, &rip_neighbor_cmd);
1083 4 : install_element(RIP_NODE, &rip_network_prefix_cmd);
1084 4 : install_element(RIP_NODE, &rip_network_if_cmd);
1085 4 : install_element(RIP_NODE, &rip_offset_list_cmd);
1086 4 : install_element(RIP_NODE, &rip_passive_default_cmd);
1087 4 : install_element(RIP_NODE, &rip_passive_interface_cmd);
1088 4 : install_element(RIP_NODE, &rip_redistribute_cmd);
1089 4 : install_element(RIP_NODE, &rip_route_cmd);
1090 4 : install_element(RIP_NODE, &rip_timers_cmd);
1091 4 : install_element(RIP_NODE, &no_rip_timers_cmd);
1092 4 : install_element(RIP_NODE, &rip_version_cmd);
1093 4 : install_element(RIP_NODE, &no_rip_version_cmd);
1094 :
1095 4 : install_element(INTERFACE_NODE, &ip_rip_split_horizon_cmd);
1096 4 : install_element(INTERFACE_NODE, &ip_rip_v2_broadcast_cmd);
1097 4 : install_element(INTERFACE_NODE, &ip_rip_receive_version_cmd);
1098 4 : install_element(INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
1099 4 : install_element(INTERFACE_NODE, &ip_rip_send_version_cmd);
1100 4 : install_element(INTERFACE_NODE, &no_ip_rip_send_version_cmd);
1101 4 : install_element(INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
1102 4 : install_element(INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
1103 4 : install_element(INTERFACE_NODE, &ip_rip_authentication_string_cmd);
1104 4 : install_element(INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
1105 4 : install_element(INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
1106 4 : install_element(INTERFACE_NODE,
1107 : &no_ip_rip_authentication_key_chain_cmd);
1108 :
1109 4 : install_element(ENABLE_NODE, &clear_ip_rip_cmd);
1110 4 : }
|