2 * Copyright (C) 1998 Kunihiro Ishiguro
3 * Copyright (C) 2018 NetDEF, Inc.
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)
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
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
28 #include "northbound_cli.h"
31 #include "ripngd/ripngd.h"
32 #include "ripngd/ripng_nb.h"
33 #include "ripngd/ripng_cli_clippy.c"
36 * XPath: /frr-ripngd:ripngd/instance
38 DEFPY_YANG_NOSH (router_ripng
,
40 "router ripng [vrf NAME]",
41 "Enable a routing process\n"
42 "Make RIPng instance command\n"
45 char xpath
[XPATH_MAXLEN
];
48 /* Build RIPng instance XPath. */
50 vrf
= VRF_DEFAULT_NAME
;
51 snprintf(xpath
, sizeof(xpath
), "/frr-ripngd:ripngd/instance[vrf='%s']",
54 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
56 ret
= nb_cli_apply_changes(vty
, NULL
);
57 if (ret
== CMD_SUCCESS
)
58 VTY_PUSH_XPATH(RIPNG_NODE
, xpath
);
63 DEFPY_YANG (no_router_ripng
,
65 "no router ripng [vrf NAME]",
67 "Enable a routing process\n"
68 "Make RIPng instance command\n"
71 char xpath
[XPATH_MAXLEN
];
73 /* Build RIPng instance XPath. */
75 vrf
= VRF_DEFAULT_NAME
;
76 snprintf(xpath
, sizeof(xpath
), "/frr-ripngd:ripngd/instance[vrf='%s']",
79 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
81 return nb_cli_apply_changes_clear_pending(vty
, NULL
);
84 void cli_show_router_ripng(struct vty
*vty
, const struct lyd_node
*dnode
,
89 vrf_name
= yang_dnode_get_string(dnode
, "./vrf");
92 vty_out(vty
, "router ripng");
93 if (!strmatch(vrf_name
, VRF_DEFAULT_NAME
))
94 vty_out(vty
, " vrf %s", vrf_name
);
99 * XPath: /frr-ripngd:ripngd/instance/allow-ecmp
101 DEFPY_YANG (ripng_allow_ecmp
,
102 ripng_allow_ecmp_cmd
,
105 "Allow Equal Cost MultiPath\n")
107 nb_cli_enqueue_change(vty
, "./allow-ecmp", NB_OP_MODIFY
,
108 no
? "false" : "true");
110 return nb_cli_apply_changes(vty
, NULL
);
113 void cli_show_ripng_allow_ecmp(struct vty
*vty
, const struct lyd_node
*dnode
,
116 if (!yang_dnode_get_bool(dnode
, NULL
))
119 vty_out(vty
, " allow-ecmp\n");
123 * XPath: /frr-ripngd:ripngd/instance/default-information-originate
125 DEFPY_YANG (ripng_default_information_originate
,
126 ripng_default_information_originate_cmd
,
127 "[no] default-information originate",
129 "Default route information\n"
130 "Distribute default route\n")
132 nb_cli_enqueue_change(vty
, "./default-information-originate",
133 NB_OP_MODIFY
, no
? "false" : "true");
135 return nb_cli_apply_changes(vty
, NULL
);
138 void cli_show_ripng_default_information_originate(struct vty
*vty
,
139 const struct lyd_node
*dnode
,
142 if (!yang_dnode_get_bool(dnode
, NULL
))
145 vty_out(vty
, " default-information originate\n");
149 * XPath: /frr-ripngd:ripngd/instance/default-metric
151 DEFPY_YANG (ripng_default_metric
,
152 ripng_default_metric_cmd
,
153 "default-metric (1-16)",
154 "Set a metric of redistribute routes\n"
157 nb_cli_enqueue_change(vty
, "./default-metric", NB_OP_MODIFY
,
160 return nb_cli_apply_changes(vty
, NULL
);
163 DEFPY_YANG (no_ripng_default_metric
,
164 no_ripng_default_metric_cmd
,
165 "no default-metric [(1-16)]",
167 "Set a metric of redistribute routes\n"
170 nb_cli_enqueue_change(vty
, "./default-metric", NB_OP_MODIFY
, NULL
);
172 return nb_cli_apply_changes(vty
, NULL
);
175 void cli_show_ripng_default_metric(struct vty
*vty
,
176 const struct lyd_node
*dnode
,
179 vty_out(vty
, " default-metric %s\n",
180 yang_dnode_get_string(dnode
, NULL
));
184 * XPath: /frr-ripngd:ripngd/instance/network
186 DEFPY_YANG (ripng_network_prefix
,
187 ripng_network_prefix_cmd
,
188 "[no] network X:X::X:X/M",
190 "RIPng enable on specified interface or network.\n"
193 nb_cli_enqueue_change(vty
, "./network",
194 no
? NB_OP_DESTROY
: NB_OP_CREATE
, network_str
);
196 return nb_cli_apply_changes(vty
, NULL
);
199 void cli_show_ripng_network_prefix(struct vty
*vty
,
200 const struct lyd_node
*dnode
,
203 vty_out(vty
, " network %s\n", yang_dnode_get_string(dnode
, NULL
));
207 * XPath: /frr-ripngd:ripngd/instance/interface
209 DEFPY_YANG (ripng_network_if
,
210 ripng_network_if_cmd
,
213 "RIPng enable on specified interface or network.\n"
216 nb_cli_enqueue_change(vty
, "./interface",
217 no
? NB_OP_DESTROY
: NB_OP_CREATE
, network
);
219 return nb_cli_apply_changes(vty
, NULL
);
222 void cli_show_ripng_network_interface(struct vty
*vty
,
223 const struct lyd_node
*dnode
,
226 vty_out(vty
, " network %s\n", yang_dnode_get_string(dnode
, NULL
));
230 * XPath: /frr-ripngd:ripngd/instance/offset-list
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]",
236 "Modify RIPng metric\n"
238 "For incoming updates\n"
239 "For outgoing updates\n"
241 "Interface to match\n")
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
,
249 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
251 return nb_cli_apply_changes(
252 vty
, "./offset-list[interface='%s'][direction='%s']",
253 ifname
? ifname
: "*", direction
);
256 void cli_show_ripng_offset_list(struct vty
*vty
, const struct lyd_node
*dnode
,
259 const char *interface
;
261 interface
= yang_dnode_get_string(dnode
, "./interface");
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
);
273 * XPath: /frr-ripngd:ripngd/instance/passive-interface
275 DEFPY_YANG (ripng_passive_interface
,
276 ripng_passive_interface_cmd
,
277 "[no] passive-interface IFNAME",
279 "Suppress routing updates on an interface\n"
282 nb_cli_enqueue_change(vty
, "./passive-interface",
283 no
? NB_OP_DESTROY
: NB_OP_CREATE
, ifname
);
285 return nb_cli_apply_changes(vty
, NULL
);
288 void cli_show_ripng_passive_interface(struct vty
*vty
,
289 const struct lyd_node
*dnode
,
292 vty_out(vty
, " passive-interface %s\n",
293 yang_dnode_get_string(dnode
, NULL
));
297 * XPath: /frr-ripngd:ripngd/instance/redistribute
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}]",
304 FRR_REDIST_HELP_STR_RIPNGD
307 "Route map reference\n"
308 "Pointer to route-map entries\n")
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
,
315 nb_cli_enqueue_change(vty
, "./metric",
316 metric_str
? NB_OP_MODIFY
: NB_OP_DESTROY
,
319 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
321 return nb_cli_apply_changes(vty
, "./redistribute[protocol='%s']",
325 void cli_show_ripng_redistribute(struct vty
*vty
, const struct lyd_node
*dnode
,
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"));
340 * XPath: /frr-ripngd:ripngd/instance/static-route
342 DEFPY_YANG (ripng_route
,
344 "[no] route X:X::X:X/M",
346 "Static route setup\n"
347 "Set static RIPng route announcement\n")
349 nb_cli_enqueue_change(vty
, "./static-route",
350 no
? NB_OP_DESTROY
: NB_OP_CREATE
, route_str
);
352 return nb_cli_apply_changes(vty
, NULL
);
355 void cli_show_ripng_route(struct vty
*vty
, const struct lyd_node
*dnode
,
358 vty_out(vty
, " route %s\n", yang_dnode_get_string(dnode
, NULL
));
362 * XPath: /frr-ripngd:ripngd/instance/aggregate-addres
364 DEFPY_YANG (ripng_aggregate_address
,
365 ripng_aggregate_address_cmd
,
366 "[no] aggregate-address X:X::X:X/M",
368 "Set aggregate RIPng route announcement\n"
369 "Aggregate network\n")
371 nb_cli_enqueue_change(vty
, "./aggregate-address",
372 no
? NB_OP_DESTROY
: NB_OP_CREATE
,
373 aggregate_address_str
);
375 return nb_cli_apply_changes(vty
, NULL
);
378 void cli_show_ripng_aggregate_address(struct vty
*vty
,
379 const struct lyd_node
*dnode
,
382 vty_out(vty
, " aggregate-address %s\n",
383 yang_dnode_get_string(dnode
, NULL
));
387 * XPath: /frr-ripngd:ripngd/instance/timers
389 DEFPY_YANG (ripng_timers
,
391 "timers basic (1-65535)$update (1-65535)$timeout (1-65535)$garbage",
392 "RIPng timers setup\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")
398 nb_cli_enqueue_change(vty
, "./update-interval", NB_OP_MODIFY
,
400 nb_cli_enqueue_change(vty
, "./holddown-interval", NB_OP_MODIFY
,
402 nb_cli_enqueue_change(vty
, "./flush-interval", NB_OP_MODIFY
,
405 return nb_cli_apply_changes(vty
, "./timers");
408 DEFPY_YANG (no_ripng_timers
,
410 "no timers basic [(1-65535) (1-65535) (1-65535)]",
412 "RIPng timers setup\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")
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
);
422 return nb_cli_apply_changes(vty
, "./timers");
425 void cli_show_ripng_timers(struct vty
*vty
, const struct lyd_node
*dnode
,
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"));
435 * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon
437 DEFPY_YANG (ipv6_ripng_split_horizon
,
438 ipv6_ripng_split_horizon_cmd
,
439 "[no] ipv6 ripng split-horizon [poisoned-reverse$poisoned_reverse]",
442 "Routing Information Protocol\n"
443 "Perform split horizon\n"
444 "With poisoned-reverse\n")
450 else if (poisoned_reverse
)
451 value
= "poison-reverse";
455 nb_cli_enqueue_change(vty
, "./split-horizon", NB_OP_MODIFY
, value
);
457 return nb_cli_apply_changes(vty
, "./frr-ripngd:ripng");
460 void cli_show_ipv6_ripng_split_horizon(struct vty
*vty
,
461 const struct lyd_node
*dnode
,
466 value
= yang_dnode_get_enum(dnode
, NULL
);
468 case RIPNG_NO_SPLIT_HORIZON
:
469 vty_out(vty
, " no ipv6 ripng split-horizon\n");
471 case RIPNG_SPLIT_HORIZON
:
472 vty_out(vty
, " ipv6 ripng split-horizon\n");
474 case RIPNG_SPLIT_HORIZON_POISONED_REVERSE
:
475 vty_out(vty
, " ipv6 ripng split-horizon poisoned-reverse\n");
481 * XPath: /frr-ripngd:clear-ripng-route
483 DEFPY_YANG (clear_ipv6_rip
,
485 "clear ipv6 ripng [vrf WORD]",
488 "Clear IPv6 RIP database\n"
496 struct yang_data
*yang_vrf
;
498 yang_vrf
= yang_data_new(
499 "/frr-ripngd:clear-ripng-route/input/vrf", vrf
);
500 listnode_add(input
, yang_vrf
);
503 ret
= nb_cli_rpc(vty
, "/frr-ripngd:clear-ripng-route", input
, NULL
);
510 DEFUN (ripng_ipv6_distribute_list
,
511 ripng_ipv6_distribute_list_cmd
,
512 "ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]",
514 "Filter networks in routing updates\n"
517 "Filter incoming routing updates\n"
518 "Filter outgoing routing updates\n"
521 const char *ifname
= NULL
;
522 int prefix
= (argv
[2]->type
== WORD_TKN
) ? 1 : 0;
524 if (argv
[argc
- 1]->type
== VARIABLE_TKN
)
525 ifname
= argv
[argc
- 1]->arg
;
527 return distribute_list_parser(prefix
, false, argv
[3 + prefix
]->text
,
528 argv
[2 + prefix
]->arg
, ifname
);
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]",
536 "Filter networks in routing updates\n"
539 "Filter incoming routing updates\n"
540 "Filter outgoing routing updates\n"
543 const char *ifname
= NULL
;
544 int prefix
= (argv
[3]->type
== WORD_TKN
) ? 1 : 0;
546 if (argv
[argc
- 1]->type
== VARIABLE_TKN
)
547 ifname
= argv
[argc
- 1]->arg
;
549 return distribute_list_no_parser(vty
, prefix
, false,
550 argv
[4 + prefix
]->text
,
551 argv
[3 + prefix
]->arg
, ifname
);
554 void ripng_cli_init(void)
556 install_element(CONFIG_NODE
, &router_ripng_cmd
);
557 install_element(CONFIG_NODE
, &no_router_ripng_cmd
);
559 install_element(RIPNG_NODE
, &ripng_ipv6_distribute_list_cmd
);
560 install_element(RIPNG_NODE
, &ripng_no_ipv6_distribute_list_cmd
);
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
);
576 install_element(INTERFACE_NODE
, &ipv6_ripng_split_horizon_cmd
);
578 install_element(ENABLE_NODE
, &clear_ipv6_rip_cmd
);