]> git.proxmox.com Git - mirror_frr.git/blame - ripd/rip_cli.c
lib: convert if_rmap config output to northbound
[mirror_frr.git] / ripd / rip_cli.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
707656ec
RW
2/*
3 * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
4 * Copyright (C) 2018 NetDEF, Inc.
5 * Renato Westphal
707656ec
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 "ripd/ripd.h"
f80ec39e 19#include "ripd/rip_nb.h"
707656ec 20#include "ripd/rip_cli_clippy.c"
707656ec 21
8c9226c2
RW
22/*
23 * XPath: /frr-ripd:ripd/instance
24 */
ca77b518 25DEFPY_YANG_NOSH (router_rip,
8c9226c2 26 router_rip_cmd,
ae7b826a 27 "router rip [vrf NAME]",
8c9226c2 28 "Enable a routing process\n"
ae7b826a
RW
29 "Routing Information Protocol (RIP)\n"
30 VRF_CMD_HELP_STR)
8c9226c2 31{
ae7b826a 32 char xpath[XPATH_MAXLEN];
8c9226c2
RW
33 int ret;
34
ae7b826a
RW
35 /* Build RIP instance XPath. */
36 if (!vrf)
37 vrf = VRF_DEFAULT_NAME;
38 snprintf(xpath, sizeof(xpath), "/frr-ripd:ripd/instance[vrf='%s']",
39 vrf);
40
41 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
a6233bfc
RW
42
43 ret = nb_cli_apply_changes(vty, NULL);
8c9226c2 44 if (ret == CMD_SUCCESS)
ae7b826a 45 VTY_PUSH_XPATH(RIP_NODE, xpath);
8c9226c2
RW
46
47 return ret;
48}
49
ca77b518 50DEFPY_YANG (no_router_rip,
8c9226c2 51 no_router_rip_cmd,
ae7b826a 52 "no router rip [vrf NAME]",
8c9226c2
RW
53 NO_STR
54 "Enable a routing process\n"
ae7b826a
RW
55 "Routing Information Protocol (RIP)\n"
56 VRF_CMD_HELP_STR)
8c9226c2 57{
ae7b826a
RW
58 char xpath[XPATH_MAXLEN];
59
60 /* Build RIP instance XPath. */
61 if (!vrf)
62 vrf = VRF_DEFAULT_NAME;
63 snprintf(xpath, sizeof(xpath), "/frr-ripd:ripd/instance[vrf='%s']",
64 vrf);
65
8f88441d 66 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
a6233bfc 67
fd396924 68 return nb_cli_apply_changes_clear_pending(vty, NULL);
8c9226c2
RW
69}
70
25605051 71void cli_show_router_rip(struct vty *vty, const struct lyd_node *dnode,
8c9226c2
RW
72 bool show_defaults)
73{
ae7b826a
RW
74 const char *vrf_name;
75
76 vrf_name = yang_dnode_get_string(dnode, "./vrf");
77
8c9226c2 78 vty_out(vty, "!\n");
ae7b826a
RW
79 vty_out(vty, "router rip");
80 if (!strmatch(vrf_name, VRF_DEFAULT_NAME))
81 vty_out(vty, " vrf %s", vrf_name);
82 vty_out(vty, "\n");
8c9226c2
RW
83}
84
edbf59d2
RW
85/*
86 * XPath: /frr-ripd:ripd/instance/allow-ecmp
87 */
ca77b518 88DEFPY_YANG (rip_allow_ecmp,
edbf59d2
RW
89 rip_allow_ecmp_cmd,
90 "[no] allow-ecmp",
91 NO_STR
92 "Allow Equal Cost MultiPath\n")
93{
a6233bfc
RW
94 nb_cli_enqueue_change(vty, "./allow-ecmp", NB_OP_MODIFY,
95 no ? "false" : "true");
96
97 return nb_cli_apply_changes(vty, NULL);
edbf59d2
RW
98}
99
25605051 100void cli_show_rip_allow_ecmp(struct vty *vty, const struct lyd_node *dnode,
edbf59d2
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
0b0609ba
RW
109/*
110 * XPath: /frr-ripd:ripd/instance/default-information-originate
111 */
ca77b518 112DEFPY_YANG (rip_default_information_originate,
0b0609ba
RW
113 rip_default_information_originate_cmd,
114 "[no] default-information originate",
115 NO_STR
116 "Control distribution of default route\n"
117 "Distribute a default route\n")
118{
a6233bfc
RW
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);
0b0609ba
RW
123}
124
125void cli_show_rip_default_information_originate(struct vty *vty,
25605051 126 const struct lyd_node *dnode,
0b0609ba
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
282ae30c
RW
135/*
136 * XPath: /frr-ripd:ripd/instance/default-metric
137 */
ca77b518 138DEFPY_YANG (rip_default_metric,
282ae30c
RW
139 rip_default_metric_cmd,
140 "default-metric (1-16)",
141 "Set a metric of redistribute routes\n"
142 "Default metric\n")
143{
a6233bfc
RW
144 nb_cli_enqueue_change(vty, "./default-metric", NB_OP_MODIFY,
145 default_metric_str);
146
147 return nb_cli_apply_changes(vty, NULL);
282ae30c
RW
148}
149
ca77b518 150DEFPY_YANG (no_rip_default_metric,
282ae30c
RW
151 no_rip_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{
a6233bfc
RW
157 nb_cli_enqueue_change(vty, "./default-metric", NB_OP_MODIFY, NULL);
158
159 return nb_cli_apply_changes(vty, NULL);
282ae30c
RW
160}
161
25605051 162void cli_show_rip_default_metric(struct vty *vty, const struct lyd_node *dnode,
282ae30c
RW
163 bool show_defaults)
164{
165 vty_out(vty, " default-metric %s\n",
166 yang_dnode_get_string(dnode, NULL));
167}
168
7f8a9cba
RW
169/*
170 * XPath: /frr-ripd:ripd/instance/distance/default
171 */
ca77b518 172DEFPY_YANG (rip_distance,
7f8a9cba
RW
173 rip_distance_cmd,
174 "distance (1-255)",
175 "Administrative distance\n"
176 "Distance value\n")
177{
a6233bfc
RW
178 nb_cli_enqueue_change(vty, "./distance/default", NB_OP_MODIFY,
179 distance_str);
180
181 return nb_cli_apply_changes(vty, NULL);
7f8a9cba
RW
182}
183
ca77b518 184DEFPY_YANG (no_rip_distance,
7f8a9cba
RW
185 no_rip_distance_cmd,
186 "no distance [(1-255)]",
187 NO_STR
188 "Administrative distance\n"
189 "Distance value\n")
190{
a6233bfc
RW
191 nb_cli_enqueue_change(vty, "./distance/default", NB_OP_MODIFY, NULL);
192
193 return nb_cli_apply_changes(vty, NULL);
7f8a9cba
RW
194}
195
25605051 196void cli_show_rip_distance(struct vty *vty, const struct lyd_node *dnode,
7f8a9cba
RW
197 bool show_defaults)
198{
bb5b9c10
RW
199 if (yang_dnode_is_default(dnode, NULL))
200 vty_out(vty, " no distance\n");
201 else
202 vty_out(vty, " distance %s\n",
203 yang_dnode_get_string(dnode, NULL));
7f8a9cba
RW
204}
205
23b23d8c
RW
206/*
207 * XPath: /frr-ripd:ripd/instance/distance/source
208 */
ca77b518 209DEFPY_YANG (rip_distance_source,
23b23d8c 210 rip_distance_source_cmd,
a6233bfc 211 "[no] distance (1-255) A.B.C.D/M$prefix [WORD$acl]",
23b23d8c
RW
212 NO_STR
213 "Administrative distance\n"
214 "Distance value\n"
215 "IP source prefix\n"
216 "Access list name\n")
217{
a6233bfc
RW
218 if (!no) {
219 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
d682d365
RW
220 nb_cli_enqueue_change(vty, "./distance", NB_OP_MODIFY,
221 distance_str);
a6233bfc 222 nb_cli_enqueue_change(vty, "./access-list",
95ce849b 223 acl ? NB_OP_MODIFY : NB_OP_DESTROY, acl);
a6233bfc 224 } else
95ce849b 225 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
a6233bfc
RW
226
227 return nb_cli_apply_changes(vty, "./distance/source[prefix='%s']",
228 prefix_str);
23b23d8c
RW
229}
230
25605051 231void cli_show_rip_distance_source(struct vty *vty, const struct lyd_node *dnode,
23b23d8c
RW
232 bool show_defaults)
233{
234 vty_out(vty, " distance %s %s",
235 yang_dnode_get_string(dnode, "./distance"),
236 yang_dnode_get_string(dnode, "./prefix"));
237 if (yang_dnode_exists(dnode, "./access-list"))
238 vty_out(vty, " %s",
239 yang_dnode_get_string(dnode, "./access-list"));
240 vty_out(vty, "\n");
241}
242
f0ab22fb
RW
243/*
244 * XPath: /frr-ripd:ripd/instance/explicit-neighbor
245 */
ca77b518 246DEFPY_YANG (rip_neighbor,
f0ab22fb
RW
247 rip_neighbor_cmd,
248 "[no] neighbor A.B.C.D",
249 NO_STR
250 "Specify a neighbor router\n"
251 "Neighbor address\n")
252{
a6233bfc 253 nb_cli_enqueue_change(vty, "./explicit-neighbor",
95ce849b 254 no ? NB_OP_DESTROY : NB_OP_CREATE, neighbor_str);
a6233bfc
RW
255
256 return nb_cli_apply_changes(vty, NULL);
f0ab22fb
RW
257}
258
25605051 259void cli_show_rip_neighbor(struct vty *vty, const struct lyd_node *dnode,
f0ab22fb
RW
260 bool show_defaults)
261{
262 vty_out(vty, " neighbor %s\n", yang_dnode_get_string(dnode, NULL));
263}
264
3d7a1be8
RW
265/*
266 * XPath: /frr-ripd:ripd/instance/network
267 */
ca77b518 268DEFPY_YANG (rip_network_prefix,
3d7a1be8
RW
269 rip_network_prefix_cmd,
270 "[no] network A.B.C.D/M",
271 NO_STR
272 "Enable routing on an IP network\n"
273 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
274{
a6233bfc 275 nb_cli_enqueue_change(vty, "./network",
95ce849b 276 no ? NB_OP_DESTROY : NB_OP_CREATE, network_str);
a6233bfc
RW
277
278 return nb_cli_apply_changes(vty, NULL);
3d7a1be8
RW
279}
280
25605051 281void cli_show_rip_network_prefix(struct vty *vty, const struct lyd_node *dnode,
3d7a1be8
RW
282 bool show_defaults)
283{
284 vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL));
285}
286
287/*
288 * XPath: /frr-ripd:ripd/instance/interface
289 */
ca77b518 290DEFPY_YANG (rip_network_if,
3d7a1be8
RW
291 rip_network_if_cmd,
292 "[no] network WORD",
293 NO_STR
294 "Enable routing on an IP network\n"
295 "Interface name\n")
296{
a6233bfc 297 nb_cli_enqueue_change(vty, "./interface",
95ce849b 298 no ? NB_OP_DESTROY : NB_OP_CREATE, network);
a6233bfc
RW
299
300 return nb_cli_apply_changes(vty, NULL);
3d7a1be8
RW
301}
302
25605051
IR
303void cli_show_rip_network_interface(struct vty *vty,
304 const struct lyd_node *dnode,
3d7a1be8
RW
305 bool show_defaults)
306{
307 vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL));
308}
309
8c942f65
RW
310/*
311 * XPath: /frr-ripd:ripd/instance/offset-list
312 */
ca77b518 313DEFPY_YANG (rip_offset_list,
8c942f65 314 rip_offset_list_cmd,
c60dec36 315 "[no] offset-list ACCESSLIST4_NAME$acl <in|out>$direction (0-16)$metric [IFNAME]",
8c942f65
RW
316 NO_STR
317 "Modify RIP metric\n"
318 "Access-list name\n"
319 "For incoming updates\n"
320 "For outgoing updates\n"
321 "Metric value\n"
322 "Interface to match\n")
323{
a6233bfc
RW
324 if (!no) {
325 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
326 nb_cli_enqueue_change(vty, "./access-list", NB_OP_MODIFY, acl);
327 nb_cli_enqueue_change(vty, "./metric", NB_OP_MODIFY,
328 metric_str);
329 } else
95ce849b 330 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
a6233bfc
RW
331
332 return nb_cli_apply_changes(
333 vty, "./offset-list[interface='%s'][direction='%s']",
334 ifname ? ifname : "*", direction);
8c942f65
RW
335}
336
25605051 337void cli_show_rip_offset_list(struct vty *vty, const struct lyd_node *dnode,
8c942f65
RW
338 bool show_defaults)
339{
340 const char *interface;
341
342 interface = yang_dnode_get_string(dnode, "./interface");
343
344 vty_out(vty, " offset-list %s %s %s",
345 yang_dnode_get_string(dnode, "./access-list"),
346 yang_dnode_get_string(dnode, "./direction"),
347 yang_dnode_get_string(dnode, "./metric"));
348 if (!strmatch(interface, "*"))
349 vty_out(vty, " %s", interface);
350 vty_out(vty, "\n");
351}
352
44f2f852
RW
353/*
354 * XPath: /frr-ripd:ripd/instance/passive-default
355 */
ca77b518 356DEFPY_YANG (rip_passive_default,
44f2f852
RW
357 rip_passive_default_cmd,
358 "[no] passive-interface default",
359 NO_STR
360 "Suppress routing updates on an interface\n"
361 "default for all interfaces\n")
362{
a6233bfc
RW
363 nb_cli_enqueue_change(vty, "./passive-default", NB_OP_MODIFY,
364 no ? "false" : "true");
365
366 return nb_cli_apply_changes(vty, NULL);
44f2f852
RW
367}
368
25605051 369void cli_show_rip_passive_default(struct vty *vty, const struct lyd_node *dnode,
44f2f852
RW
370 bool show_defaults)
371{
372 if (!yang_dnode_get_bool(dnode, NULL))
373 vty_out(vty, " no");
374
375 vty_out(vty, " passive-interface default\n");
376}
377
378/*
379 * XPath: /frr-ripd:ripd/instance/passive-interface
380 * /frr-ripd:ripd/instance/non-passive-interface
381 */
ca77b518 382DEFPY_YANG (rip_passive_interface,
44f2f852
RW
383 rip_passive_interface_cmd,
384 "[no] passive-interface IFNAME",
385 NO_STR
386 "Suppress routing updates on an interface\n"
387 "Interface name\n")
388{
58e39d52
RW
389 bool passive_default =
390 yang_dnode_get_bool(vty->candidate_config->dnode, "%s%s",
391 VTY_CURR_XPATH, "/passive-default");
392
393 if (passive_default) {
394 nb_cli_enqueue_change(vty, "./non-passive-interface",
395 no ? NB_OP_CREATE : NB_OP_DESTROY,
396 ifname);
397 } else {
398 nb_cli_enqueue_change(vty, "./passive-interface",
399 no ? NB_OP_DESTROY : NB_OP_CREATE,
400 ifname);
401 }
a6233bfc
RW
402
403 return nb_cli_apply_changes(vty, NULL);
44f2f852
RW
404}
405
25605051
IR
406void cli_show_rip_passive_interface(struct vty *vty,
407 const struct lyd_node *dnode,
44f2f852
RW
408 bool show_defaults)
409{
410 vty_out(vty, " passive-interface %s\n",
411 yang_dnode_get_string(dnode, NULL));
412}
413
25605051
IR
414void cli_show_rip_non_passive_interface(struct vty *vty,
415 const struct lyd_node *dnode,
44f2f852
RW
416 bool show_defaults)
417{
418 vty_out(vty, " no passive-interface %s\n",
419 yang_dnode_get_string(dnode, NULL));
420}
421
908f0020
RW
422/*
423 * XPath: /frr-ripd:ripd/instance/redistribute
424 */
ca77b518 425DEFPY_YANG (rip_redistribute,
908f0020 426 rip_redistribute_cmd,
70dd370f 427 "[no] redistribute " FRR_REDIST_STR_RIPD "$protocol [{metric (0-16)|route-map RMAP_NAME$route_map}]",
908f0020
RW
428 NO_STR
429 REDIST_STR
430 FRR_REDIST_HELP_STR_RIPD
431 "Metric\n"
432 "Metric value\n"
433 "Route map reference\n"
434 "Pointer to route-map entries\n")
435{
a6233bfc
RW
436 if (!no) {
437 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
438 nb_cli_enqueue_change(vty, "./route-map",
95ce849b 439 route_map ? NB_OP_MODIFY : NB_OP_DESTROY,
a6233bfc
RW
440 route_map);
441 nb_cli_enqueue_change(vty, "./metric",
95ce849b 442 metric_str ? NB_OP_MODIFY : NB_OP_DESTROY,
a6233bfc
RW
443 metric_str);
444 } else
95ce849b 445 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
a6233bfc
RW
446
447 return nb_cli_apply_changes(vty, "./redistribute[protocol='%s']",
448 protocol);
908f0020
RW
449}
450
25605051 451void cli_show_rip_redistribute(struct vty *vty, const struct lyd_node *dnode,
908f0020
RW
452 bool show_defaults)
453{
454 vty_out(vty, " redistribute %s",
455 yang_dnode_get_string(dnode, "./protocol"));
456 if (yang_dnode_exists(dnode, "./metric"))
457 vty_out(vty, " metric %s",
458 yang_dnode_get_string(dnode, "./metric"));
459 if (yang_dnode_exists(dnode, "./route-map"))
460 vty_out(vty, " route-map %s",
461 yang_dnode_get_string(dnode, "./route-map"));
462 vty_out(vty, "\n");
463}
464
40687878
RW
465/*
466 * XPath: /frr-ripd:ripd/instance/static-route
467 */
ca77b518 468DEFPY_YANG (rip_route,
40687878
RW
469 rip_route_cmd,
470 "[no] route A.B.C.D/M",
471 NO_STR
472 "RIP static route configuration\n"
473 "IP prefix <network>/<length>\n")
474{
a6233bfc 475 nb_cli_enqueue_change(vty, "./static-route",
95ce849b 476 no ? NB_OP_DESTROY : NB_OP_CREATE, route_str);
a6233bfc
RW
477
478 return nb_cli_apply_changes(vty, NULL);
40687878
RW
479}
480
25605051 481void cli_show_rip_route(struct vty *vty, const struct lyd_node *dnode,
40687878
RW
482 bool show_defaults)
483{
484 vty_out(vty, " route %s\n", yang_dnode_get_string(dnode, NULL));
485}
486
b745780b
RW
487/*
488 * XPath: /frr-ripd:ripd/instance/timers
489 */
ca77b518 490DEFPY_YANG (rip_timers,
b745780b
RW
491 rip_timers_cmd,
492 "timers basic (5-2147483647)$update (5-2147483647)$timeout (5-2147483647)$garbage",
493 "Adjust routing timers\n"
494 "Basic routing protocol update timers\n"
495 "Routing table update timer value in second. Default is 30.\n"
496 "Routing information timeout timer. Default is 180.\n"
497 "Garbage collection timer. Default is 120.\n")
498{
a6233bfc
RW
499 nb_cli_enqueue_change(vty, "./update-interval", NB_OP_MODIFY,
500 update_str);
501 nb_cli_enqueue_change(vty, "./holddown-interval", NB_OP_MODIFY,
502 timeout_str);
503 nb_cli_enqueue_change(vty, "./flush-interval", NB_OP_MODIFY,
504 garbage_str);
505
506 return nb_cli_apply_changes(vty, "./timers");
b745780b
RW
507}
508
ca77b518 509DEFPY_YANG (no_rip_timers,
b745780b
RW
510 no_rip_timers_cmd,
511 "no timers basic [(5-2147483647) (5-2147483647) (5-2147483647)]",
512 NO_STR
513 "Adjust routing timers\n"
514 "Basic routing protocol update timers\n"
515 "Routing table update timer value in second. Default is 30.\n"
516 "Routing information timeout timer. Default is 180.\n"
517 "Garbage collection timer. Default is 120.\n")
518{
a6233bfc
RW
519 nb_cli_enqueue_change(vty, "./update-interval", NB_OP_MODIFY, NULL);
520 nb_cli_enqueue_change(vty, "./holddown-interval", NB_OP_MODIFY, NULL);
521 nb_cli_enqueue_change(vty, "./flush-interval", NB_OP_MODIFY, NULL);
522
523 return nb_cli_apply_changes(vty, "./timers");
b745780b
RW
524}
525
25605051 526void cli_show_rip_timers(struct vty *vty, const struct lyd_node *dnode,
b745780b
RW
527 bool show_defaults)
528{
529 vty_out(vty, " timers basic %s %s %s\n",
530 yang_dnode_get_string(dnode, "./update-interval"),
531 yang_dnode_get_string(dnode, "./holddown-interval"),
532 yang_dnode_get_string(dnode, "./flush-interval"));
533}
534
90eff9da
RW
535/*
536 * XPath: /frr-ripd:ripd/instance/version
537 */
ca77b518 538DEFPY_YANG (rip_version,
90eff9da
RW
539 rip_version_cmd,
540 "version (1-2)",
541 "Set routing protocol version\n"
542 "version\n")
543{
a6233bfc
RW
544 nb_cli_enqueue_change(vty, "./version/receive", NB_OP_MODIFY,
545 version_str);
546 nb_cli_enqueue_change(vty, "./version/send", NB_OP_MODIFY, version_str);
547
548 return nb_cli_apply_changes(vty, NULL);
90eff9da
RW
549}
550
ca77b518 551DEFPY_YANG (no_rip_version,
90eff9da
RW
552 no_rip_version_cmd,
553 "no version [(1-2)]",
554 NO_STR
555 "Set routing protocol version\n"
556 "version\n")
557{
a6233bfc
RW
558 nb_cli_enqueue_change(vty, "./version/receive", NB_OP_MODIFY, NULL);
559 nb_cli_enqueue_change(vty, "./version/send", NB_OP_MODIFY, NULL);
560
561 return nb_cli_apply_changes(vty, NULL);
90eff9da
RW
562}
563
25605051 564void cli_show_rip_version(struct vty *vty, const struct lyd_node *dnode,
90eff9da
RW
565 bool show_defaults)
566{
567 /*
568 * We have only one "version" command and three possible combinations of
569 * send/receive values.
570 */
571 switch (yang_dnode_get_enum(dnode, "./receive")) {
572 case RI_RIP_VERSION_1:
573 vty_out(vty, " version 1\n");
574 break;
575 case RI_RIP_VERSION_2:
576 vty_out(vty, " version 2\n");
577 break;
578 case RI_RIP_VERSION_1_AND_2:
579 vty_out(vty, " no version\n");
580 break;
581 }
582}
583
94b117b2
RW
584/*
585 * XPath: /frr-interface:lib/interface/frr-ripd:rip/split-horizon
586 */
ca77b518 587DEFPY_YANG (ip_rip_split_horizon,
94b117b2
RW
588 ip_rip_split_horizon_cmd,
589 "[no] ip rip split-horizon [poisoned-reverse$poisoned_reverse]",
590 NO_STR
591 IP_STR
592 "Routing Information Protocol\n"
593 "Perform split horizon\n"
594 "With poisoned-reverse\n")
595{
a6233bfc 596 const char *value;
94b117b2
RW
597
598 if (no)
a6233bfc 599 value = "disabled";
94b117b2 600 else if (poisoned_reverse)
a6233bfc 601 value = "poison-reverse";
94b117b2 602 else
a6233bfc
RW
603 value = "simple";
604
605 nb_cli_enqueue_change(vty, "./split-horizon", NB_OP_MODIFY, value);
94b117b2 606
a6233bfc 607 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
608}
609
25605051
IR
610void cli_show_ip_rip_split_horizon(struct vty *vty,
611 const struct lyd_node *dnode,
94b117b2
RW
612 bool show_defaults)
613{
614 int value;
615
616 value = yang_dnode_get_enum(dnode, NULL);
617 switch (value) {
618 case RIP_NO_SPLIT_HORIZON:
619 vty_out(vty, " no ip rip split-horizon\n");
620 break;
621 case RIP_SPLIT_HORIZON:
622 vty_out(vty, " ip rip split-horizon\n");
623 break;
624 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
625 vty_out(vty, " ip rip split-horizon poisoned-reverse\n");
626 break;
627 }
628}
629
630/*
631 * XPath: /frr-interface:lib/interface/frr-ripd:rip/v2-broadcast
632 */
ca77b518 633DEFPY_YANG (ip_rip_v2_broadcast,
94b117b2
RW
634 ip_rip_v2_broadcast_cmd,
635 "[no] ip rip v2-broadcast",
636 NO_STR
637 IP_STR
638 "Routing Information Protocol\n"
639 "Send ip broadcast v2 update\n")
640{
a6233bfc
RW
641 nb_cli_enqueue_change(vty, "./v2-broadcast", NB_OP_MODIFY,
642 no ? "false" : "true");
643
644 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
645}
646
25605051 647void cli_show_ip_rip_v2_broadcast(struct vty *vty, const struct lyd_node *dnode,
94b117b2
RW
648 bool show_defaults)
649{
650 if (!yang_dnode_get_bool(dnode, NULL))
651 vty_out(vty, " no");
652
653 vty_out(vty, " ip rip v2-broadcast\n");
654}
655
656/*
657 * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-receive
658 */
ca77b518 659DEFPY_YANG (ip_rip_receive_version,
94b117b2
RW
660 ip_rip_receive_version_cmd,
661 "ip rip receive version <{1$v1|2$v2}|none>",
662 IP_STR
663 "Routing Information Protocol\n"
664 "Advertisement reception\n"
665 "Version control\n"
666 "RIP version 1\n"
667 "RIP version 2\n"
668 "None\n")
669{
a6233bfc 670 const char *value;
94b117b2
RW
671
672 if (v1 && v2)
a6233bfc 673 value = "both";
94b117b2 674 else if (v1)
a6233bfc 675 value = "1";
94b117b2 676 else if (v2)
a6233bfc 677 value = "2";
94b117b2 678 else
a6233bfc
RW
679 value = "none";
680
681 nb_cli_enqueue_change(vty, "./version-receive", NB_OP_MODIFY, value);
94b117b2 682
a6233bfc 683 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
684}
685
ca77b518 686DEFPY_YANG (no_ip_rip_receive_version,
94b117b2
RW
687 no_ip_rip_receive_version_cmd,
688 "no ip rip receive version [<{1|2}|none>]",
689 NO_STR
690 IP_STR
691 "Routing Information Protocol\n"
692 "Advertisement reception\n"
693 "Version control\n"
694 "RIP version 1\n"
695 "RIP version 2\n"
696 "None\n")
697{
a6233bfc
RW
698 nb_cli_enqueue_change(vty, "./version-receive", NB_OP_MODIFY, NULL);
699
700 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
701}
702
25605051
IR
703void cli_show_ip_rip_receive_version(struct vty *vty,
704 const struct lyd_node *dnode,
94b117b2
RW
705 bool show_defaults)
706{
707 switch (yang_dnode_get_enum(dnode, NULL)) {
708 case RI_RIP_UNSPEC:
709 vty_out(vty, " no ip rip receive version\n");
710 break;
711 case RI_RIP_VERSION_1:
712 vty_out(vty, " ip rip receive version 1\n");
713 break;
714 case RI_RIP_VERSION_2:
715 vty_out(vty, " ip rip receive version 2\n");
716 break;
717 case RI_RIP_VERSION_1_AND_2:
718 vty_out(vty, " ip rip receive version 1 2\n");
719 break;
720 case RI_RIP_VERSION_NONE:
721 vty_out(vty, " ip rip receive version none\n");
722 break;
723 }
724}
725
726/*
727 * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-send
728 */
ca77b518 729DEFPY_YANG (ip_rip_send_version,
94b117b2
RW
730 ip_rip_send_version_cmd,
731 "ip rip send version <{1$v1|2$v2}|none>",
732 IP_STR
733 "Routing Information Protocol\n"
734 "Advertisement transmission\n"
735 "Version control\n"
736 "RIP version 1\n"
737 "RIP version 2\n"
738 "None\n")
739{
a6233bfc 740 const char *value;
94b117b2
RW
741
742 if (v1 && v2)
a6233bfc 743 value = "both";
94b117b2 744 else if (v1)
a6233bfc 745 value = "1";
94b117b2 746 else if (v2)
a6233bfc 747 value = "2";
94b117b2 748 else
a6233bfc
RW
749 value = "none";
750
751 nb_cli_enqueue_change(vty, "./version-send", NB_OP_MODIFY, value);
94b117b2 752
a6233bfc 753 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
754}
755
ca77b518 756DEFPY_YANG (no_ip_rip_send_version,
94b117b2
RW
757 no_ip_rip_send_version_cmd,
758 "no ip rip send version [<{1|2}|none>]",
759 NO_STR
760 IP_STR
761 "Routing Information Protocol\n"
762 "Advertisement transmission\n"
763 "Version control\n"
764 "RIP version 1\n"
765 "RIP version 2\n"
766 "None\n")
767{
a6233bfc
RW
768 nb_cli_enqueue_change(vty, "./version-send", NB_OP_MODIFY, NULL);
769
770 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
771}
772
25605051 773void cli_show_ip_rip_send_version(struct vty *vty, const struct lyd_node *dnode,
94b117b2
RW
774 bool show_defaults)
775{
776 switch (yang_dnode_get_enum(dnode, NULL)) {
777 case RI_RIP_UNSPEC:
778 vty_out(vty, " no ip rip send version\n");
779 break;
780 case RI_RIP_VERSION_1:
781 vty_out(vty, " ip rip send version 1\n");
782 break;
783 case RI_RIP_VERSION_2:
784 vty_out(vty, " ip rip send version 2\n");
785 break;
786 case RI_RIP_VERSION_1_AND_2:
787 vty_out(vty, " ip rip send version 1 2\n");
788 break;
789 case RI_RIP_VERSION_NONE:
790 vty_out(vty, " ip rip send version none\n");
791 break;
792 }
793}
794
795/*
796 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme
797 */
ca77b518 798DEFPY_YANG (ip_rip_authentication_mode,
94b117b2
RW
799 ip_rip_authentication_mode_cmd,
800 "ip rip authentication mode <md5$mode [auth-length <rfc|old-ripd>$auth_length]|text$mode>",
801 IP_STR
802 "Routing Information Protocol\n"
803 "Authentication control\n"
804 "Authentication mode\n"
805 "Keyed message digest\n"
806 "MD5 authentication data length\n"
807 "RFC compatible\n"
808 "Old ripd compatible\n"
809 "Clear text authentication\n")
810{
a6233bfc 811 const char *value = NULL;
94b117b2
RW
812
813 if (auth_length) {
814 if (strmatch(auth_length, "rfc"))
a6233bfc 815 value = "16";
94b117b2 816 else
a6233bfc 817 value = "20";
94b117b2
RW
818 }
819
a6233bfc
RW
820 nb_cli_enqueue_change(vty, "./authentication-scheme/mode", NB_OP_MODIFY,
821 strmatch(mode, "md5") ? "md5" : "plain-text");
94b7ff46
RW
822 if (strmatch(mode, "md5"))
823 nb_cli_enqueue_change(vty,
824 "./authentication-scheme/md5-auth-length",
825 NB_OP_MODIFY, value);
a6233bfc
RW
826
827 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
828}
829
ca77b518 830DEFPY_YANG (no_ip_rip_authentication_mode,
94b117b2
RW
831 no_ip_rip_authentication_mode_cmd,
832 "no ip rip authentication mode [<md5 [auth-length <rfc|old-ripd>]|text>]",
833 NO_STR
834 IP_STR
835 "Routing Information Protocol\n"
836 "Authentication control\n"
837 "Authentication mode\n"
838 "Keyed message digest\n"
839 "MD5 authentication data length\n"
840 "RFC compatible\n"
841 "Old ripd compatible\n"
842 "Clear text authentication\n")
843{
a6233bfc
RW
844 nb_cli_enqueue_change(vty, "./authentication-scheme/mode", NB_OP_MODIFY,
845 NULL);
846 nb_cli_enqueue_change(vty, "./authentication-scheme/md5-auth-length",
94b7ff46 847 NB_OP_DESTROY, NULL);
a6233bfc
RW
848
849 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
850}
851
852void cli_show_ip_rip_authentication_scheme(struct vty *vty,
25605051 853 const struct lyd_node *dnode,
94b117b2
RW
854 bool show_defaults)
855{
856 switch (yang_dnode_get_enum(dnode, "./mode")) {
857 case RIP_NO_AUTH:
858 vty_out(vty, " no ip rip authentication mode\n");
859 break;
860 case RIP_AUTH_SIMPLE_PASSWORD:
861 vty_out(vty, " ip rip authentication mode text\n");
862 break;
863 case RIP_AUTH_MD5:
864 vty_out(vty, " ip rip authentication mode md5");
865 if (show_defaults
866 || !yang_dnode_is_default(dnode, "./md5-auth-length")) {
867 if (yang_dnode_get_enum(dnode, "./md5-auth-length")
868 == RIP_AUTH_MD5_SIZE)
869 vty_out(vty, " auth-length rfc");
870 else
871 vty_out(vty, " auth-length old-ripd");
872 }
873 vty_out(vty, "\n");
874 break;
875 }
876}
877
878/*
879 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-password
880 */
ca77b518 881DEFPY_YANG (ip_rip_authentication_string,
94b117b2
RW
882 ip_rip_authentication_string_cmd,
883 "ip rip authentication string LINE$password",
884 IP_STR
885 "Routing Information Protocol\n"
886 "Authentication control\n"
887 "Authentication string\n"
888 "Authentication string\n")
889{
94b117b2
RW
890 if (strlen(password) > 16) {
891 vty_out(vty,
892 "%% RIPv2 authentication string must be shorter than 16\n");
893 return CMD_WARNING_CONFIG_FAILED;
894 }
895
3bb513c3
CH
896 if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
897 VTY_CURR_XPATH,
898 "/frr-ripd:rip/authentication-key-chain")) {
94b117b2
RW
899 vty_out(vty, "%% key-chain configuration exists\n");
900 return CMD_WARNING_CONFIG_FAILED;
901 }
902
a6233bfc
RW
903 nb_cli_enqueue_change(vty, "./authentication-password", NB_OP_MODIFY,
904 password);
905
906 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
907}
908
ca77b518 909DEFPY_YANG (no_ip_rip_authentication_string,
94b117b2
RW
910 no_ip_rip_authentication_string_cmd,
911 "no ip rip authentication string [LINE]",
912 NO_STR
913 IP_STR
914 "Routing Information Protocol\n"
915 "Authentication control\n"
916 "Authentication string\n"
917 "Authentication string\n")
918{
8f88441d 919 nb_cli_enqueue_change(vty, "./authentication-password", NB_OP_DESTROY,
a6233bfc
RW
920 NULL);
921
922 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
923}
924
925void cli_show_ip_rip_authentication_string(struct vty *vty,
25605051 926 const struct lyd_node *dnode,
94b117b2
RW
927 bool show_defaults)
928{
929 vty_out(vty, " ip rip authentication string %s\n",
930 yang_dnode_get_string(dnode, NULL));
931}
932
933/*
934 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain
935 */
ca77b518 936DEFPY_YANG (ip_rip_authentication_key_chain,
94b117b2
RW
937 ip_rip_authentication_key_chain_cmd,
938 "ip rip authentication key-chain LINE$keychain",
939 IP_STR
940 "Routing Information Protocol\n"
941 "Authentication control\n"
942 "Authentication key-chain\n"
943 "name of key-chain\n")
944{
3bb513c3
CH
945 if (yang_dnode_existsf(vty->candidate_config->dnode, "%s%s",
946 VTY_CURR_XPATH,
947 "/frr-ripd:rip/authentication-password")) {
94b117b2
RW
948 vty_out(vty, "%% authentication string configuration exists\n");
949 return CMD_WARNING_CONFIG_FAILED;
950 }
951
a6233bfc
RW
952 nb_cli_enqueue_change(vty, "./authentication-key-chain", NB_OP_MODIFY,
953 keychain);
954
955 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
956}
957
ca77b518 958DEFPY_YANG (no_ip_rip_authentication_key_chain,
94b117b2
RW
959 no_ip_rip_authentication_key_chain_cmd,
960 "no ip rip authentication key-chain [LINE]",
961 NO_STR
962 IP_STR
963 "Routing Information Protocol\n"
964 "Authentication control\n"
965 "Authentication key-chain\n"
966 "name of key-chain\n")
967{
95ce849b 968 nb_cli_enqueue_change(vty, "./authentication-key-chain", NB_OP_DESTROY,
a6233bfc
RW
969 NULL);
970
971 return nb_cli_apply_changes(vty, "./frr-ripd:rip");
94b117b2
RW
972}
973
974void cli_show_ip_rip_authentication_key_chain(struct vty *vty,
25605051 975 const struct lyd_node *dnode,
94b117b2
RW
976 bool show_defaults)
977{
978 vty_out(vty, " ip rip authentication key-chain %s\n",
979 yang_dnode_get_string(dnode, NULL));
980}
981
1137aef4
RW
982/*
983 * XPath: /frr-ripd:clear-rip-route
984 */
ca77b518 985DEFPY_YANG (clear_ip_rip,
1137aef4 986 clear_ip_rip_cmd,
14f17e63 987 "clear ip rip [vrf WORD]",
1137aef4
RW
988 CLEAR_STR
989 IP_STR
14f17e63
RW
990 "Clear IP RIP database\n"
991 VRF_CMD_HELP_STR)
1137aef4 992{
14f17e63 993 struct list *input;
0783b36d 994 int ret;
14f17e63
RW
995
996 input = list_new();
997 if (vrf) {
998 struct yang_data *yang_vrf;
999
1000 yang_vrf = yang_data_new("/frr-ripd:clear-rip-route/input/vrf",
1001 vrf);
1002 listnode_add(input, yang_vrf);
1003 }
1004
f63f5f19 1005 ret = nb_cli_rpc(vty, "/frr-ripd:clear-rip-route", input, NULL);
0783b36d
DS
1006
1007 list_delete(&input);
1008
1009 return ret;
1137aef4
RW
1010}
1011
458133db
DS
1012DEFUN (rip_distribute_list,
1013 rip_distribute_list_cmd,
c60dec36 1014 "distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]",
458133db
DS
1015 "Filter networks in routing updates\n"
1016 "Specify a prefix\n"
1017 "Access-list name\n"
1018 "Filter incoming routing updates\n"
1019 "Filter outgoing routing updates\n"
1020 "Interface name\n")
1021{
1022 const char *ifname = NULL;
1023 int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0;
1024
1025 if (argv[argc - 1]->type == VARIABLE_TKN)
1026 ifname = argv[argc - 1]->arg;
1027
1028 return distribute_list_parser(prefix, true, argv[2 + prefix]->text,
1029 argv[1 + prefix]->arg, ifname);
1030}
1031
1032DEFUN (rip_no_distribute_list,
1033 rip_no_distribute_list_cmd,
c60dec36 1034 "no distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]",
458133db
DS
1035 NO_STR
1036 "Filter networks in routing updates\n"
1037 "Specify a prefix\n"
1038 "Access-list name\n"
1039 "Filter incoming routing updates\n"
1040 "Filter outgoing routing updates\n"
1041 "Interface name\n")
1042{
1043 const char *ifname = NULL;
1044 int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
1045
1046 if (argv[argc - 1]->type == VARIABLE_TKN)
1047 ifname = argv[argc - 1]->arg;
1048
1049 return distribute_list_no_parser(vty, prefix, true,
1050 argv[3 + prefix]->text,
1051 argv[2 + prefix]->arg, ifname);
1052}
1053
707656ec
RW
1054void rip_cli_init(void)
1055{
8c9226c2
RW
1056 install_element(CONFIG_NODE, &router_rip_cmd);
1057 install_element(CONFIG_NODE, &no_router_rip_cmd);
edbf59d2 1058
458133db
DS
1059 install_element(RIP_NODE, &rip_distribute_list_cmd);
1060 install_element(RIP_NODE, &rip_no_distribute_list_cmd);
1061
edbf59d2 1062 install_element(RIP_NODE, &rip_allow_ecmp_cmd);
0b0609ba 1063 install_element(RIP_NODE, &rip_default_information_originate_cmd);
282ae30c
RW
1064 install_element(RIP_NODE, &rip_default_metric_cmd);
1065 install_element(RIP_NODE, &no_rip_default_metric_cmd);
7f8a9cba
RW
1066 install_element(RIP_NODE, &rip_distance_cmd);
1067 install_element(RIP_NODE, &no_rip_distance_cmd);
23b23d8c 1068 install_element(RIP_NODE, &rip_distance_source_cmd);
f0ab22fb 1069 install_element(RIP_NODE, &rip_neighbor_cmd);
3d7a1be8
RW
1070 install_element(RIP_NODE, &rip_network_prefix_cmd);
1071 install_element(RIP_NODE, &rip_network_if_cmd);
8c942f65 1072 install_element(RIP_NODE, &rip_offset_list_cmd);
44f2f852
RW
1073 install_element(RIP_NODE, &rip_passive_default_cmd);
1074 install_element(RIP_NODE, &rip_passive_interface_cmd);
908f0020 1075 install_element(RIP_NODE, &rip_redistribute_cmd);
40687878 1076 install_element(RIP_NODE, &rip_route_cmd);
b745780b
RW
1077 install_element(RIP_NODE, &rip_timers_cmd);
1078 install_element(RIP_NODE, &no_rip_timers_cmd);
90eff9da
RW
1079 install_element(RIP_NODE, &rip_version_cmd);
1080 install_element(RIP_NODE, &no_rip_version_cmd);
94b117b2
RW
1081
1082 install_element(INTERFACE_NODE, &ip_rip_split_horizon_cmd);
1083 install_element(INTERFACE_NODE, &ip_rip_v2_broadcast_cmd);
1084 install_element(INTERFACE_NODE, &ip_rip_receive_version_cmd);
1085 install_element(INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
1086 install_element(INTERFACE_NODE, &ip_rip_send_version_cmd);
1087 install_element(INTERFACE_NODE, &no_ip_rip_send_version_cmd);
1088 install_element(INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
1089 install_element(INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
1090 install_element(INTERFACE_NODE, &ip_rip_authentication_string_cmd);
1091 install_element(INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
1092 install_element(INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
1093 install_element(INTERFACE_NODE,
1094 &no_ip_rip_authentication_key_chain_cmd);
1095
1137aef4 1096 install_element(ENABLE_NODE, &clear_ip_rip_cmd);
707656ec 1097}