]> git.proxmox.com Git - mirror_frr.git/blame - ripngd/ripng_cli.c
Merge pull request #5278 from slankdev/slankdev-bgpd-fix-prefix-sid-fetch-error
[mirror_frr.git] / ripngd / ripng_cli.c
CommitLineData
e9ce224b
RW
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"
ca473936 32#include "ripngd/ripng_nb.h"
e9ce224b
RW
33#ifndef VTYSH_EXTRACT_PL
34#include "ripngd/ripng_cli_clippy.c"
35#endif
36
9a12e9e5
RW
37/*
38 * XPath: /frr-ripngd:ripngd/instance
39 */
40DEFPY_NOSH (router_ripng,
41 router_ripng_cmd,
dde7b15b 42 "router ripng [vrf NAME]",
9a12e9e5 43 "Enable a routing process\n"
dde7b15b
RW
44 "Make RIPng instance command\n"
45 VRF_CMD_HELP_STR)
9a12e9e5 46{
dde7b15b 47 char xpath[XPATH_MAXLEN];
9a12e9e5
RW
48 int ret;
49
dde7b15b
RW
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);
9a12e9e5
RW
57
58 ret = nb_cli_apply_changes(vty, NULL);
59 if (ret == CMD_SUCCESS)
dde7b15b 60 VTY_PUSH_XPATH(RIPNG_NODE, xpath);
9a12e9e5
RW
61
62 return ret;
63}
64
65DEFPY (no_router_ripng,
66 no_router_ripng_cmd,
dde7b15b 67 "no router ripng [vrf NAME]",
9a12e9e5
RW
68 NO_STR
69 "Enable a routing process\n"
dde7b15b
RW
70 "Make RIPng instance command\n"
71 VRF_CMD_HELP_STR)
9a12e9e5 72{
dde7b15b
RW
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
8f88441d 81 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
9a12e9e5
RW
82
83 return nb_cli_apply_changes(vty, NULL);
84}
85
86void cli_show_router_ripng(struct vty *vty, struct lyd_node *dnode,
87 bool show_defaults)
88{
dde7b15b
RW
89 const char *vrf_name;
90
91 vrf_name = yang_dnode_get_string(dnode, "./vrf");
92
9a12e9e5 93 vty_out(vty, "!\n");
dde7b15b
RW
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");
9a12e9e5
RW
98}
99
1e42a07c
RW
100/*
101 * XPath: /frr-ripngd:ripngd/instance/allow-ecmp
102 */
103DEFPY (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
115void cli_show_ripng_allow_ecmp(struct vty *vty, 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
54b56562
RW
124/*
125 * XPath: /frr-ripngd:ripngd/instance/default-information-originate
126 */
127DEFPY (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
140void cli_show_ripng_default_information_originate(struct vty *vty,
141 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
ad8778c0
RW
150/*
151 * XPath: /frr-ripngd:ripngd/instance/default-metric
152 */
153DEFPY (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
165DEFPY (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
177void cli_show_ripng_default_metric(struct vty *vty, 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
cc48702b
RW
184/*
185 * XPath: /frr-ripngd:ripngd/instance/network
186 */
187DEFPY (ripng_network_prefix,
188 ripng_network_prefix_cmd,
189 "[no] network X:X::X:X/M",
190 NO_STR
191 "RIPng enable on specified interface or network.\n"
192 "IPv6 network\n")
193{
194 nb_cli_enqueue_change(vty, "./network",
95ce849b 195 no ? NB_OP_DESTROY : NB_OP_CREATE, network_str);
cc48702b
RW
196
197 return nb_cli_apply_changes(vty, NULL);
198}
199
200void cli_show_ripng_network_prefix(struct vty *vty, 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 */
209DEFPY (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",
95ce849b 217 no ? NB_OP_DESTROY : NB_OP_CREATE, network);
cc48702b
RW
218
219 return nb_cli_apply_changes(vty, NULL);
220}
221
222void cli_show_ripng_network_interface(struct vty *vty, struct lyd_node *dnode,
223 bool show_defaults)
224{
225 vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL));
226}
227
b09956ca
RW
228/*
229 * XPath: /frr-ripngd:ripngd/instance/offset-list
230 */
231DEFPY (ripng_offset_list,
232 ripng_offset_list_cmd,
233 "[no] offset-list WORD$acl <in|out>$direction (0-16)$metric [IFNAME]",
234 NO_STR
235 "Modify RIPng metric\n"
236 "Access-list name\n"
237 "For incoming updates\n"
238 "For outgoing updates\n"
239 "Metric value\n"
240 "Interface to match\n")
241{
242 if (!no) {
243 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
244 nb_cli_enqueue_change(vty, "./access-list", NB_OP_MODIFY, acl);
245 nb_cli_enqueue_change(vty, "./metric", NB_OP_MODIFY,
246 metric_str);
247 } else
95ce849b 248 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
b09956ca
RW
249
250 return nb_cli_apply_changes(
251 vty, "./offset-list[interface='%s'][direction='%s']",
252 ifname ? ifname : "*", direction);
253}
254
255void cli_show_ripng_offset_list(struct vty *vty, struct lyd_node *dnode,
256 bool show_defaults)
257{
258 const char *interface;
259
260 interface = yang_dnode_get_string(dnode, "./interface");
261
262 vty_out(vty, " offset-list %s %s %s",
263 yang_dnode_get_string(dnode, "./access-list"),
264 yang_dnode_get_string(dnode, "./direction"),
265 yang_dnode_get_string(dnode, "./metric"));
266 if (!strmatch(interface, "*"))
267 vty_out(vty, " %s", interface);
268 vty_out(vty, "\n");
269}
270
22e8c7ae
RW
271/*
272 * XPath: /frr-ripngd:ripngd/instance/passive-interface
273 */
274DEFPY (ripng_passive_interface,
275 ripng_passive_interface_cmd,
276 "[no] passive-interface IFNAME",
277 NO_STR
278 "Suppress routing updates on an interface\n"
279 "Interface name\n")
280{
281 nb_cli_enqueue_change(vty, "./passive-interface",
95ce849b 282 no ? NB_OP_DESTROY : NB_OP_CREATE, ifname);
22e8c7ae
RW
283
284 return nb_cli_apply_changes(vty, NULL);
285}
286
287void cli_show_ripng_passive_interface(struct vty *vty, struct lyd_node *dnode,
288 bool show_defaults)
289{
290 vty_out(vty, " passive-interface %s\n",
291 yang_dnode_get_string(dnode, NULL));
292}
293
db2038c7
RW
294/*
295 * XPath: /frr-ripngd:ripngd/instance/redistribute
296 */
297DEFPY (ripng_redistribute,
298 ripng_redistribute_cmd,
299 "[no] redistribute " FRR_REDIST_STR_RIPNGD "$protocol [{metric (0-16)|route-map WORD}]",
300 NO_STR
301 REDIST_STR
302 FRR_REDIST_HELP_STR_RIPNGD
303 "Metric\n"
304 "Metric value\n"
305 "Route map reference\n"
306 "Pointer to route-map entries\n")
307{
308 if (!no) {
309 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
310 nb_cli_enqueue_change(vty, "./route-map",
95ce849b 311 route_map ? NB_OP_MODIFY : NB_OP_DESTROY,
db2038c7
RW
312 route_map);
313 nb_cli_enqueue_change(vty, "./metric",
95ce849b 314 metric_str ? NB_OP_MODIFY : NB_OP_DESTROY,
db2038c7
RW
315 metric_str);
316 } else
95ce849b 317 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
db2038c7
RW
318
319 return nb_cli_apply_changes(vty, "./redistribute[protocol='%s']",
320 protocol);
321}
322
323void cli_show_ripng_redistribute(struct vty *vty, struct lyd_node *dnode,
324 bool show_defaults)
325{
326 vty_out(vty, " redistribute %s",
327 yang_dnode_get_string(dnode, "./protocol"));
328 if (yang_dnode_exists(dnode, "./metric"))
329 vty_out(vty, " metric %s",
330 yang_dnode_get_string(dnode, "./metric"));
331 if (yang_dnode_exists(dnode, "./route-map"))
332 vty_out(vty, " route-map %s",
333 yang_dnode_get_string(dnode, "./route-map"));
334 vty_out(vty, "\n");
335}
336
521d1b12
RW
337/*
338 * XPath: /frr-ripngd:ripngd/instance/static-route
339 */
340DEFPY (ripng_route,
341 ripng_route_cmd,
342 "[no] route X:X::X:X/M",
343 NO_STR
344 "Static route setup\n"
345 "Set static RIPng route announcement\n")
346{
347 nb_cli_enqueue_change(vty, "./static-route",
95ce849b 348 no ? NB_OP_DESTROY : NB_OP_CREATE, route_str);
521d1b12
RW
349
350 return nb_cli_apply_changes(vty, NULL);
351}
352
353void cli_show_ripng_route(struct vty *vty, struct lyd_node *dnode,
354 bool show_defaults)
355{
356 vty_out(vty, " route %s\n", yang_dnode_get_string(dnode, NULL));
357}
358
6fc29385
RW
359/*
360 * XPath: /frr-ripngd:ripngd/instance/aggregate-addres
361 */
362DEFPY (ripng_aggregate_address,
363 ripng_aggregate_address_cmd,
364 "[no] aggregate-address X:X::X:X/M",
365 NO_STR
366 "Set aggregate RIPng route announcement\n"
367 "Aggregate network\n")
368{
369 nb_cli_enqueue_change(vty, "./aggregate-address",
95ce849b 370 no ? NB_OP_DESTROY : NB_OP_CREATE,
6fc29385
RW
371 aggregate_address_str);
372
373 return nb_cli_apply_changes(vty, NULL);
374}
375
376void cli_show_ripng_aggregate_address(struct vty *vty, struct lyd_node *dnode,
377 bool show_defaults)
378{
379 vty_out(vty, " aggregate-address %s\n",
380 yang_dnode_get_string(dnode, NULL));
381}
382
f8981ec5
RW
383/*
384 * XPath: /frr-ripngd:ripngd/instance/timers
385 */
386DEFPY (ripng_timers,
387 ripng_timers_cmd,
388 "timers basic (1-65535)$update (1-65535)$timeout (1-65535)$garbage",
389 "RIPng timers setup\n"
390 "Basic timer\n"
391 "Routing table update timer value in second. Default is 30.\n"
392 "Routing information timeout timer. Default is 180.\n"
393 "Garbage collection timer. Default is 120.\n")
394{
395 nb_cli_enqueue_change(vty, "./update-interval", NB_OP_MODIFY,
396 update_str);
397 nb_cli_enqueue_change(vty, "./holddown-interval", NB_OP_MODIFY,
398 timeout_str);
399 nb_cli_enqueue_change(vty, "./flush-interval", NB_OP_MODIFY,
400 garbage_str);
401
402 return nb_cli_apply_changes(vty, "./timers");
403}
404
405DEFPY (no_ripng_timers,
406 no_ripng_timers_cmd,
407 "no timers basic [(1-65535) (1-65535) (1-65535)]",
408 NO_STR
409 "RIPng timers setup\n"
410 "Basic timer\n"
411 "Routing table update timer value in second. Default is 30.\n"
412 "Routing information timeout timer. Default is 180.\n"
413 "Garbage collection timer. Default is 120.\n")
414{
415 nb_cli_enqueue_change(vty, "./update-interval", NB_OP_MODIFY, NULL);
416 nb_cli_enqueue_change(vty, "./holddown-interval", NB_OP_MODIFY, NULL);
417 nb_cli_enqueue_change(vty, "./flush-interval", NB_OP_MODIFY, NULL);
418
419 return nb_cli_apply_changes(vty, "./timers");
420}
421
422void cli_show_ripng_timers(struct vty *vty, struct lyd_node *dnode,
423 bool show_defaults)
424{
425 vty_out(vty, " timers basic %s %s %s\n",
426 yang_dnode_get_string(dnode, "./update-interval"),
427 yang_dnode_get_string(dnode, "./holddown-interval"),
428 yang_dnode_get_string(dnode, "./flush-interval"));
429}
430
d406db4c
RW
431/*
432 * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon
433 */
434DEFPY (ipv6_ripng_split_horizon,
435 ipv6_ripng_split_horizon_cmd,
436 "[no] ipv6 ripng split-horizon [poisoned-reverse$poisoned_reverse]",
437 NO_STR
438 IPV6_STR
439 "Routing Information Protocol\n"
440 "Perform split horizon\n"
441 "With poisoned-reverse\n")
442{
443 const char *value;
444
445 if (no)
446 value = "disabled";
447 else if (poisoned_reverse)
448 value = "poison-reverse";
449 else
450 value = "simple";
451
452 nb_cli_enqueue_change(vty, "./split-horizon", NB_OP_MODIFY, value);
453
454 return nb_cli_apply_changes(vty, "./frr-ripngd:ripng");
455}
456
457void cli_show_ipv6_ripng_split_horizon(struct vty *vty, struct lyd_node *dnode,
458 bool show_defaults)
459{
460 int value;
461
462 value = yang_dnode_get_enum(dnode, NULL);
463 switch (value) {
464 case RIPNG_NO_SPLIT_HORIZON:
465 vty_out(vty, " no ipv6 ripng split-horizon\n");
466 break;
467 case RIPNG_SPLIT_HORIZON:
468 vty_out(vty, " ipv6 ripng split-horizon\n");
469 break;
470 case RIPNG_SPLIT_HORIZON_POISONED_REVERSE:
471 vty_out(vty, " ipv6 ripng split-horizon poisoned-reverse\n");
472 break;
473 }
474}
475
49e06d25
RW
476/*
477 * XPath: /frr-ripngd:clear-ripng-route
478 */
479DEFPY (clear_ipv6_rip,
480 clear_ipv6_rip_cmd,
c5b2b5f6 481 "clear ipv6 ripng [vrf WORD]",
49e06d25
RW
482 CLEAR_STR
483 IPV6_STR
c5b2b5f6
RW
484 "Clear IPv6 RIP database\n"
485 VRF_CMD_HELP_STR)
49e06d25 486{
c5b2b5f6
RW
487 struct list *input;
488
489 input = list_new();
490 if (vrf) {
491 struct yang_data *yang_vrf;
492
493 yang_vrf = yang_data_new(
494 "/frr-ripngd:clear-ripng-route/input/vrf", vrf);
495 listnode_add(input, yang_vrf);
496 }
497
498 return nb_cli_rpc("/frr-ripngd:clear-ripng-route", input, NULL);
49e06d25
RW
499}
500
e9ce224b
RW
501void ripng_cli_init(void)
502{
9a12e9e5
RW
503 install_element(CONFIG_NODE, &router_ripng_cmd);
504 install_element(CONFIG_NODE, &no_router_ripng_cmd);
1e42a07c
RW
505
506 install_element(RIPNG_NODE, &ripng_allow_ecmp_cmd);
54b56562 507 install_element(RIPNG_NODE, &ripng_default_information_originate_cmd);
ad8778c0
RW
508 install_element(RIPNG_NODE, &ripng_default_metric_cmd);
509 install_element(RIPNG_NODE, &no_ripng_default_metric_cmd);
cc48702b
RW
510 install_element(RIPNG_NODE, &ripng_network_prefix_cmd);
511 install_element(RIPNG_NODE, &ripng_network_if_cmd);
b09956ca 512 install_element(RIPNG_NODE, &ripng_offset_list_cmd);
22e8c7ae 513 install_element(RIPNG_NODE, &ripng_passive_interface_cmd);
db2038c7 514 install_element(RIPNG_NODE, &ripng_redistribute_cmd);
521d1b12 515 install_element(RIPNG_NODE, &ripng_route_cmd);
6fc29385 516 install_element(RIPNG_NODE, &ripng_aggregate_address_cmd);
f8981ec5
RW
517 install_element(RIPNG_NODE, &ripng_timers_cmd);
518 install_element(RIPNG_NODE, &no_ripng_timers_cmd);
d406db4c
RW
519
520 install_element(INTERFACE_NODE, &ipv6_ripng_split_horizon_cmd);
49e06d25
RW
521
522 install_element(ENABLE_NODE, &clear_ipv6_rip_cmd);
e9ce224b 523}