]> git.proxmox.com Git - mirror_frr.git/blob - ripngd/ripng_cli.c
*: Fix spelling of atleast
[mirror_frr.git] / ripngd / ripng_cli.c
1 /*
2 * Copyright (C) 1998 Kunihiro Ishiguro
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 "ripngd/ripngd.h"
32 #include "ripngd/ripng_nb.h"
33 #ifndef VTYSH_EXTRACT_PL
34 #include "ripngd/ripng_cli_clippy.c"
35 #endif
36
37 /*
38 * XPath: /frr-ripngd:ripngd/instance
39 */
40 DEFPY_YANG_NOSH (router_ripng,
41 router_ripng_cmd,
42 "router ripng [vrf NAME]",
43 "Enable a routing process\n"
44 "Make RIPng instance command\n"
45 VRF_CMD_HELP_STR)
46 {
47 char xpath[XPATH_MAXLEN];
48 int ret;
49
50 /* Build RIPng instance XPath. */
51 if (!vrf)
52 vrf = VRF_DEFAULT_NAME;
53 snprintf(xpath, sizeof(xpath), "/frr-ripngd:ripngd/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(RIPNG_NODE, xpath);
61
62 return ret;
63 }
64
65 DEFPY_YANG (no_router_ripng,
66 no_router_ripng_cmd,
67 "no router ripng [vrf NAME]",
68 NO_STR
69 "Enable a routing process\n"
70 "Make RIPng instance command\n"
71 VRF_CMD_HELP_STR)
72 {
73 char xpath[XPATH_MAXLEN];
74
75 /* Build RIPng instance XPath. */
76 if (!vrf)
77 vrf = VRF_DEFAULT_NAME;
78 snprintf(xpath, sizeof(xpath), "/frr-ripngd:ripngd/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_ripng(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 ripng");
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-ripngd:ripngd/instance/allow-ecmp
102 */
103 DEFPY_YANG (ripng_allow_ecmp,
104 ripng_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_ripng_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-ripngd:ripngd/instance/default-information-originate
126 */
127 DEFPY_YANG (ripng_default_information_originate,
128 ripng_default_information_originate_cmd,
129 "[no] default-information originate",
130 NO_STR
131 "Default route information\n"
132 "Distribute 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_ripng_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-ripngd:ripngd/instance/default-metric
152 */
153 DEFPY_YANG (ripng_default_metric,
154 ripng_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_ripng_default_metric,
166 no_ripng_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_ripng_default_metric(struct vty *vty,
178 const struct lyd_node *dnode,
179 bool show_defaults)
180 {
181 vty_out(vty, " default-metric %s\n",
182 yang_dnode_get_string(dnode, NULL));
183 }
184
185 /*
186 * XPath: /frr-ripngd:ripngd/instance/network
187 */
188 DEFPY_YANG (ripng_network_prefix,
189 ripng_network_prefix_cmd,
190 "[no] network X:X::X:X/M",
191 NO_STR
192 "RIPng enable on specified interface or network.\n"
193 "IPv6 network\n")
194 {
195 nb_cli_enqueue_change(vty, "./network",
196 no ? NB_OP_DESTROY : NB_OP_CREATE, network_str);
197
198 return nb_cli_apply_changes(vty, NULL);
199 }
200
201 void cli_show_ripng_network_prefix(struct vty *vty,
202 const struct lyd_node *dnode,
203 bool show_defaults)
204 {
205 vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL));
206 }
207
208 /*
209 * XPath: /frr-ripngd:ripngd/instance/interface
210 */
211 DEFPY_YANG (ripng_network_if,
212 ripng_network_if_cmd,
213 "[no] network WORD",
214 NO_STR
215 "RIPng enable on specified interface or network.\n"
216 "Interface name\n")
217 {
218 nb_cli_enqueue_change(vty, "./interface",
219 no ? NB_OP_DESTROY : NB_OP_CREATE, network);
220
221 return nb_cli_apply_changes(vty, NULL);
222 }
223
224 void cli_show_ripng_network_interface(struct vty *vty,
225 const struct lyd_node *dnode,
226 bool show_defaults)
227 {
228 vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL));
229 }
230
231 /*
232 * XPath: /frr-ripngd:ripngd/instance/offset-list
233 */
234 DEFPY_YANG (ripng_offset_list,
235 ripng_offset_list_cmd,
236 "[no] offset-list ACCESSLIST6_NAME$acl <in|out>$direction (0-16)$metric [IFNAME]",
237 NO_STR
238 "Modify RIPng metric\n"
239 "Access-list name\n"
240 "For incoming updates\n"
241 "For outgoing updates\n"
242 "Metric value\n"
243 "Interface to match\n")
244 {
245 if (!no) {
246 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
247 nb_cli_enqueue_change(vty, "./access-list", NB_OP_MODIFY, acl);
248 nb_cli_enqueue_change(vty, "./metric", NB_OP_MODIFY,
249 metric_str);
250 } else
251 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
252
253 return nb_cli_apply_changes(
254 vty, "./offset-list[interface='%s'][direction='%s']",
255 ifname ? ifname : "*", direction);
256 }
257
258 void cli_show_ripng_offset_list(struct vty *vty, const struct lyd_node *dnode,
259 bool show_defaults)
260 {
261 const char *interface;
262
263 interface = yang_dnode_get_string(dnode, "./interface");
264
265 vty_out(vty, " offset-list %s %s %s",
266 yang_dnode_get_string(dnode, "./access-list"),
267 yang_dnode_get_string(dnode, "./direction"),
268 yang_dnode_get_string(dnode, "./metric"));
269 if (!strmatch(interface, "*"))
270 vty_out(vty, " %s", interface);
271 vty_out(vty, "\n");
272 }
273
274 /*
275 * XPath: /frr-ripngd:ripngd/instance/passive-interface
276 */
277 DEFPY_YANG (ripng_passive_interface,
278 ripng_passive_interface_cmd,
279 "[no] passive-interface IFNAME",
280 NO_STR
281 "Suppress routing updates on an interface\n"
282 "Interface name\n")
283 {
284 nb_cli_enqueue_change(vty, "./passive-interface",
285 no ? NB_OP_DESTROY : NB_OP_CREATE, ifname);
286
287 return nb_cli_apply_changes(vty, NULL);
288 }
289
290 void cli_show_ripng_passive_interface(struct vty *vty,
291 const struct lyd_node *dnode,
292 bool show_defaults)
293 {
294 vty_out(vty, " passive-interface %s\n",
295 yang_dnode_get_string(dnode, NULL));
296 }
297
298 /*
299 * XPath: /frr-ripngd:ripngd/instance/redistribute
300 */
301 DEFPY_YANG (ripng_redistribute,
302 ripng_redistribute_cmd,
303 "[no] redistribute " FRR_REDIST_STR_RIPNGD "$protocol [{metric (0-16)|route-map WORD}]",
304 NO_STR
305 REDIST_STR
306 FRR_REDIST_HELP_STR_RIPNGD
307 "Metric\n"
308 "Metric value\n"
309 "Route map reference\n"
310 "Pointer to route-map entries\n")
311 {
312 if (!no) {
313 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
314 nb_cli_enqueue_change(vty, "./route-map",
315 route_map ? NB_OP_MODIFY : NB_OP_DESTROY,
316 route_map);
317 nb_cli_enqueue_change(vty, "./metric",
318 metric_str ? NB_OP_MODIFY : NB_OP_DESTROY,
319 metric_str);
320 } else
321 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
322
323 return nb_cli_apply_changes(vty, "./redistribute[protocol='%s']",
324 protocol);
325 }
326
327 void cli_show_ripng_redistribute(struct vty *vty, const struct lyd_node *dnode,
328 bool show_defaults)
329 {
330 vty_out(vty, " redistribute %s",
331 yang_dnode_get_string(dnode, "./protocol"));
332 if (yang_dnode_exists(dnode, "./metric"))
333 vty_out(vty, " metric %s",
334 yang_dnode_get_string(dnode, "./metric"));
335 if (yang_dnode_exists(dnode, "./route-map"))
336 vty_out(vty, " route-map %s",
337 yang_dnode_get_string(dnode, "./route-map"));
338 vty_out(vty, "\n");
339 }
340
341 /*
342 * XPath: /frr-ripngd:ripngd/instance/static-route
343 */
344 DEFPY_YANG (ripng_route,
345 ripng_route_cmd,
346 "[no] route X:X::X:X/M",
347 NO_STR
348 "Static route setup\n"
349 "Set static RIPng route announcement\n")
350 {
351 nb_cli_enqueue_change(vty, "./static-route",
352 no ? NB_OP_DESTROY : NB_OP_CREATE, route_str);
353
354 return nb_cli_apply_changes(vty, NULL);
355 }
356
357 void cli_show_ripng_route(struct vty *vty, const struct lyd_node *dnode,
358 bool show_defaults)
359 {
360 vty_out(vty, " route %s\n", yang_dnode_get_string(dnode, NULL));
361 }
362
363 /*
364 * XPath: /frr-ripngd:ripngd/instance/aggregate-addres
365 */
366 DEFPY_YANG (ripng_aggregate_address,
367 ripng_aggregate_address_cmd,
368 "[no] aggregate-address X:X::X:X/M",
369 NO_STR
370 "Set aggregate RIPng route announcement\n"
371 "Aggregate network\n")
372 {
373 nb_cli_enqueue_change(vty, "./aggregate-address",
374 no ? NB_OP_DESTROY : NB_OP_CREATE,
375 aggregate_address_str);
376
377 return nb_cli_apply_changes(vty, NULL);
378 }
379
380 void cli_show_ripng_aggregate_address(struct vty *vty,
381 const struct lyd_node *dnode,
382 bool show_defaults)
383 {
384 vty_out(vty, " aggregate-address %s\n",
385 yang_dnode_get_string(dnode, NULL));
386 }
387
388 /*
389 * XPath: /frr-ripngd:ripngd/instance/timers
390 */
391 DEFPY_YANG (ripng_timers,
392 ripng_timers_cmd,
393 "timers basic (1-65535)$update (1-65535)$timeout (1-65535)$garbage",
394 "RIPng timers setup\n"
395 "Basic timer\n"
396 "Routing table update timer value in second. Default is 30.\n"
397 "Routing information timeout timer. Default is 180.\n"
398 "Garbage collection timer. Default is 120.\n")
399 {
400 nb_cli_enqueue_change(vty, "./update-interval", NB_OP_MODIFY,
401 update_str);
402 nb_cli_enqueue_change(vty, "./holddown-interval", NB_OP_MODIFY,
403 timeout_str);
404 nb_cli_enqueue_change(vty, "./flush-interval", NB_OP_MODIFY,
405 garbage_str);
406
407 return nb_cli_apply_changes(vty, "./timers");
408 }
409
410 DEFPY_YANG (no_ripng_timers,
411 no_ripng_timers_cmd,
412 "no timers basic [(1-65535) (1-65535) (1-65535)]",
413 NO_STR
414 "RIPng timers setup\n"
415 "Basic timer\n"
416 "Routing table update timer value in second. Default is 30.\n"
417 "Routing information timeout timer. Default is 180.\n"
418 "Garbage collection timer. Default is 120.\n")
419 {
420 nb_cli_enqueue_change(vty, "./update-interval", NB_OP_MODIFY, NULL);
421 nb_cli_enqueue_change(vty, "./holddown-interval", NB_OP_MODIFY, NULL);
422 nb_cli_enqueue_change(vty, "./flush-interval", NB_OP_MODIFY, NULL);
423
424 return nb_cli_apply_changes(vty, "./timers");
425 }
426
427 void cli_show_ripng_timers(struct vty *vty, const struct lyd_node *dnode,
428 bool show_defaults)
429 {
430 vty_out(vty, " timers basic %s %s %s\n",
431 yang_dnode_get_string(dnode, "./update-interval"),
432 yang_dnode_get_string(dnode, "./holddown-interval"),
433 yang_dnode_get_string(dnode, "./flush-interval"));
434 }
435
436 /*
437 * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon
438 */
439 DEFPY_YANG (ipv6_ripng_split_horizon,
440 ipv6_ripng_split_horizon_cmd,
441 "[no] ipv6 ripng split-horizon [poisoned-reverse$poisoned_reverse]",
442 NO_STR
443 IPV6_STR
444 "Routing Information Protocol\n"
445 "Perform split horizon\n"
446 "With poisoned-reverse\n")
447 {
448 const char *value;
449
450 if (no)
451 value = "disabled";
452 else if (poisoned_reverse)
453 value = "poison-reverse";
454 else
455 value = "simple";
456
457 nb_cli_enqueue_change(vty, "./split-horizon", NB_OP_MODIFY, value);
458
459 return nb_cli_apply_changes(vty, "./frr-ripngd:ripng");
460 }
461
462 void cli_show_ipv6_ripng_split_horizon(struct vty *vty,
463 const struct lyd_node *dnode,
464 bool show_defaults)
465 {
466 int value;
467
468 value = yang_dnode_get_enum(dnode, NULL);
469 switch (value) {
470 case RIPNG_NO_SPLIT_HORIZON:
471 vty_out(vty, " no ipv6 ripng split-horizon\n");
472 break;
473 case RIPNG_SPLIT_HORIZON:
474 vty_out(vty, " ipv6 ripng split-horizon\n");
475 break;
476 case RIPNG_SPLIT_HORIZON_POISONED_REVERSE:
477 vty_out(vty, " ipv6 ripng split-horizon poisoned-reverse\n");
478 break;
479 }
480 }
481
482 /*
483 * XPath: /frr-ripngd:clear-ripng-route
484 */
485 DEFPY_YANG (clear_ipv6_rip,
486 clear_ipv6_rip_cmd,
487 "clear ipv6 ripng [vrf WORD]",
488 CLEAR_STR
489 IPV6_STR
490 "Clear IPv6 RIP database\n"
491 VRF_CMD_HELP_STR)
492 {
493 struct list *input;
494 int ret;
495
496 input = list_new();
497 if (vrf) {
498 struct yang_data *yang_vrf;
499
500 yang_vrf = yang_data_new(
501 "/frr-ripngd:clear-ripng-route/input/vrf", vrf);
502 listnode_add(input, yang_vrf);
503 }
504
505 ret = nb_cli_rpc(vty, "/frr-ripngd:clear-ripng-route", input, NULL);
506
507 list_delete(&input);
508
509 return ret;
510 }
511
512 DEFUN (ripng_ipv6_distribute_list,
513 ripng_ipv6_distribute_list_cmd,
514 "ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]",
515 "IPv6\n"
516 "Filter networks in routing updates\n"
517 "Specify a prefix\n"
518 "Access-list name\n"
519 "Filter incoming routing updates\n"
520 "Filter outgoing routing updates\n"
521 "Interface name\n")
522 {
523 const char *ifname = NULL;
524 int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
525
526 if (argv[argc - 1]->type == VARIABLE_TKN)
527 ifname = argv[argc - 1]->arg;
528
529 return distribute_list_parser(prefix, false, argv[3 + prefix]->text,
530 argv[2 + prefix]->arg, ifname);
531 }
532
533 DEFUN (ripng_no_ipv6_distribute_list,
534 ripng_no_ipv6_distribute_list_cmd,
535 "no ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]",
536 NO_STR
537 "IPv6\n"
538 "Filter networks in routing updates\n"
539 "Specify a prefix\n"
540 "Access-list name\n"
541 "Filter incoming routing updates\n"
542 "Filter outgoing routing updates\n"
543 "Interface name\n")
544 {
545 const char *ifname = NULL;
546 int prefix = (argv[3]->type == WORD_TKN) ? 1 : 0;
547
548 if (argv[argc - 1]->type == VARIABLE_TKN)
549 ifname = argv[argc - 1]->arg;
550
551 return distribute_list_no_parser(vty, prefix, false,
552 argv[4 + prefix]->text,
553 argv[3 + prefix]->arg, ifname);
554 }
555
556 void ripng_cli_init(void)
557 {
558 install_element(CONFIG_NODE, &router_ripng_cmd);
559 install_element(CONFIG_NODE, &no_router_ripng_cmd);
560
561 install_element(RIPNG_NODE, &ripng_ipv6_distribute_list_cmd);
562 install_element(RIPNG_NODE, &ripng_no_ipv6_distribute_list_cmd);
563
564 install_element(RIPNG_NODE, &ripng_allow_ecmp_cmd);
565 install_element(RIPNG_NODE, &ripng_default_information_originate_cmd);
566 install_element(RIPNG_NODE, &ripng_default_metric_cmd);
567 install_element(RIPNG_NODE, &no_ripng_default_metric_cmd);
568 install_element(RIPNG_NODE, &ripng_network_prefix_cmd);
569 install_element(RIPNG_NODE, &ripng_network_if_cmd);
570 install_element(RIPNG_NODE, &ripng_offset_list_cmd);
571 install_element(RIPNG_NODE, &ripng_passive_interface_cmd);
572 install_element(RIPNG_NODE, &ripng_redistribute_cmd);
573 install_element(RIPNG_NODE, &ripng_route_cmd);
574 install_element(RIPNG_NODE, &ripng_aggregate_address_cmd);
575 install_element(RIPNG_NODE, &ripng_timers_cmd);
576 install_element(RIPNG_NODE, &no_ripng_timers_cmd);
577
578 install_element(INTERFACE_NODE, &ipv6_ripng_split_horizon_cmd);
579
580 install_element(ENABLE_NODE, &clear_ipv6_rip_cmd);
581 }