]> git.proxmox.com Git - mirror_frr.git/blame - ripd/rip_northbound.c
Merge pull request #3311 from dslicenc/static-int-up
[mirror_frr.git] / ripd / rip_northbound.c
CommitLineData
707656ec
RW
1/*
2 * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
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 "table.h"
28#include "command.h"
908f0020 29#include "routemap.h"
707656ec
RW
30#include "northbound.h"
31#include "libfrr.h"
32
33#include "ripd/ripd.h"
34#include "ripd/rip_cli.h"
35
36/*
37 * XPath: /frr-ripd:ripd/instance
38 */
39static int ripd_instance_create(enum nb_event event,
40 const struct lyd_node *dnode,
41 union nb_resource *resource)
42{
8c9226c2
RW
43 int socket;
44
45 switch (event) {
46 case NB_EV_VALIDATE:
47 break;
48 case NB_EV_PREPARE:
49 socket = rip_create_socket();
50 if (socket < 0)
51 return NB_ERR_RESOURCE;
52 resource->fd = socket;
53 break;
54 case NB_EV_ABORT:
55 socket = resource->fd;
56 close(socket);
57 break;
58 case NB_EV_APPLY:
59 socket = resource->fd;
60 rip_create(socket);
61 break;
62 }
63
707656ec
RW
64 return NB_OK;
65}
66
67static int ripd_instance_delete(enum nb_event event,
68 const struct lyd_node *dnode)
69{
8c9226c2
RW
70 if (event != NB_EV_APPLY)
71 return NB_OK;
72
73 rip_clean();
74
707656ec
RW
75 return NB_OK;
76}
77
78/*
79 * XPath: /frr-ripd:ripd/instance/allow-ecmp
80 */
81static int ripd_instance_allow_ecmp_modify(enum nb_event event,
82 const struct lyd_node *dnode,
83 union nb_resource *resource)
84{
edbf59d2
RW
85 if (event != NB_EV_APPLY)
86 return NB_OK;
87
88 rip->ecmp = yang_dnode_get_bool(dnode, NULL);
89 if (!rip->ecmp)
90 rip_ecmp_disable();
91
707656ec
RW
92 return NB_OK;
93}
94
95/*
96 * XPath: /frr-ripd:ripd/instance/default-information-originate
97 */
98static int
99ripd_instance_default_information_originate_modify(enum nb_event event,
100 const struct lyd_node *dnode,
101 union nb_resource *resource)
102{
0b0609ba
RW
103 bool default_information;
104 struct prefix_ipv4 p;
105
106 if (event != NB_EV_APPLY)
107 return NB_OK;
108
109 default_information = yang_dnode_get_bool(dnode, NULL);
110
111 memset(&p, 0, sizeof(struct prefix_ipv4));
112 p.family = AF_INET;
113 if (default_information) {
114 struct nexthop nh;
115
116 memset(&nh, 0, sizeof(nh));
117 nh.type = NEXTHOP_TYPE_IPV4;
118 rip_redistribute_add(ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p,
119 &nh, 0, 0, 0);
120 } else {
121 rip_redistribute_delete(ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p,
122 0);
123 }
124
707656ec
RW
125 return NB_OK;
126}
127
128/*
129 * XPath: /frr-ripd:ripd/instance/default-metric
130 */
131static int ripd_instance_default_metric_modify(enum nb_event event,
132 const struct lyd_node *dnode,
133 union nb_resource *resource)
134{
282ae30c
RW
135 if (event != NB_EV_APPLY)
136 return NB_OK;
137
138 rip->default_metric = yang_dnode_get_uint8(dnode, NULL);
139 /* rip_update_default_metric (); */
140
707656ec
RW
141 return NB_OK;
142}
143
144/*
145 * XPath: /frr-ripd:ripd/instance/distance/default
146 */
147static int ripd_instance_distance_default_modify(enum nb_event event,
148 const struct lyd_node *dnode,
149 union nb_resource *resource)
150{
7f8a9cba
RW
151 if (event != NB_EV_APPLY)
152 return NB_OK;
153
154 rip->distance = yang_dnode_get_uint8(dnode, NULL);
155
707656ec
RW
156 return NB_OK;
157}
158
159/*
160 * XPath: /frr-ripd:ripd/instance/distance/source
161 */
162static int ripd_instance_distance_source_create(enum nb_event event,
163 const struct lyd_node *dnode,
164 union nb_resource *resource)
165{
23b23d8c
RW
166 struct prefix_ipv4 prefix;
167 struct route_node *rn;
168
169 if (event != NB_EV_APPLY)
170 return NB_OK;
171
172 yang_dnode_get_ipv4p(&prefix, dnode, "./prefix");
173
174 /* Get RIP distance node. */
175 rn = route_node_get(rip_distance_table, (struct prefix *)&prefix);
176 rn->info = rip_distance_new();
177 yang_dnode_set_entry(dnode, rn);
178
707656ec
RW
179 return NB_OK;
180}
181
182static int ripd_instance_distance_source_delete(enum nb_event event,
183 const struct lyd_node *dnode)
184{
23b23d8c
RW
185 struct route_node *rn;
186 struct rip_distance *rdistance;
187
188 if (event != NB_EV_APPLY)
189 return NB_OK;
190
191 rn = yang_dnode_get_entry(dnode);
192 rdistance = rn->info;
193 if (rdistance->access_list)
194 free(rdistance->access_list);
195 rip_distance_free(rdistance);
196
197 rn->info = NULL;
198 route_unlock_node(rn);
199
707656ec
RW
200 return NB_OK;
201}
202
203/*
204 * XPath: /frr-ripd:ripd/instance/distance/source/distance
205 */
206static int
207ripd_instance_distance_source_distance_modify(enum nb_event event,
208 const struct lyd_node *dnode,
209 union nb_resource *resource)
210{
23b23d8c
RW
211 struct route_node *rn;
212 uint8_t distance;
213 struct rip_distance *rdistance;
214
215 if (event != NB_EV_APPLY)
216 return NB_OK;
217
218 /* Set distance value. */
219 rn = yang_dnode_get_entry(dnode);
220 distance = yang_dnode_get_uint8(dnode, NULL);
221 rdistance = rn->info;
222 rdistance->distance = distance;
223
707656ec
RW
224 return NB_OK;
225}
226
227/*
228 * XPath: /frr-ripd:ripd/instance/distance/source/access-list
229 */
230static int
231ripd_instance_distance_source_access_list_modify(enum nb_event event,
232 const struct lyd_node *dnode,
233 union nb_resource *resource)
234{
23b23d8c
RW
235 const char *acl_name;
236 struct route_node *rn;
237 struct rip_distance *rdistance;
238
239 if (event != NB_EV_APPLY)
240 return NB_OK;
241
242 acl_name = yang_dnode_get_string(dnode, NULL);
243
244 /* Set access-list */
245 rn = yang_dnode_get_entry(dnode);
246 rdistance = rn->info;
247 if (rdistance->access_list)
248 free(rdistance->access_list);
249 rdistance->access_list = strdup(acl_name);
250
707656ec
RW
251 return NB_OK;
252}
253
254static int
255ripd_instance_distance_source_access_list_delete(enum nb_event event,
256 const struct lyd_node *dnode)
257{
23b23d8c
RW
258 struct route_node *rn;
259 struct rip_distance *rdistance;
260
261 if (event != NB_EV_APPLY)
262 return NB_OK;
263
264 /* Reset access-list configuration. */
265 rn = yang_dnode_get_entry(dnode);
266 rdistance = rn->info;
267 free(rdistance->access_list);
268 rdistance->access_list = NULL;
269
707656ec
RW
270 return NB_OK;
271}
272
273/*
274 * XPath: /frr-ripd:ripd/instance/explicit-neighbor
275 */
276static int ripd_instance_explicit_neighbor_create(enum nb_event event,
277 const struct lyd_node *dnode,
278 union nb_resource *resource)
279{
f0ab22fb
RW
280 struct prefix_ipv4 p;
281
282 if (event != NB_EV_APPLY)
283 return NB_OK;
284
285 p.family = AF_INET;
286 p.prefixlen = IPV4_MAX_BITLEN;
287 yang_dnode_get_ipv4(&p.prefix, dnode, NULL);
288
289 return rip_neighbor_add(&p);
707656ec
RW
290}
291
292static int ripd_instance_explicit_neighbor_delete(enum nb_event event,
293 const struct lyd_node *dnode)
294{
f0ab22fb
RW
295 struct prefix_ipv4 p;
296
297 if (event != NB_EV_APPLY)
298 return NB_OK;
299
300 p.family = AF_INET;
301 p.prefixlen = IPV4_MAX_BITLEN;
302 yang_dnode_get_ipv4(&p.prefix, dnode, NULL);
303
304 return rip_neighbor_delete(&p);
707656ec
RW
305}
306
307/*
308 * XPath: /frr-ripd:ripd/instance/network
309 */
310static int ripd_instance_network_create(enum nb_event event,
311 const struct lyd_node *dnode,
312 union nb_resource *resource)
313{
3d7a1be8
RW
314 struct prefix p;
315
316 if (event != NB_EV_APPLY)
317 return NB_OK;
318
319 yang_dnode_get_ipv4p(&p, dnode, NULL);
320
321 return rip_enable_network_add(&p);
707656ec
RW
322}
323
324static int ripd_instance_network_delete(enum nb_event event,
325 const struct lyd_node *dnode)
326{
3d7a1be8
RW
327 struct prefix p;
328
329 if (event != NB_EV_APPLY)
330 return NB_OK;
331
332 yang_dnode_get_ipv4p(&p, dnode, NULL);
333
334 return rip_enable_network_delete(&p);
707656ec
RW
335}
336
337/*
338 * XPath: /frr-ripd:ripd/instance/interface
339 */
340static int ripd_instance_interface_create(enum nb_event event,
341 const struct lyd_node *dnode,
342 union nb_resource *resource)
343{
3d7a1be8
RW
344 const char *ifname;
345
346 if (event != NB_EV_APPLY)
347 return NB_OK;
348
349 ifname = yang_dnode_get_string(dnode, NULL);
350
351 return rip_enable_if_add(ifname);
707656ec
RW
352}
353
354static int ripd_instance_interface_delete(enum nb_event event,
355 const struct lyd_node *dnode)
356{
3d7a1be8
RW
357 const char *ifname;
358
359 if (event != NB_EV_APPLY)
360 return NB_OK;
361
362 ifname = yang_dnode_get_string(dnode, NULL);
363
364 return rip_enable_if_delete(ifname);
707656ec
RW
365}
366
367/*
368 * XPath: /frr-ripd:ripd/instance/offset-list
369 */
370static int ripd_instance_offset_list_create(enum nb_event event,
371 const struct lyd_node *dnode,
372 union nb_resource *resource)
373{
8c942f65
RW
374 const char *ifname;
375 struct rip_offset_list *offset;
376
377 if (event != NB_EV_APPLY)
378 return NB_OK;
379
380 ifname = yang_dnode_get_string(dnode, "./interface");
381
382 offset = rip_offset_list_new(ifname);
383 yang_dnode_set_entry(dnode, offset);
384
707656ec
RW
385 return NB_OK;
386}
387
388static int ripd_instance_offset_list_delete(enum nb_event event,
389 const struct lyd_node *dnode)
390{
8c942f65
RW
391 int direct;
392 struct rip_offset_list *offset;
393
394 if (event != NB_EV_APPLY)
395 return NB_OK;
396
397 direct = yang_dnode_get_enum(dnode, "./direction");
398
399 offset = yang_dnode_get_entry(dnode);
400 if (offset->direct[direct].alist_name) {
401 free(offset->direct[direct].alist_name);
402 offset->direct[direct].alist_name = NULL;
403 }
404 if (offset->direct[RIP_OFFSET_LIST_IN].alist_name == NULL
405 && offset->direct[RIP_OFFSET_LIST_OUT].alist_name == NULL)
406 offset_list_del(offset);
407
707656ec
RW
408 return NB_OK;
409}
410
411/*
412 * XPath: /frr-ripd:ripd/instance/offset-list/access-list
413 */
414static int
415ripd_instance_offset_list_access_list_modify(enum nb_event event,
416 const struct lyd_node *dnode,
417 union nb_resource *resource)
418{
8c942f65
RW
419 int direct;
420 struct rip_offset_list *offset;
421 const char *alist_name;
422
423 if (event != NB_EV_APPLY)
424 return NB_OK;
425
426 direct = yang_dnode_get_enum(dnode, "../direction");
427 alist_name = yang_dnode_get_string(dnode, NULL);
428
429 offset = yang_dnode_get_entry(dnode);
430 if (offset->direct[direct].alist_name)
431 free(offset->direct[direct].alist_name);
432 offset->direct[direct].alist_name = strdup(alist_name);
433
707656ec
RW
434 return NB_OK;
435}
436
437/*
438 * XPath: /frr-ripd:ripd/instance/offset-list/metric
439 */
440static int ripd_instance_offset_list_metric_modify(enum nb_event event,
441 const struct lyd_node *dnode,
442 union nb_resource *resource)
443{
8c942f65
RW
444 int direct;
445 uint8_t metric;
446 struct rip_offset_list *offset;
447
448 if (event != NB_EV_APPLY)
449 return NB_OK;
450
451 direct = yang_dnode_get_enum(dnode, "../direction");
452 metric = yang_dnode_get_uint8(dnode, NULL);
453
454 offset = yang_dnode_get_entry(dnode);
455 offset->direct[direct].metric = metric;
456
707656ec
RW
457 return NB_OK;
458}
459
460/*
461 * XPath: /frr-ripd:ripd/instance/passive-default
462 */
463static int ripd_instance_passive_default_modify(enum nb_event event,
464 const struct lyd_node *dnode,
465 union nb_resource *resource)
466{
44f2f852
RW
467 if (event != NB_EV_APPLY)
468 return NB_OK;
469
470 rip->passive_default = yang_dnode_get_bool(dnode, NULL);
471 rip_passive_nondefault_clean();
472
707656ec
RW
473 return NB_OK;
474}
475
476/*
477 * XPath: /frr-ripd:ripd/instance/passive-interface
478 */
479static int ripd_instance_passive_interface_create(enum nb_event event,
480 const struct lyd_node *dnode,
481 union nb_resource *resource)
482{
44f2f852
RW
483 const char *ifname;
484
485 if (event != NB_EV_APPLY)
486 return NB_OK;
487
488 ifname = yang_dnode_get_string(dnode, NULL);
489
490 return rip_passive_nondefault_set(ifname);
707656ec
RW
491}
492
493static int ripd_instance_passive_interface_delete(enum nb_event event,
494 const struct lyd_node *dnode)
495{
44f2f852
RW
496 const char *ifname;
497
498 if (event != NB_EV_APPLY)
499 return NB_OK;
500
501 ifname = yang_dnode_get_string(dnode, NULL);
502
503 return rip_passive_nondefault_unset(ifname);
707656ec
RW
504}
505
506/*
507 * XPath: /frr-ripd:ripd/instance/non-passive-interface
508 */
509static int
510ripd_instance_non_passive_interface_create(enum nb_event event,
511 const struct lyd_node *dnode,
512 union nb_resource *resource)
513{
44f2f852
RW
514 const char *ifname;
515
516 if (event != NB_EV_APPLY)
517 return NB_OK;
518
519 ifname = yang_dnode_get_string(dnode, NULL);
520
521 return rip_passive_nondefault_unset(ifname);
707656ec
RW
522}
523
524static int
525ripd_instance_non_passive_interface_delete(enum nb_event event,
526 const struct lyd_node *dnode)
527{
44f2f852
RW
528 const char *ifname;
529
530 if (event != NB_EV_APPLY)
531 return NB_OK;
532
533 ifname = yang_dnode_get_string(dnode, NULL);
534
535 return rip_passive_nondefault_set(ifname);
707656ec
RW
536}
537
538/*
539 * XPath: /frr-ripd:ripd/instance/redistribute
540 */
541static int ripd_instance_redistribute_create(enum nb_event event,
542 const struct lyd_node *dnode,
543 union nb_resource *resource)
544{
707656ec
RW
545 return NB_OK;
546}
547
548static int ripd_instance_redistribute_delete(enum nb_event event,
549 const struct lyd_node *dnode)
550{
908f0020
RW
551 int type;
552
553 if (event != NB_EV_APPLY)
554 return NB_OK;
555
556 type = yang_dnode_get_enum(dnode, "./protocol");
557
558 rip_redistribute_conf_delete(type);
559
707656ec
RW
560 return NB_OK;
561}
562
908f0020
RW
563static void
564ripd_instance_redistribute_apply_finish(const struct lyd_node *dnode)
565{
566 int type;
567
568 type = yang_dnode_get_enum(dnode, "./protocol");
569 rip_redistribute_conf_update(type);
570}
571
707656ec
RW
572/*
573 * XPath: /frr-ripd:ripd/instance/redistribute/route-map
574 */
575static int
576ripd_instance_redistribute_route_map_modify(enum nb_event event,
577 const struct lyd_node *dnode,
578 union nb_resource *resource)
579{
908f0020
RW
580 int type;
581 const char *rmap_name;
582
583 if (event != NB_EV_APPLY)
584 return NB_OK;
585
586 type = yang_dnode_get_enum(dnode, "../protocol");
587 rmap_name = yang_dnode_get_string(dnode, NULL);
588
589 if (rip->route_map[type].name)
590 free(rip->route_map[type].name);
591 rip->route_map[type].name = strdup(rmap_name);
592 rip->route_map[type].map = route_map_lookup_by_name(rmap_name);
593
707656ec
RW
594 return NB_OK;
595}
596
597static int
598ripd_instance_redistribute_route_map_delete(enum nb_event event,
599 const struct lyd_node *dnode)
600{
908f0020
RW
601 int type;
602
603 if (event != NB_EV_APPLY)
604 return NB_OK;
605
606 type = yang_dnode_get_enum(dnode, "../protocol");
607
608 if (rip->route_map[type].name) {
609 free(rip->route_map[type].name);
610 rip->route_map[type].name = NULL;
611 }
612
707656ec
RW
613 return NB_OK;
614}
615
616/*
617 * XPath: /frr-ripd:ripd/instance/redistribute/metric
618 */
619static int
620ripd_instance_redistribute_metric_modify(enum nb_event event,
621 const struct lyd_node *dnode,
622 union nb_resource *resource)
623{
908f0020
RW
624 int type;
625 uint8_t metric;
626
627 if (event != NB_EV_APPLY)
628 return NB_OK;
629
630 type = yang_dnode_get_enum(dnode, "../protocol");
631 metric = yang_dnode_get_uint8(dnode, NULL);
632
633 rip->route_map[type].metric_config = true;
634 rip->route_map[type].metric = metric;
635
707656ec
RW
636 return NB_OK;
637}
638
639static int
640ripd_instance_redistribute_metric_delete(enum nb_event event,
641 const struct lyd_node *dnode)
642{
908f0020
RW
643 int type;
644
645 if (event != NB_EV_APPLY)
646 return NB_OK;
647
648 type = yang_dnode_get_enum(dnode, "../protocol");
649
650 rip->route_map[type].metric_config = false;
651 rip->route_map[type].metric = 0;
652
707656ec
RW
653 return NB_OK;
654}
655
656/*
657 * XPath: /frr-ripd:ripd/instance/static-route
658 */
659static int ripd_instance_static_route_create(enum nb_event event,
660 const struct lyd_node *dnode,
661 union nb_resource *resource)
662{
40687878
RW
663 struct nexthop nh;
664 struct prefix_ipv4 p;
665
666 if (event != NB_EV_APPLY)
667 return NB_OK;
668
669 yang_dnode_get_ipv4p(&p, dnode, NULL);
670
671 memset(&nh, 0, sizeof(nh));
672 nh.type = NEXTHOP_TYPE_IPV4;
673 rip_redistribute_add(ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, &nh, 0, 0,
674 0);
675
707656ec
RW
676 return NB_OK;
677}
678
679static int ripd_instance_static_route_delete(enum nb_event event,
680 const struct lyd_node *dnode)
681{
40687878
RW
682 struct prefix_ipv4 p;
683
684 if (event != NB_EV_APPLY)
685 return NB_OK;
686
687 yang_dnode_get_ipv4p(&p, dnode, NULL);
688
689 rip_redistribute_delete(ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0);
690
707656ec
RW
691 return NB_OK;
692}
693
b745780b
RW
694/*
695 * XPath: /frr-ripd:ripd/instance/timers/
696 */
697static void ripd_instance_timers_apply_finish(const struct lyd_node *dnode)
698{
699 /* Reset update timer thread. */
700 rip_event(RIP_UPDATE_EVENT, 0);
701}
702
707656ec
RW
703/*
704 * XPath: /frr-ripd:ripd/instance/timers/flush-interval
705 */
706static int
707ripd_instance_timers_flush_interval_modify(enum nb_event event,
708 const struct lyd_node *dnode,
709 union nb_resource *resource)
710{
b745780b
RW
711 if (event != NB_EV_APPLY)
712 return NB_OK;
713
714 rip->garbage_time = yang_dnode_get_uint32(dnode, NULL);
715
707656ec
RW
716 return NB_OK;
717}
718
719/*
720 * XPath: /frr-ripd:ripd/instance/timers/holddown-interval
721 */
722static int
723ripd_instance_timers_holddown_interval_modify(enum nb_event event,
724 const struct lyd_node *dnode,
725 union nb_resource *resource)
726{
b745780b
RW
727 if (event != NB_EV_APPLY)
728 return NB_OK;
729
730 rip->timeout_time = yang_dnode_get_uint32(dnode, NULL);
731
707656ec
RW
732 return NB_OK;
733}
734
735/*
736 * XPath: /frr-ripd:ripd/instance/timers/update-interval
737 */
738static int
739ripd_instance_timers_update_interval_modify(enum nb_event event,
740 const struct lyd_node *dnode,
741 union nb_resource *resource)
742{
b745780b
RW
743 if (event != NB_EV_APPLY)
744 return NB_OK;
745
746 rip->update_time = yang_dnode_get_uint32(dnode, NULL);
747
707656ec
RW
748 return NB_OK;
749}
750
751/*
752 * XPath: /frr-ripd:ripd/instance/version/receive
753 */
754static int ripd_instance_version_receive_modify(enum nb_event event,
755 const struct lyd_node *dnode,
756 union nb_resource *resource)
757{
90eff9da
RW
758 if (event != NB_EV_APPLY)
759 return NB_OK;
760
761 rip->version_recv = yang_dnode_get_enum(dnode, NULL);
762
707656ec
RW
763 return NB_OK;
764}
765
766/*
767 * XPath: /frr-ripd:ripd/instance/version/send
768 */
769static int ripd_instance_version_send_modify(enum nb_event event,
770 const struct lyd_node *dnode,
771 union nb_resource *resource)
772{
90eff9da
RW
773 if (event != NB_EV_APPLY)
774 return NB_OK;
775
776 rip->version_send = yang_dnode_get_enum(dnode, NULL);
777
707656ec
RW
778 return NB_OK;
779}
780
781/*
782 * XPath: /frr-interface:lib/interface/frr-ripd:rip/split-horizon
783 */
784static int lib_interface_rip_split_horizon_modify(enum nb_event event,
785 const struct lyd_node *dnode,
786 union nb_resource *resource)
787{
94b117b2
RW
788 struct interface *ifp;
789 struct rip_interface *ri;
790
791 if (event != NB_EV_APPLY)
792 return NB_OK;
793
794 ifp = yang_dnode_get_entry(dnode);
795 ri = ifp->info;
796 ri->split_horizon = yang_dnode_get_enum(dnode, NULL);
797
707656ec
RW
798 return NB_OK;
799}
800
801/*
802 * XPath: /frr-interface:lib/interface/frr-ripd:rip/v2-broadcast
803 */
804static int lib_interface_rip_v2_broadcast_modify(enum nb_event event,
805 const struct lyd_node *dnode,
806 union nb_resource *resource)
807{
94b117b2
RW
808 struct interface *ifp;
809 struct rip_interface *ri;
810
811 if (event != NB_EV_APPLY)
812 return NB_OK;
813
814 ifp = yang_dnode_get_entry(dnode);
815 ri = ifp->info;
816 ri->v2_broadcast = yang_dnode_get_bool(dnode, NULL);
817
707656ec
RW
818 return NB_OK;
819}
820
821/*
822 * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-receive
823 */
824static int
825lib_interface_rip_version_receive_modify(enum nb_event event,
826 const struct lyd_node *dnode,
827 union nb_resource *resource)
828{
94b117b2
RW
829 struct interface *ifp;
830 struct rip_interface *ri;
831
832 if (event != NB_EV_APPLY)
833 return NB_OK;
834
835 ifp = yang_dnode_get_entry(dnode);
836 ri = ifp->info;
837 ri->ri_receive = yang_dnode_get_enum(dnode, NULL);
838
707656ec
RW
839 return NB_OK;
840}
841
842/*
843 * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-send
844 */
845static int lib_interface_rip_version_send_modify(enum nb_event event,
846 const struct lyd_node *dnode,
847 union nb_resource *resource)
848{
94b117b2
RW
849 struct interface *ifp;
850 struct rip_interface *ri;
851
852 if (event != NB_EV_APPLY)
853 return NB_OK;
854
855 ifp = yang_dnode_get_entry(dnode);
856 ri = ifp->info;
857 ri->ri_send = yang_dnode_get_enum(dnode, NULL);
858
707656ec
RW
859 return NB_OK;
860}
861
862/*
863 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/mode
864 */
865static int lib_interface_rip_authentication_scheme_mode_modify(
866 enum nb_event event, const struct lyd_node *dnode,
867 union nb_resource *resource)
868{
94b117b2
RW
869 struct interface *ifp;
870 struct rip_interface *ri;
871
872 if (event != NB_EV_APPLY)
873 return NB_OK;
874
875 ifp = yang_dnode_get_entry(dnode);
876 ri = ifp->info;
877 ri->auth_type = yang_dnode_get_enum(dnode, NULL);
878
707656ec
RW
879 return NB_OK;
880}
881
882/*
883 * XPath:
884 * /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/md5-auth-length
885 */
886static int lib_interface_rip_authentication_scheme_md5_auth_length_modify(
887 enum nb_event event, const struct lyd_node *dnode,
888 union nb_resource *resource)
889{
94b117b2
RW
890 struct interface *ifp;
891 struct rip_interface *ri;
892
893 if (event != NB_EV_APPLY)
894 return NB_OK;
895
896 ifp = yang_dnode_get_entry(dnode);
897 ri = ifp->info;
898 ri->md5_auth_len = yang_dnode_get_enum(dnode, NULL);
899
707656ec
RW
900 return NB_OK;
901}
902
903static int lib_interface_rip_authentication_scheme_md5_auth_length_delete(
904 enum nb_event event, const struct lyd_node *dnode)
905{
94b117b2
RW
906 struct interface *ifp;
907 struct rip_interface *ri;
908
909 if (event != NB_EV_APPLY)
910 return NB_OK;
911
912 ifp = yang_dnode_get_entry(dnode);
913 ri = ifp->info;
914 ri->md5_auth_len = yang_get_default_enum(
915 "%s/authentication-scheme/md5-auth-length", RIP_IFACE);
916
707656ec
RW
917 return NB_OK;
918}
919
920/*
921 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-password
922 */
923static int
924lib_interface_rip_authentication_password_modify(enum nb_event event,
925 const struct lyd_node *dnode,
926 union nb_resource *resource)
927{
94b117b2
RW
928 struct interface *ifp;
929 struct rip_interface *ri;
930
931 if (event != NB_EV_APPLY)
932 return NB_OK;
933
934 ifp = yang_dnode_get_entry(dnode);
935 ri = ifp->info;
936 if (ri->auth_str)
937 XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
938 ri->auth_str = XSTRDUP(MTYPE_RIP_INTERFACE_STRING,
939 yang_dnode_get_string(dnode, NULL));
940
707656ec
RW
941 return NB_OK;
942}
943
944static int
945lib_interface_rip_authentication_password_delete(enum nb_event event,
946 const struct lyd_node *dnode)
947{
94b117b2
RW
948 struct interface *ifp;
949 struct rip_interface *ri;
950
951 if (event != NB_EV_APPLY)
952 return NB_OK;
953
954 ifp = yang_dnode_get_entry(dnode);
955 ri = ifp->info;
956 XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
957
707656ec
RW
958 return NB_OK;
959}
960
961/*
962 * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain
963 */
964static int
965lib_interface_rip_authentication_key_chain_modify(enum nb_event event,
966 const struct lyd_node *dnode,
967 union nb_resource *resource)
968{
94b117b2
RW
969 struct interface *ifp;
970 struct rip_interface *ri;
971
972 if (event != NB_EV_APPLY)
973 return NB_OK;
974
975 ifp = yang_dnode_get_entry(dnode);
976 ri = ifp->info;
977 if (ri->key_chain)
978 XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
979 ri->key_chain = XSTRDUP(MTYPE_RIP_INTERFACE_STRING,
980 yang_dnode_get_string(dnode, NULL));
981
707656ec
RW
982 return NB_OK;
983}
984
985static int
986lib_interface_rip_authentication_key_chain_delete(enum nb_event event,
987 const struct lyd_node *dnode)
988{
94b117b2
RW
989 struct interface *ifp;
990 struct rip_interface *ri;
991
992 if (event != NB_EV_APPLY)
993 return NB_OK;
994
995 ifp = yang_dnode_get_entry(dnode);
996 ri = ifp->info;
997 XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
998
707656ec
RW
999 return NB_OK;
1000}
1001
1002/*
1003 * XPath: /frr-ripd:ripd/state/neighbors/neighbor
1004 */
1005static const void *
1006ripd_state_neighbors_neighbor_get_next(const char *xpath,
1007 const void *list_entry)
1008{
5c1a8497
RW
1009 struct listnode *node;
1010
1011 if (list_entry == NULL)
1012 node = listhead(peer_list);
1013 else
1014 node = listnextnode((struct listnode *)list_entry);
1015
1016 return node;
707656ec
RW
1017}
1018
1019static int ripd_state_neighbors_neighbor_get_keys(const void *list_entry,
1020 struct yang_list_keys *keys)
1021{
5c1a8497
RW
1022 const struct listnode *node = list_entry;
1023 const struct rip_peer *peer = listgetdata(node);
1024
1025 keys->num = 1;
1026 (void)inet_ntop(AF_INET, &peer->addr, keys->key[0].value,
1027 sizeof(keys->key[0].value));
1028
707656ec
RW
1029 return NB_OK;
1030}
1031
1032static const void *
1033ripd_state_neighbors_neighbor_lookup_entry(const struct yang_list_keys *keys)
1034{
5c1a8497
RW
1035 struct in_addr address;
1036
1037 yang_str2ipv4(keys->key[0].value, &address);
1038
1039 return rip_peer_lookup(&address);
707656ec
RW
1040}
1041
1042/*
1043 * XPath: /frr-ripd:ripd/state/neighbors/neighbor/address
1044 */
1045static struct yang_data *
1046ripd_state_neighbors_neighbor_address_get_elem(const char *xpath,
1047 const void *list_entry)
1048{
5c1a8497
RW
1049 const struct rip_peer *peer = list_entry;
1050
1051 return yang_data_new_ipv4(xpath, &peer->addr);
707656ec
RW
1052}
1053
1054/*
1055 * XPath: /frr-ripd:ripd/state/neighbors/neighbor/last-update
1056 */
1057static struct yang_data *
1058ripd_state_neighbors_neighbor_last_update_get_elem(const char *xpath,
1059 const void *list_entry)
1060{
5c1a8497 1061 /* TODO: yang:date-and-time is tricky */
707656ec
RW
1062 return NULL;
1063}
1064
1065/*
1066 * XPath: /frr-ripd:ripd/state/neighbors/neighbor/bad-packets-rcvd
1067 */
1068static struct yang_data *
1069ripd_state_neighbors_neighbor_bad_packets_rcvd_get_elem(const char *xpath,
1070 const void *list_entry)
1071{
5c1a8497
RW
1072 const struct rip_peer *peer = list_entry;
1073
1074 return yang_data_new_uint32(xpath, peer->recv_badpackets);
707656ec
RW
1075}
1076
1077/*
1078 * XPath: /frr-ripd:ripd/state/neighbors/neighbor/bad-routes-rcvd
1079 */
1080static struct yang_data *
1081ripd_state_neighbors_neighbor_bad_routes_rcvd_get_elem(const char *xpath,
1082 const void *list_entry)
1083{
5c1a8497
RW
1084 const struct rip_peer *peer = list_entry;
1085
1086 return yang_data_new_uint32(xpath, peer->recv_badroutes);
707656ec
RW
1087}
1088
1089/*
1090 * XPath: /frr-ripd:ripd/state/routes/route
1091 */
1092static const void *ripd_state_routes_route_get_next(const char *xpath,
1093 const void *list_entry)
1094{
6270ce38
RW
1095 struct route_node *rn;
1096
1097 if (rip == NULL)
1098 return NULL;
1099
1100 if (list_entry == NULL)
1101 rn = route_top(rip->table);
1102 else
1103 rn = route_next((struct route_node *)list_entry);
1104 while (rn && rn->info == NULL)
1105 rn = route_next(rn);
1106
1107 return rn;
707656ec
RW
1108}
1109
1110static int ripd_state_routes_route_get_keys(const void *list_entry,
1111 struct yang_list_keys *keys)
1112{
6270ce38
RW
1113 const struct route_node *rn = list_entry;
1114
1115 keys->num = 1;
1116 (void)prefix2str(&rn->p, keys->key[0].value,
1117 sizeof(keys->key[0].value));
1118
707656ec
RW
1119 return NB_OK;
1120}
1121
1122static const void *
1123ripd_state_routes_route_lookup_entry(const struct yang_list_keys *keys)
1124{
6270ce38
RW
1125 struct prefix prefix;
1126 struct route_node *rn;
1127
1128 yang_str2ipv4p(keys->key[0].value, &prefix);
1129
1130 rn = route_node_lookup(rip->table, &prefix);
1131 if (!rn || !rn->info)
1132 return NULL;
1133
1134 route_unlock_node(rn);
1135
1136 /*
1137 * TODO: we need to handle ECMP properly.
1138 */
1139 return listnode_head(rn->info);
707656ec
RW
1140}
1141
1142/*
1143 * XPath: /frr-ripd:ripd/state/routes/route/prefix
1144 */
1145static struct yang_data *
1146ripd_state_routes_route_prefix_get_elem(const char *xpath,
1147 const void *list_entry)
1148{
6270ce38
RW
1149 const struct rip_info *rinfo = list_entry;
1150
1151 return yang_data_new_ipv4p(xpath, &rinfo->rp->p);
707656ec
RW
1152}
1153
1154/*
1155 * XPath: /frr-ripd:ripd/state/routes/route/next-hop
1156 */
1157static struct yang_data *
1158ripd_state_routes_route_next_hop_get_elem(const char *xpath,
1159 const void *list_entry)
1160{
6270ce38
RW
1161 const struct rip_info *rinfo = list_entry;
1162
1163 switch (rinfo->nh.type) {
1164 case NEXTHOP_TYPE_IPV4:
1165 case NEXTHOP_TYPE_IPV4_IFINDEX:
1166 return yang_data_new_ipv4(xpath, &rinfo->nh.gate.ipv4);
1167 default:
1168 return NULL;
1169 }
707656ec
RW
1170}
1171
1172/*
1173 * XPath: /frr-ripd:ripd/state/routes/route/interface
1174 */
1175static struct yang_data *
1176ripd_state_routes_route_interface_get_elem(const char *xpath,
1177 const void *list_entry)
1178{
6270ce38
RW
1179 const struct rip_info *rinfo = list_entry;
1180
1181 switch (rinfo->nh.type) {
1182 case NEXTHOP_TYPE_IFINDEX:
1183 case NEXTHOP_TYPE_IPV4_IFINDEX:
1184 return yang_data_new_string(
1185 xpath, ifindex2ifname(rinfo->nh.ifindex, VRF_DEFAULT));
1186 default:
1187 return NULL;
1188 }
707656ec
RW
1189}
1190
1191/*
1192 * XPath: /frr-ripd:ripd/state/routes/route/metric
1193 */
1194static struct yang_data *
1195ripd_state_routes_route_metric_get_elem(const char *xpath,
1196 const void *list_entry)
1197{
6270ce38
RW
1198 const struct rip_info *rinfo = list_entry;
1199
1200 return yang_data_new_uint8(xpath, rinfo->metric);
707656ec
RW
1201}
1202
1203/*
1204 * XPath: /frr-ripd:clear-rip-route
1205 */
1206static int clear_rip_route_rpc(const char *xpath, const struct list *input,
1207 struct list *output)
1208{
1137aef4
RW
1209 struct route_node *rp;
1210 struct rip_info *rinfo;
1211 struct list *list;
1212 struct listnode *listnode;
1213
1214 /* Clear received RIP routes */
1215 for (rp = route_top(rip->table); rp; rp = route_next(rp)) {
1216 list = rp->info;
1217 if (!list)
1218 continue;
1219
1220 for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
1221 if (!rip_route_rte(rinfo))
1222 continue;
1223
1224 if (CHECK_FLAG(rinfo->flags, RIP_RTF_FIB))
1225 rip_zebra_ipv4_delete(rp);
1226 break;
1227 }
1228
1229 if (rinfo) {
1230 RIP_TIMER_OFF(rinfo->t_timeout);
1231 RIP_TIMER_OFF(rinfo->t_garbage_collect);
1232 listnode_delete(list, rinfo);
1233 rip_info_free(rinfo);
1234 }
1235
1236 if (list_isempty(list)) {
1237 list_delete(&list);
1238 rp->info = NULL;
1239 route_unlock_node(rp);
1240 }
1241 }
1242
707656ec
RW
1243 return NB_OK;
1244}
1245
fe339c95
RW
1246/*
1247 * XPath: /frr-ripd:authentication-type-failure
1248 */
1249void ripd_notif_send_auth_type_failure(const char *ifname)
1250{
1251 const char *xpath = "/frr-ripd:authentication-type-failure";
1252 struct list *arguments;
1253 char xpath_arg[XPATH_MAXLEN];
1254 struct yang_data *data;
1255
1256 arguments = yang_data_list_new();
1257
1258 snprintf(xpath_arg, sizeof(xpath_arg), "%s/interface-name", xpath);
1259 data = yang_data_new_string(xpath_arg, ifname);
1260 listnode_add(arguments, data);
1261
1262 nb_notification_send(xpath, arguments);
1263}
1264
1265/*
1266 * XPath: /frr-ripd:authentication-failure
1267 */
1268void ripd_notif_send_auth_failure(const char *ifname)
1269{
1270 const char *xpath = "/frr-ripd:authentication-failure";
1271 struct list *arguments;
1272 char xpath_arg[XPATH_MAXLEN];
1273 struct yang_data *data;
1274
1275 arguments = yang_data_list_new();
1276
1277 snprintf(xpath_arg, sizeof(xpath_arg), "%s/interface-name", xpath);
1278 data = yang_data_new_string(xpath_arg, ifname);
1279 listnode_add(arguments, data);
1280
1281 nb_notification_send(xpath, arguments);
1282}
1283
707656ec
RW
1284/* clang-format off */
1285const struct frr_yang_module_info frr_ripd_info = {
1286 .name = "frr-ripd",
1287 .nodes = {
1288 {
1289 .xpath = "/frr-ripd:ripd/instance",
1290 .cbs.create = ripd_instance_create,
1291 .cbs.delete = ripd_instance_delete,
8c9226c2 1292 .cbs.cli_show = cli_show_router_rip,
707656ec
RW
1293 },
1294 {
1295 .xpath = "/frr-ripd:ripd/instance/allow-ecmp",
1296 .cbs.modify = ripd_instance_allow_ecmp_modify,
edbf59d2 1297 .cbs.cli_show = cli_show_rip_allow_ecmp,
707656ec
RW
1298 },
1299 {
1300 .xpath = "/frr-ripd:ripd/instance/default-information-originate",
1301 .cbs.modify = ripd_instance_default_information_originate_modify,
0b0609ba 1302 .cbs.cli_show = cli_show_rip_default_information_originate,
707656ec
RW
1303 },
1304 {
1305 .xpath = "/frr-ripd:ripd/instance/default-metric",
1306 .cbs.modify = ripd_instance_default_metric_modify,
282ae30c 1307 .cbs.cli_show = cli_show_rip_default_metric,
707656ec
RW
1308 },
1309 {
1310 .xpath = "/frr-ripd:ripd/instance/distance/default",
1311 .cbs.modify = ripd_instance_distance_default_modify,
7f8a9cba 1312 .cbs.cli_show = cli_show_rip_distance,
707656ec
RW
1313 },
1314 {
1315 .xpath = "/frr-ripd:ripd/instance/distance/source",
1316 .cbs.create = ripd_instance_distance_source_create,
1317 .cbs.delete = ripd_instance_distance_source_delete,
23b23d8c 1318 .cbs.cli_show = cli_show_rip_distance_source,
707656ec
RW
1319 },
1320 {
1321 .xpath = "/frr-ripd:ripd/instance/distance/source/distance",
1322 .cbs.modify = ripd_instance_distance_source_distance_modify,
1323 },
1324 {
1325 .xpath = "/frr-ripd:ripd/instance/distance/source/access-list",
1326 .cbs.modify = ripd_instance_distance_source_access_list_modify,
1327 .cbs.delete = ripd_instance_distance_source_access_list_delete,
1328 },
1329 {
1330 .xpath = "/frr-ripd:ripd/instance/explicit-neighbor",
1331 .cbs.create = ripd_instance_explicit_neighbor_create,
1332 .cbs.delete = ripd_instance_explicit_neighbor_delete,
f0ab22fb 1333 .cbs.cli_show = cli_show_rip_neighbor,
707656ec
RW
1334 },
1335 {
1336 .xpath = "/frr-ripd:ripd/instance/network",
1337 .cbs.create = ripd_instance_network_create,
1338 .cbs.delete = ripd_instance_network_delete,
3d7a1be8 1339 .cbs.cli_show = cli_show_rip_network_prefix,
707656ec
RW
1340 },
1341 {
1342 .xpath = "/frr-ripd:ripd/instance/interface",
1343 .cbs.create = ripd_instance_interface_create,
1344 .cbs.delete = ripd_instance_interface_delete,
3d7a1be8 1345 .cbs.cli_show = cli_show_rip_network_interface,
707656ec
RW
1346 },
1347 {
1348 .xpath = "/frr-ripd:ripd/instance/offset-list",
1349 .cbs.create = ripd_instance_offset_list_create,
1350 .cbs.delete = ripd_instance_offset_list_delete,
8c942f65 1351 .cbs.cli_show = cli_show_rip_offset_list,
707656ec
RW
1352 },
1353 {
1354 .xpath = "/frr-ripd:ripd/instance/offset-list/access-list",
1355 .cbs.modify = ripd_instance_offset_list_access_list_modify,
1356 },
1357 {
1358 .xpath = "/frr-ripd:ripd/instance/offset-list/metric",
1359 .cbs.modify = ripd_instance_offset_list_metric_modify,
1360 },
1361 {
1362 .xpath = "/frr-ripd:ripd/instance/passive-default",
1363 .cbs.modify = ripd_instance_passive_default_modify,
44f2f852 1364 .cbs.cli_show = cli_show_rip_passive_default,
707656ec
RW
1365 },
1366 {
1367 .xpath = "/frr-ripd:ripd/instance/passive-interface",
1368 .cbs.create = ripd_instance_passive_interface_create,
1369 .cbs.delete = ripd_instance_passive_interface_delete,
44f2f852 1370 .cbs.cli_show = cli_show_rip_passive_interface,
707656ec
RW
1371 },
1372 {
1373 .xpath = "/frr-ripd:ripd/instance/non-passive-interface",
1374 .cbs.create = ripd_instance_non_passive_interface_create,
1375 .cbs.delete = ripd_instance_non_passive_interface_delete,
44f2f852 1376 .cbs.cli_show = cli_show_rip_non_passive_interface,
707656ec
RW
1377 },
1378 {
1379 .xpath = "/frr-ripd:ripd/instance/redistribute",
1380 .cbs.create = ripd_instance_redistribute_create,
1381 .cbs.delete = ripd_instance_redistribute_delete,
908f0020
RW
1382 .cbs.apply_finish = ripd_instance_redistribute_apply_finish,
1383 .cbs.cli_show = cli_show_rip_redistribute,
707656ec
RW
1384 },
1385 {
1386 .xpath = "/frr-ripd:ripd/instance/redistribute/route-map",
1387 .cbs.modify = ripd_instance_redistribute_route_map_modify,
1388 .cbs.delete = ripd_instance_redistribute_route_map_delete,
1389 },
1390 {
1391 .xpath = "/frr-ripd:ripd/instance/redistribute/metric",
1392 .cbs.modify = ripd_instance_redistribute_metric_modify,
1393 .cbs.delete = ripd_instance_redistribute_metric_delete,
1394 },
1395 {
1396 .xpath = "/frr-ripd:ripd/instance/static-route",
1397 .cbs.create = ripd_instance_static_route_create,
1398 .cbs.delete = ripd_instance_static_route_delete,
40687878 1399 .cbs.cli_show = cli_show_rip_route,
707656ec 1400 },
b745780b
RW
1401 {
1402 .xpath = "/frr-ripd:ripd/instance/timers",
1403 .cbs.apply_finish = ripd_instance_timers_apply_finish,
1404 .cbs.cli_show = cli_show_rip_timers,
1405 },
707656ec
RW
1406 {
1407 .xpath = "/frr-ripd:ripd/instance/timers/flush-interval",
1408 .cbs.modify = ripd_instance_timers_flush_interval_modify,
1409 },
1410 {
1411 .xpath = "/frr-ripd:ripd/instance/timers/holddown-interval",
1412 .cbs.modify = ripd_instance_timers_holddown_interval_modify,
1413 },
1414 {
1415 .xpath = "/frr-ripd:ripd/instance/timers/update-interval",
1416 .cbs.modify = ripd_instance_timers_update_interval_modify,
1417 },
90eff9da
RW
1418 {
1419 .xpath = "/frr-ripd:ripd/instance/version",
1420 .cbs.cli_show = cli_show_rip_version,
1421 },
707656ec
RW
1422 {
1423 .xpath = "/frr-ripd:ripd/instance/version/receive",
1424 .cbs.modify = ripd_instance_version_receive_modify,
1425 },
1426 {
1427 .xpath = "/frr-ripd:ripd/instance/version/send",
1428 .cbs.modify = ripd_instance_version_send_modify,
1429 },
1430 {
1431 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/split-horizon",
1432 .cbs.modify = lib_interface_rip_split_horizon_modify,
94b117b2 1433 .cbs.cli_show = cli_show_ip_rip_split_horizon,
707656ec
RW
1434 },
1435 {
1436 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/v2-broadcast",
1437 .cbs.modify = lib_interface_rip_v2_broadcast_modify,
94b117b2 1438 .cbs.cli_show = cli_show_ip_rip_v2_broadcast,
707656ec
RW
1439 },
1440 {
1441 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/version-receive",
1442 .cbs.modify = lib_interface_rip_version_receive_modify,
94b117b2 1443 .cbs.cli_show = cli_show_ip_rip_receive_version,
707656ec
RW
1444 },
1445 {
1446 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/version-send",
1447 .cbs.modify = lib_interface_rip_version_send_modify,
94b117b2
RW
1448 .cbs.cli_show = cli_show_ip_rip_send_version,
1449 },
1450 {
1451 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme",
1452 .cbs.cli_show = cli_show_ip_rip_authentication_scheme,
707656ec
RW
1453 },
1454 {
1455 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/mode",
1456 .cbs.modify = lib_interface_rip_authentication_scheme_mode_modify,
1457 },
1458 {
1459 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/md5-auth-length",
1460 .cbs.modify = lib_interface_rip_authentication_scheme_md5_auth_length_modify,
1461 .cbs.delete = lib_interface_rip_authentication_scheme_md5_auth_length_delete,
1462 },
1463 {
1464 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-password",
1465 .cbs.modify = lib_interface_rip_authentication_password_modify,
1466 .cbs.delete = lib_interface_rip_authentication_password_delete,
94b117b2 1467 .cbs.cli_show = cli_show_ip_rip_authentication_string,
707656ec
RW
1468 },
1469 {
1470 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain",
1471 .cbs.modify = lib_interface_rip_authentication_key_chain_modify,
1472 .cbs.delete = lib_interface_rip_authentication_key_chain_delete,
94b117b2 1473 .cbs.cli_show = cli_show_ip_rip_authentication_key_chain,
707656ec
RW
1474 },
1475 {
1476 .xpath = "/frr-ripd:ripd/state/neighbors/neighbor",
1477 .cbs.get_next = ripd_state_neighbors_neighbor_get_next,
1478 .cbs.get_keys = ripd_state_neighbors_neighbor_get_keys,
1479 .cbs.lookup_entry = ripd_state_neighbors_neighbor_lookup_entry,
1480 },
1481 {
1482 .xpath = "/frr-ripd:ripd/state/neighbors/neighbor/address",
1483 .cbs.get_elem = ripd_state_neighbors_neighbor_address_get_elem,
1484 },
1485 {
1486 .xpath = "/frr-ripd:ripd/state/neighbors/neighbor/last-update",
1487 .cbs.get_elem = ripd_state_neighbors_neighbor_last_update_get_elem,
1488 },
1489 {
1490 .xpath = "/frr-ripd:ripd/state/neighbors/neighbor/bad-packets-rcvd",
1491 .cbs.get_elem = ripd_state_neighbors_neighbor_bad_packets_rcvd_get_elem,
1492 },
1493 {
1494 .xpath = "/frr-ripd:ripd/state/neighbors/neighbor/bad-routes-rcvd",
1495 .cbs.get_elem = ripd_state_neighbors_neighbor_bad_routes_rcvd_get_elem,
1496 },
1497 {
1498 .xpath = "/frr-ripd:ripd/state/routes/route",
1499 .cbs.get_next = ripd_state_routes_route_get_next,
1500 .cbs.get_keys = ripd_state_routes_route_get_keys,
1501 .cbs.lookup_entry = ripd_state_routes_route_lookup_entry,
1502 },
1503 {
1504 .xpath = "/frr-ripd:ripd/state/routes/route/prefix",
1505 .cbs.get_elem = ripd_state_routes_route_prefix_get_elem,
1506 },
1507 {
1508 .xpath = "/frr-ripd:ripd/state/routes/route/next-hop",
1509 .cbs.get_elem = ripd_state_routes_route_next_hop_get_elem,
1510 },
1511 {
1512 .xpath = "/frr-ripd:ripd/state/routes/route/interface",
1513 .cbs.get_elem = ripd_state_routes_route_interface_get_elem,
1514 },
1515 {
1516 .xpath = "/frr-ripd:ripd/state/routes/route/metric",
1517 .cbs.get_elem = ripd_state_routes_route_metric_get_elem,
1518 },
1519 {
1520 .xpath = "/frr-ripd:clear-rip-route",
1521 .cbs.rpc = clear_rip_route_rpc,
1522 },
1523 {
1524 .xpath = NULL,
1525 },
1526 }
1527};