]> git.proxmox.com Git - mirror_frr.git/blame - ripngd/ripng_cli.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / ripngd / ripng_cli.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
e9ce224b
RW
2/*
3 * Copyright (C) 1998 Kunihiro Ishiguro
4 * Copyright (C) 2018 NetDEF, Inc.
5 * Renato Westphal
e9ce224b
RW
6 */
7
8#include <zebra.h>
9
10#include "if.h"
11#include "vrf.h"
12#include "log.h"
13#include "prefix.h"
14#include "command.h"
15#include "northbound_cli.h"
16#include "libfrr.h"
17
18#include "ripngd/ripngd.h"
ca473936 19#include "ripngd/ripng_nb.h"
e9ce224b 20#include "ripngd/ripng_cli_clippy.c"
e9ce224b 21
9a12e9e5
RW
22/*
23 * XPath: /frr-ripngd:ripngd/instance
24 */
ca77b518 25DEFPY_YANG_NOSH (router_ripng,
9a12e9e5 26 router_ripng_cmd,
dde7b15b 27 "router ripng [vrf NAME]",
9a12e9e5 28 "Enable a routing process\n"
dde7b15b
RW
29 "Make RIPng instance command\n"
30 VRF_CMD_HELP_STR)
9a12e9e5 31{
dde7b15b 32 char xpath[XPATH_MAXLEN];
9a12e9e5
RW
33 int ret;
34
dde7b15b
RW
35 /* Build RIPng instance XPath. */
36 if (!vrf)
37 vrf = VRF_DEFAULT_NAME;
38 snprintf(xpath, sizeof(xpath), "/frr-ripngd:ripngd/instance[vrf='%s']",
39 vrf);
40
41 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
9a12e9e5
RW
42
43 ret = nb_cli_apply_changes(vty, NULL);
44 if (ret == CMD_SUCCESS)
dde7b15b 45 VTY_PUSH_XPATH(RIPNG_NODE, xpath);
9a12e9e5
RW
46
47 return ret;
48}
49
ca77b518 50DEFPY_YANG (no_router_ripng,
9a12e9e5 51 no_router_ripng_cmd,
dde7b15b 52 "no router ripng [vrf NAME]",
9a12e9e5
RW
53 NO_STR
54 "Enable a routing process\n"
dde7b15b
RW
55 "Make RIPng instance command\n"
56 VRF_CMD_HELP_STR)
9a12e9e5 57{
dde7b15b
RW
58 char xpath[XPATH_MAXLEN];
59
60 /* Build RIPng instance XPath. */
61 if (!vrf)
62 vrf = VRF_DEFAULT_NAME;
63 snprintf(xpath, sizeof(xpath), "/frr-ripngd:ripngd/instance[vrf='%s']",
64 vrf);
65
8f88441d 66 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
9a12e9e5 67
fd396924 68 return nb_cli_apply_changes_clear_pending(vty, NULL);
9a12e9e5
RW
69}
70
25605051
IR
71void cli_show_router_ripng(struct vty *vty, const struct lyd_node *dnode,
72 bool show_defaults)
9a12e9e5 73{
dde7b15b
RW
74 const char *vrf_name;
75
76 vrf_name = yang_dnode_get_string(dnode, "./vrf");
77
9a12e9e5 78 vty_out(vty, "!\n");
dde7b15b
RW
79 vty_out(vty, "router ripng");
80 if (!strmatch(vrf_name, VRF_DEFAULT_NAME))
81 vty_out(vty, " vrf %s", vrf_name);
82 vty_out(vty, "\n");
9a12e9e5
RW
83}
84
1e42a07c
RW
85/*
86 * XPath: /frr-ripngd:ripngd/instance/allow-ecmp
87 */
ca77b518 88DEFPY_YANG (ripng_allow_ecmp,
1e42a07c
RW
89 ripng_allow_ecmp_cmd,
90 "[no] allow-ecmp",
91 NO_STR
92 "Allow Equal Cost MultiPath\n")
93{
94 nb_cli_enqueue_change(vty, "./allow-ecmp", NB_OP_MODIFY,
95 no ? "false" : "true");
96
97 return nb_cli_apply_changes(vty, NULL);
98}
99
25605051 100void cli_show_ripng_allow_ecmp(struct vty *vty, const struct lyd_node *dnode,
1e42a07c
RW
101 bool show_defaults)
102{
103 if (!yang_dnode_get_bool(dnode, NULL))
104 vty_out(vty, " no");
105
106 vty_out(vty, " allow-ecmp\n");
107}
108
54b56562
RW
109/*
110 * XPath: /frr-ripngd:ripngd/instance/default-information-originate
111 */
ca77b518 112DEFPY_YANG (ripng_default_information_originate,
54b56562
RW
113 ripng_default_information_originate_cmd,
114 "[no] default-information originate",
115 NO_STR
116 "Default route information\n"
117 "Distribute default route\n")
118{
119 nb_cli_enqueue_change(vty, "./default-information-originate",
120 NB_OP_MODIFY, no ? "false" : "true");
121
122 return nb_cli_apply_changes(vty, NULL);
123}
124
125void cli_show_ripng_default_information_originate(struct vty *vty,
25605051 126 const struct lyd_node *dnode,
54b56562
RW
127 bool show_defaults)
128{
129 if (!yang_dnode_get_bool(dnode, NULL))
130 vty_out(vty, " no");
131
132 vty_out(vty, " default-information originate\n");
133}
134
ad8778c0
RW
135/*
136 * XPath: /frr-ripngd:ripngd/instance/default-metric
137 */
ca77b518 138DEFPY_YANG (ripng_default_metric,
ad8778c0
RW
139 ripng_default_metric_cmd,
140 "default-metric (1-16)",
141 "Set a metric of redistribute routes\n"
142 "Default metric\n")
143{
144 nb_cli_enqueue_change(vty, "./default-metric", NB_OP_MODIFY,
145 default_metric_str);
146
147 return nb_cli_apply_changes(vty, NULL);
148}
149
ca77b518 150DEFPY_YANG (no_ripng_default_metric,
ad8778c0
RW
151 no_ripng_default_metric_cmd,
152 "no default-metric [(1-16)]",
153 NO_STR
154 "Set a metric of redistribute routes\n"
155 "Default metric\n")
156{
157 nb_cli_enqueue_change(vty, "./default-metric", NB_OP_MODIFY, NULL);
158
159 return nb_cli_apply_changes(vty, NULL);
160}
161
25605051
IR
162void cli_show_ripng_default_metric(struct vty *vty,
163 const struct lyd_node *dnode,
ad8778c0
RW
164 bool show_defaults)
165{
166 vty_out(vty, " default-metric %s\n",
167 yang_dnode_get_string(dnode, NULL));
168}
169
cc48702b
RW
170/*
171 * XPath: /frr-ripngd:ripngd/instance/network
172 */
ca77b518 173DEFPY_YANG (ripng_network_prefix,
cc48702b
RW
174 ripng_network_prefix_cmd,
175 "[no] network X:X::X:X/M",
176 NO_STR
177 "RIPng enable on specified interface or network.\n"
178 "IPv6 network\n")
179{
180 nb_cli_enqueue_change(vty, "./network",
95ce849b 181 no ? NB_OP_DESTROY : NB_OP_CREATE, network_str);
cc48702b
RW
182
183 return nb_cli_apply_changes(vty, NULL);
184}
185
25605051
IR
186void cli_show_ripng_network_prefix(struct vty *vty,
187 const struct lyd_node *dnode,
cc48702b
RW
188 bool show_defaults)
189{
190 vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL));
191}
192
193/*
194 * XPath: /frr-ripngd:ripngd/instance/interface
195 */
ca77b518 196DEFPY_YANG (ripng_network_if,
cc48702b
RW
197 ripng_network_if_cmd,
198 "[no] network WORD",
199 NO_STR
200 "RIPng enable on specified interface or network.\n"
201 "Interface name\n")
202{
203 nb_cli_enqueue_change(vty, "./interface",
95ce849b 204 no ? NB_OP_DESTROY : NB_OP_CREATE, network);
cc48702b
RW
205
206 return nb_cli_apply_changes(vty, NULL);
207}
208
25605051
IR
209void cli_show_ripng_network_interface(struct vty *vty,
210 const struct lyd_node *dnode,
cc48702b
RW
211 bool show_defaults)
212{
213 vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL));
214}
215
b09956ca
RW
216/*
217 * XPath: /frr-ripngd:ripngd/instance/offset-list
218 */
ca77b518 219DEFPY_YANG (ripng_offset_list,
b09956ca 220 ripng_offset_list_cmd,
c60dec36 221 "[no] offset-list ACCESSLIST6_NAME$acl <in|out>$direction (0-16)$metric [IFNAME]",
b09956ca
RW
222 NO_STR
223 "Modify RIPng metric\n"
224 "Access-list name\n"
225 "For incoming updates\n"
226 "For outgoing updates\n"
227 "Metric value\n"
228 "Interface to match\n")
229{
230 if (!no) {
231 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
232 nb_cli_enqueue_change(vty, "./access-list", NB_OP_MODIFY, acl);
233 nb_cli_enqueue_change(vty, "./metric", NB_OP_MODIFY,
234 metric_str);
235 } else
95ce849b 236 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
b09956ca
RW
237
238 return nb_cli_apply_changes(
239 vty, "./offset-list[interface='%s'][direction='%s']",
240 ifname ? ifname : "*", direction);
241}
242
25605051 243void cli_show_ripng_offset_list(struct vty *vty, const struct lyd_node *dnode,
b09956ca
RW
244 bool show_defaults)
245{
246 const char *interface;
247
248 interface = yang_dnode_get_string(dnode, "./interface");
249
250 vty_out(vty, " offset-list %s %s %s",
251 yang_dnode_get_string(dnode, "./access-list"),
252 yang_dnode_get_string(dnode, "./direction"),
253 yang_dnode_get_string(dnode, "./metric"));
254 if (!strmatch(interface, "*"))
255 vty_out(vty, " %s", interface);
256 vty_out(vty, "\n");
257}
258
22e8c7ae
RW
259/*
260 * XPath: /frr-ripngd:ripngd/instance/passive-interface
261 */
ca77b518 262DEFPY_YANG (ripng_passive_interface,
22e8c7ae
RW
263 ripng_passive_interface_cmd,
264 "[no] passive-interface IFNAME",
265 NO_STR
266 "Suppress routing updates on an interface\n"
267 "Interface name\n")
268{
269 nb_cli_enqueue_change(vty, "./passive-interface",
95ce849b 270 no ? NB_OP_DESTROY : NB_OP_CREATE, ifname);
22e8c7ae
RW
271
272 return nb_cli_apply_changes(vty, NULL);
273}
274
25605051
IR
275void cli_show_ripng_passive_interface(struct vty *vty,
276 const struct lyd_node *dnode,
22e8c7ae
RW
277 bool show_defaults)
278{
279 vty_out(vty, " passive-interface %s\n",
280 yang_dnode_get_string(dnode, NULL));
281}
282
db2038c7
RW
283/*
284 * XPath: /frr-ripngd:ripngd/instance/redistribute
285 */
ca77b518 286DEFPY_YANG (ripng_redistribute,
db2038c7 287 ripng_redistribute_cmd,
70dd370f 288 "[no] redistribute " FRR_REDIST_STR_RIPNGD "$protocol [{metric (0-16)|route-map RMAP_NAME$route_map}]",
db2038c7
RW
289 NO_STR
290 REDIST_STR
291 FRR_REDIST_HELP_STR_RIPNGD
292 "Metric\n"
293 "Metric value\n"
294 "Route map reference\n"
295 "Pointer to route-map entries\n")
296{
297 if (!no) {
298 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
299 nb_cli_enqueue_change(vty, "./route-map",
95ce849b 300 route_map ? NB_OP_MODIFY : NB_OP_DESTROY,
db2038c7
RW
301 route_map);
302 nb_cli_enqueue_change(vty, "./metric",
95ce849b 303 metric_str ? NB_OP_MODIFY : NB_OP_DESTROY,
db2038c7
RW
304 metric_str);
305 } else
95ce849b 306 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
db2038c7
RW
307
308 return nb_cli_apply_changes(vty, "./redistribute[protocol='%s']",
309 protocol);
310}
311
25605051 312void cli_show_ripng_redistribute(struct vty *vty, const struct lyd_node *dnode,
db2038c7
RW
313 bool show_defaults)
314{
315 vty_out(vty, " redistribute %s",
316 yang_dnode_get_string(dnode, "./protocol"));
317 if (yang_dnode_exists(dnode, "./metric"))
318 vty_out(vty, " metric %s",
319 yang_dnode_get_string(dnode, "./metric"));
320 if (yang_dnode_exists(dnode, "./route-map"))
321 vty_out(vty, " route-map %s",
322 yang_dnode_get_string(dnode, "./route-map"));
323 vty_out(vty, "\n");
324}
325
521d1b12
RW
326/*
327 * XPath: /frr-ripngd:ripngd/instance/static-route
328 */
ca77b518 329DEFPY_YANG (ripng_route,
521d1b12
RW
330 ripng_route_cmd,
331 "[no] route X:X::X:X/M",
332 NO_STR
333 "Static route setup\n"
334 "Set static RIPng route announcement\n")
335{
336 nb_cli_enqueue_change(vty, "./static-route",
95ce849b 337 no ? NB_OP_DESTROY : NB_OP_CREATE, route_str);
521d1b12
RW
338
339 return nb_cli_apply_changes(vty, NULL);
340}
341
25605051 342void cli_show_ripng_route(struct vty *vty, const struct lyd_node *dnode,
521d1b12
RW
343 bool show_defaults)
344{
345 vty_out(vty, " route %s\n", yang_dnode_get_string(dnode, NULL));
346}
347
6fc29385
RW
348/*
349 * XPath: /frr-ripngd:ripngd/instance/aggregate-addres
350 */
ca77b518 351DEFPY_YANG (ripng_aggregate_address,
6fc29385
RW
352 ripng_aggregate_address_cmd,
353 "[no] aggregate-address X:X::X:X/M",
354 NO_STR
355 "Set aggregate RIPng route announcement\n"
356 "Aggregate network\n")
357{
358 nb_cli_enqueue_change(vty, "./aggregate-address",
95ce849b 359 no ? NB_OP_DESTROY : NB_OP_CREATE,
6fc29385
RW
360 aggregate_address_str);
361
362 return nb_cli_apply_changes(vty, NULL);
363}
364
25605051
IR
365void cli_show_ripng_aggregate_address(struct vty *vty,
366 const struct lyd_node *dnode,
6fc29385
RW
367 bool show_defaults)
368{
369 vty_out(vty, " aggregate-address %s\n",
370 yang_dnode_get_string(dnode, NULL));
371}
372
f8981ec5
RW
373/*
374 * XPath: /frr-ripngd:ripngd/instance/timers
375 */
ca77b518 376DEFPY_YANG (ripng_timers,
f8981ec5
RW
377 ripng_timers_cmd,
378 "timers basic (1-65535)$update (1-65535)$timeout (1-65535)$garbage",
379 "RIPng timers setup\n"
380 "Basic timer\n"
381 "Routing table update timer value in second. Default is 30.\n"
382 "Routing information timeout timer. Default is 180.\n"
383 "Garbage collection timer. Default is 120.\n")
384{
385 nb_cli_enqueue_change(vty, "./update-interval", NB_OP_MODIFY,
386 update_str);
387 nb_cli_enqueue_change(vty, "./holddown-interval", NB_OP_MODIFY,
388 timeout_str);
389 nb_cli_enqueue_change(vty, "./flush-interval", NB_OP_MODIFY,
390 garbage_str);
391
392 return nb_cli_apply_changes(vty, "./timers");
393}
394
ca77b518 395DEFPY_YANG (no_ripng_timers,
f8981ec5
RW
396 no_ripng_timers_cmd,
397 "no timers basic [(1-65535) (1-65535) (1-65535)]",
398 NO_STR
399 "RIPng timers setup\n"
400 "Basic timer\n"
401 "Routing table update timer value in second. Default is 30.\n"
402 "Routing information timeout timer. Default is 180.\n"
403 "Garbage collection timer. Default is 120.\n")
404{
405 nb_cli_enqueue_change(vty, "./update-interval", NB_OP_MODIFY, NULL);
406 nb_cli_enqueue_change(vty, "./holddown-interval", NB_OP_MODIFY, NULL);
407 nb_cli_enqueue_change(vty, "./flush-interval", NB_OP_MODIFY, NULL);
408
409 return nb_cli_apply_changes(vty, "./timers");
410}
411
25605051 412void cli_show_ripng_timers(struct vty *vty, const struct lyd_node *dnode,
f8981ec5
RW
413 bool show_defaults)
414{
415 vty_out(vty, " timers basic %s %s %s\n",
416 yang_dnode_get_string(dnode, "./update-interval"),
417 yang_dnode_get_string(dnode, "./holddown-interval"),
418 yang_dnode_get_string(dnode, "./flush-interval"));
419}
420
d406db4c
RW
421/*
422 * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon
423 */
ca77b518 424DEFPY_YANG (ipv6_ripng_split_horizon,
d406db4c
RW
425 ipv6_ripng_split_horizon_cmd,
426 "[no] ipv6 ripng split-horizon [poisoned-reverse$poisoned_reverse]",
427 NO_STR
428 IPV6_STR
429 "Routing Information Protocol\n"
430 "Perform split horizon\n"
431 "With poisoned-reverse\n")
432{
433 const char *value;
434
435 if (no)
436 value = "disabled";
437 else if (poisoned_reverse)
438 value = "poison-reverse";
439 else
440 value = "simple";
441
442 nb_cli_enqueue_change(vty, "./split-horizon", NB_OP_MODIFY, value);
443
444 return nb_cli_apply_changes(vty, "./frr-ripngd:ripng");
445}
446
25605051
IR
447void cli_show_ipv6_ripng_split_horizon(struct vty *vty,
448 const struct lyd_node *dnode,
d406db4c
RW
449 bool show_defaults)
450{
451 int value;
452
453 value = yang_dnode_get_enum(dnode, NULL);
454 switch (value) {
455 case RIPNG_NO_SPLIT_HORIZON:
456 vty_out(vty, " no ipv6 ripng split-horizon\n");
457 break;
458 case RIPNG_SPLIT_HORIZON:
459 vty_out(vty, " ipv6 ripng split-horizon\n");
460 break;
461 case RIPNG_SPLIT_HORIZON_POISONED_REVERSE:
462 vty_out(vty, " ipv6 ripng split-horizon poisoned-reverse\n");
463 break;
464 }
465}
466
49e06d25
RW
467/*
468 * XPath: /frr-ripngd:clear-ripng-route
469 */
ca77b518 470DEFPY_YANG (clear_ipv6_rip,
49e06d25 471 clear_ipv6_rip_cmd,
c5b2b5f6 472 "clear ipv6 ripng [vrf WORD]",
49e06d25
RW
473 CLEAR_STR
474 IPV6_STR
c5b2b5f6
RW
475 "Clear IPv6 RIP database\n"
476 VRF_CMD_HELP_STR)
49e06d25 477{
c5b2b5f6 478 struct list *input;
0783b36d 479 int ret;
c5b2b5f6
RW
480
481 input = list_new();
482 if (vrf) {
483 struct yang_data *yang_vrf;
484
485 yang_vrf = yang_data_new(
486 "/frr-ripngd:clear-ripng-route/input/vrf", vrf);
487 listnode_add(input, yang_vrf);
488 }
489
f63f5f19 490 ret = nb_cli_rpc(vty, "/frr-ripngd:clear-ripng-route", input, NULL);
0783b36d
DS
491
492 list_delete(&input);
493
494 return ret;
49e06d25
RW
495}
496
458133db
DS
497DEFUN (ripng_ipv6_distribute_list,
498 ripng_ipv6_distribute_list_cmd,
c60dec36 499 "ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]",
458133db
DS
500 "IPv6\n"
501 "Filter networks in routing updates\n"
502 "Specify a prefix\n"
503 "Access-list name\n"
504 "Filter incoming routing updates\n"
505 "Filter outgoing routing updates\n"
506 "Interface name\n")
507{
508 const char *ifname = NULL;
509 int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
510
511 if (argv[argc - 1]->type == VARIABLE_TKN)
512 ifname = argv[argc - 1]->arg;
513
514 return distribute_list_parser(prefix, false, argv[3 + prefix]->text,
515 argv[2 + prefix]->arg, ifname);
516}
517
518DEFUN (ripng_no_ipv6_distribute_list,
519 ripng_no_ipv6_distribute_list_cmd,
c60dec36 520 "no ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]",
458133db
DS
521 NO_STR
522 "IPv6\n"
523 "Filter networks in routing updates\n"
524 "Specify a prefix\n"
525 "Access-list name\n"
526 "Filter incoming routing updates\n"
527 "Filter outgoing routing updates\n"
528 "Interface name\n")
529{
530 const char *ifname = NULL;
531 int prefix = (argv[3]->type == WORD_TKN) ? 1 : 0;
532
533 if (argv[argc - 1]->type == VARIABLE_TKN)
534 ifname = argv[argc - 1]->arg;
535
536 return distribute_list_no_parser(vty, prefix, false,
537 argv[4 + prefix]->text,
538 argv[3 + prefix]->arg, ifname);
539}
540
e9ce224b
RW
541void ripng_cli_init(void)
542{
9a12e9e5
RW
543 install_element(CONFIG_NODE, &router_ripng_cmd);
544 install_element(CONFIG_NODE, &no_router_ripng_cmd);
1e42a07c 545
458133db
DS
546 install_element(RIPNG_NODE, &ripng_ipv6_distribute_list_cmd);
547 install_element(RIPNG_NODE, &ripng_no_ipv6_distribute_list_cmd);
548
1e42a07c 549 install_element(RIPNG_NODE, &ripng_allow_ecmp_cmd);
54b56562 550 install_element(RIPNG_NODE, &ripng_default_information_originate_cmd);
ad8778c0
RW
551 install_element(RIPNG_NODE, &ripng_default_metric_cmd);
552 install_element(RIPNG_NODE, &no_ripng_default_metric_cmd);
cc48702b
RW
553 install_element(RIPNG_NODE, &ripng_network_prefix_cmd);
554 install_element(RIPNG_NODE, &ripng_network_if_cmd);
b09956ca 555 install_element(RIPNG_NODE, &ripng_offset_list_cmd);
22e8c7ae 556 install_element(RIPNG_NODE, &ripng_passive_interface_cmd);
db2038c7 557 install_element(RIPNG_NODE, &ripng_redistribute_cmd);
521d1b12 558 install_element(RIPNG_NODE, &ripng_route_cmd);
6fc29385 559 install_element(RIPNG_NODE, &ripng_aggregate_address_cmd);
f8981ec5
RW
560 install_element(RIPNG_NODE, &ripng_timers_cmd);
561 install_element(RIPNG_NODE, &no_ripng_timers_cmd);
d406db4c
RW
562
563 install_element(INTERFACE_NODE, &ipv6_ripng_split_horizon_cmd);
49e06d25
RW
564
565 install_element(ENABLE_NODE, &clear_ipv6_rip_cmd);
e9ce224b 566}