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 #ifndef VTYSH_EXTRACT_PL
34 #include "ripngd/ripng_cli_clippy.c"
38 * XPath: /frr-ripngd:ripngd/instance
40 DEFPY_YANG_NOSH (router_ripng
,
42 "router ripng [vrf NAME]",
43 "Enable a routing process\n"
44 "Make RIPng instance command\n"
47 char xpath
[XPATH_MAXLEN
];
50 /* Build RIPng instance XPath. */
52 vrf
= VRF_DEFAULT_NAME
;
53 snprintf(xpath
, sizeof(xpath
), "/frr-ripngd:ripngd/instance[vrf='%s']",
56 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
58 ret
= nb_cli_apply_changes(vty
, NULL
);
59 if (ret
== CMD_SUCCESS
)
60 VTY_PUSH_XPATH(RIPNG_NODE
, xpath
);
65 DEFPY_YANG (no_router_ripng
,
67 "no router ripng [vrf NAME]",
69 "Enable a routing process\n"
70 "Make RIPng instance command\n"
73 char xpath
[XPATH_MAXLEN
];
75 /* Build RIPng instance XPath. */
77 vrf
= VRF_DEFAULT_NAME
;
78 snprintf(xpath
, sizeof(xpath
), "/frr-ripngd:ripngd/instance[vrf='%s']",
81 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
83 return nb_cli_apply_changes_clear_pending(vty
, NULL
);
86 void cli_show_router_ripng(struct vty
*vty
, const struct lyd_node
*dnode
,
91 vrf_name
= yang_dnode_get_string(dnode
, "./vrf");
94 vty_out(vty
, "router ripng");
95 if (!strmatch(vrf_name
, VRF_DEFAULT_NAME
))
96 vty_out(vty
, " vrf %s", vrf_name
);
101 * XPath: /frr-ripngd:ripngd/instance/allow-ecmp
103 DEFPY_YANG (ripng_allow_ecmp
,
104 ripng_allow_ecmp_cmd
,
107 "Allow Equal Cost MultiPath\n")
109 nb_cli_enqueue_change(vty
, "./allow-ecmp", NB_OP_MODIFY
,
110 no
? "false" : "true");
112 return nb_cli_apply_changes(vty
, NULL
);
115 void cli_show_ripng_allow_ecmp(struct vty
*vty
, const struct lyd_node
*dnode
,
118 if (!yang_dnode_get_bool(dnode
, NULL
))
121 vty_out(vty
, " allow-ecmp\n");
125 * XPath: /frr-ripngd:ripngd/instance/default-information-originate
127 DEFPY_YANG (ripng_default_information_originate
,
128 ripng_default_information_originate_cmd
,
129 "[no] default-information originate",
131 "Default route information\n"
132 "Distribute default route\n")
134 nb_cli_enqueue_change(vty
, "./default-information-originate",
135 NB_OP_MODIFY
, no
? "false" : "true");
137 return nb_cli_apply_changes(vty
, NULL
);
140 void cli_show_ripng_default_information_originate(struct vty
*vty
,
141 const struct lyd_node
*dnode
,
144 if (!yang_dnode_get_bool(dnode
, NULL
))
147 vty_out(vty
, " default-information originate\n");
151 * XPath: /frr-ripngd:ripngd/instance/default-metric
153 DEFPY_YANG (ripng_default_metric
,
154 ripng_default_metric_cmd
,
155 "default-metric (1-16)",
156 "Set a metric of redistribute routes\n"
159 nb_cli_enqueue_change(vty
, "./default-metric", NB_OP_MODIFY
,
162 return nb_cli_apply_changes(vty
, NULL
);
165 DEFPY_YANG (no_ripng_default_metric
,
166 no_ripng_default_metric_cmd
,
167 "no default-metric [(1-16)]",
169 "Set a metric of redistribute routes\n"
172 nb_cli_enqueue_change(vty
, "./default-metric", NB_OP_MODIFY
, NULL
);
174 return nb_cli_apply_changes(vty
, NULL
);
177 void cli_show_ripng_default_metric(struct vty
*vty
,
178 const struct lyd_node
*dnode
,
181 vty_out(vty
, " default-metric %s\n",
182 yang_dnode_get_string(dnode
, NULL
));
186 * XPath: /frr-ripngd:ripngd/instance/network
188 DEFPY_YANG (ripng_network_prefix
,
189 ripng_network_prefix_cmd
,
190 "[no] network X:X::X:X/M",
192 "RIPng enable on specified interface or network.\n"
195 nb_cli_enqueue_change(vty
, "./network",
196 no
? NB_OP_DESTROY
: NB_OP_CREATE
, network_str
);
198 return nb_cli_apply_changes(vty
, NULL
);
201 void cli_show_ripng_network_prefix(struct vty
*vty
,
202 const struct lyd_node
*dnode
,
205 vty_out(vty
, " network %s\n", yang_dnode_get_string(dnode
, NULL
));
209 * XPath: /frr-ripngd:ripngd/instance/interface
211 DEFPY_YANG (ripng_network_if
,
212 ripng_network_if_cmd
,
215 "RIPng enable on specified interface or network.\n"
218 nb_cli_enqueue_change(vty
, "./interface",
219 no
? NB_OP_DESTROY
: NB_OP_CREATE
, network
);
221 return nb_cli_apply_changes(vty
, NULL
);
224 void cli_show_ripng_network_interface(struct vty
*vty
,
225 const struct lyd_node
*dnode
,
228 vty_out(vty
, " network %s\n", yang_dnode_get_string(dnode
, NULL
));
232 * XPath: /frr-ripngd:ripngd/instance/offset-list
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]",
238 "Modify RIPng metric\n"
240 "For incoming updates\n"
241 "For outgoing updates\n"
243 "Interface to match\n")
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
,
251 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
253 return nb_cli_apply_changes(
254 vty
, "./offset-list[interface='%s'][direction='%s']",
255 ifname
? ifname
: "*", direction
);
258 void cli_show_ripng_offset_list(struct vty
*vty
, const struct lyd_node
*dnode
,
261 const char *interface
;
263 interface
= yang_dnode_get_string(dnode
, "./interface");
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
);
275 * XPath: /frr-ripngd:ripngd/instance/passive-interface
277 DEFPY_YANG (ripng_passive_interface
,
278 ripng_passive_interface_cmd
,
279 "[no] passive-interface IFNAME",
281 "Suppress routing updates on an interface\n"
284 nb_cli_enqueue_change(vty
, "./passive-interface",
285 no
? NB_OP_DESTROY
: NB_OP_CREATE
, ifname
);
287 return nb_cli_apply_changes(vty
, NULL
);
290 void cli_show_ripng_passive_interface(struct vty
*vty
,
291 const struct lyd_node
*dnode
,
294 vty_out(vty
, " passive-interface %s\n",
295 yang_dnode_get_string(dnode
, NULL
));
299 * XPath: /frr-ripngd:ripngd/instance/redistribute
301 DEFPY_YANG (ripng_redistribute
,
302 ripng_redistribute_cmd
,
303 "[no] redistribute " FRR_REDIST_STR_RIPNGD
"$protocol [{metric (0-16)|route-map WORD}]",
306 FRR_REDIST_HELP_STR_RIPNGD
309 "Route map reference\n"
310 "Pointer to route-map entries\n")
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
,
317 nb_cli_enqueue_change(vty
, "./metric",
318 metric_str
? NB_OP_MODIFY
: NB_OP_DESTROY
,
321 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
323 return nb_cli_apply_changes(vty
, "./redistribute[protocol='%s']",
327 void cli_show_ripng_redistribute(struct vty
*vty
, const struct lyd_node
*dnode
,
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"));
342 * XPath: /frr-ripngd:ripngd/instance/static-route
344 DEFPY_YANG (ripng_route
,
346 "[no] route X:X::X:X/M",
348 "Static route setup\n"
349 "Set static RIPng route announcement\n")
351 nb_cli_enqueue_change(vty
, "./static-route",
352 no
? NB_OP_DESTROY
: NB_OP_CREATE
, route_str
);
354 return nb_cli_apply_changes(vty
, NULL
);
357 void cli_show_ripng_route(struct vty
*vty
, const struct lyd_node
*dnode
,
360 vty_out(vty
, " route %s\n", yang_dnode_get_string(dnode
, NULL
));
364 * XPath: /frr-ripngd:ripngd/instance/aggregate-addres
366 DEFPY_YANG (ripng_aggregate_address
,
367 ripng_aggregate_address_cmd
,
368 "[no] aggregate-address X:X::X:X/M",
370 "Set aggregate RIPng route announcement\n"
371 "Aggregate network\n")
373 nb_cli_enqueue_change(vty
, "./aggregate-address",
374 no
? NB_OP_DESTROY
: NB_OP_CREATE
,
375 aggregate_address_str
);
377 return nb_cli_apply_changes(vty
, NULL
);
380 void cli_show_ripng_aggregate_address(struct vty
*vty
,
381 const struct lyd_node
*dnode
,
384 vty_out(vty
, " aggregate-address %s\n",
385 yang_dnode_get_string(dnode
, NULL
));
389 * XPath: /frr-ripngd:ripngd/instance/timers
391 DEFPY_YANG (ripng_timers
,
393 "timers basic (1-65535)$update (1-65535)$timeout (1-65535)$garbage",
394 "RIPng timers setup\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")
400 nb_cli_enqueue_change(vty
, "./update-interval", NB_OP_MODIFY
,
402 nb_cli_enqueue_change(vty
, "./holddown-interval", NB_OP_MODIFY
,
404 nb_cli_enqueue_change(vty
, "./flush-interval", NB_OP_MODIFY
,
407 return nb_cli_apply_changes(vty
, "./timers");
410 DEFPY_YANG (no_ripng_timers
,
412 "no timers basic [(1-65535) (1-65535) (1-65535)]",
414 "RIPng timers setup\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")
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
);
424 return nb_cli_apply_changes(vty
, "./timers");
427 void cli_show_ripng_timers(struct vty
*vty
, const struct lyd_node
*dnode
,
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"));
437 * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon
439 DEFPY_YANG (ipv6_ripng_split_horizon
,
440 ipv6_ripng_split_horizon_cmd
,
441 "[no] ipv6 ripng split-horizon [poisoned-reverse$poisoned_reverse]",
444 "Routing Information Protocol\n"
445 "Perform split horizon\n"
446 "With poisoned-reverse\n")
452 else if (poisoned_reverse
)
453 value
= "poison-reverse";
457 nb_cli_enqueue_change(vty
, "./split-horizon", NB_OP_MODIFY
, value
);
459 return nb_cli_apply_changes(vty
, "./frr-ripngd:ripng");
462 void cli_show_ipv6_ripng_split_horizon(struct vty
*vty
,
463 const struct lyd_node
*dnode
,
468 value
= yang_dnode_get_enum(dnode
, NULL
);
470 case RIPNG_NO_SPLIT_HORIZON
:
471 vty_out(vty
, " no ipv6 ripng split-horizon\n");
473 case RIPNG_SPLIT_HORIZON
:
474 vty_out(vty
, " ipv6 ripng split-horizon\n");
476 case RIPNG_SPLIT_HORIZON_POISONED_REVERSE
:
477 vty_out(vty
, " ipv6 ripng split-horizon poisoned-reverse\n");
483 * XPath: /frr-ripngd:clear-ripng-route
485 DEFPY_YANG (clear_ipv6_rip
,
487 "clear ipv6 ripng [vrf WORD]",
490 "Clear IPv6 RIP database\n"
498 struct yang_data
*yang_vrf
;
500 yang_vrf
= yang_data_new(
501 "/frr-ripngd:clear-ripng-route/input/vrf", vrf
);
502 listnode_add(input
, yang_vrf
);
505 ret
= nb_cli_rpc(vty
, "/frr-ripngd:clear-ripng-route", input
, NULL
);
512 DEFUN (ripng_ipv6_distribute_list
,
513 ripng_ipv6_distribute_list_cmd
,
514 "ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]",
516 "Filter networks in routing updates\n"
519 "Filter incoming routing updates\n"
520 "Filter outgoing routing updates\n"
523 const char *ifname
= NULL
;
524 int prefix
= (argv
[2]->type
== WORD_TKN
) ? 1 : 0;
526 if (argv
[argc
- 1]->type
== VARIABLE_TKN
)
527 ifname
= argv
[argc
- 1]->arg
;
529 return distribute_list_parser(prefix
, false, argv
[3 + prefix
]->text
,
530 argv
[2 + prefix
]->arg
, ifname
);
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]",
538 "Filter networks in routing updates\n"
541 "Filter incoming routing updates\n"
542 "Filter outgoing routing updates\n"
545 const char *ifname
= NULL
;
546 int prefix
= (argv
[3]->type
== WORD_TKN
) ? 1 : 0;
548 if (argv
[argc
- 1]->type
== VARIABLE_TKN
)
549 ifname
= argv
[argc
- 1]->arg
;
551 return distribute_list_no_parser(vty
, prefix
, false,
552 argv
[4 + prefix
]->text
,
553 argv
[3 + prefix
]->arg
, ifname
);
556 void ripng_cli_init(void)
558 install_element(CONFIG_NODE
, &router_ripng_cmd
);
559 install_element(CONFIG_NODE
, &no_router_ripng_cmd
);
561 install_element(RIPNG_NODE
, &ripng_ipv6_distribute_list_cmd
);
562 install_element(RIPNG_NODE
, &ripng_no_ipv6_distribute_list_cmd
);
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
);
578 install_element(INTERFACE_NODE
, &ipv6_ripng_split_horizon_cmd
);
580 install_element(ENABLE_NODE
, &clear_ipv6_rip_cmd
);