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