]> git.proxmox.com Git - mirror_frr.git/blame - ripd/rip_northbound.c
lib, tests: major rework in the operational-data callbacks
[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 *
1a4bc045 1006ripd_state_neighbors_neighbor_get_next(const void *parent_list_entry,
707656ec
RW
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;
80243aef
RW
1026 (void)inet_ntop(AF_INET, &peer->addr, keys->key[0],
1027 sizeof(keys->key[0]));
5c1a8497 1028
707656ec
RW
1029 return NB_OK;
1030}
1031
1032static const void *
1a4bc045
RW
1033ripd_state_neighbors_neighbor_lookup_entry(const void *parent_list_entry,
1034 const struct yang_list_keys *keys)
707656ec 1035{
5c1a8497
RW
1036 struct in_addr address;
1037
80243aef 1038 yang_str2ipv4(keys->key[0], &address);
5c1a8497
RW
1039
1040 return rip_peer_lookup(&address);
707656ec
RW
1041}
1042
1043/*
1044 * XPath: /frr-ripd:ripd/state/neighbors/neighbor/address
1045 */
1046static struct yang_data *
1047ripd_state_neighbors_neighbor_address_get_elem(const char *xpath,
1048 const void *list_entry)
1049{
5c1a8497
RW
1050 const struct rip_peer *peer = list_entry;
1051
1052 return yang_data_new_ipv4(xpath, &peer->addr);
707656ec
RW
1053}
1054
1055/*
1056 * XPath: /frr-ripd:ripd/state/neighbors/neighbor/last-update
1057 */
1058static struct yang_data *
1059ripd_state_neighbors_neighbor_last_update_get_elem(const char *xpath,
1060 const void *list_entry)
1061{
5c1a8497 1062 /* TODO: yang:date-and-time is tricky */
707656ec
RW
1063 return NULL;
1064}
1065
1066/*
1067 * XPath: /frr-ripd:ripd/state/neighbors/neighbor/bad-packets-rcvd
1068 */
1069static struct yang_data *
1070ripd_state_neighbors_neighbor_bad_packets_rcvd_get_elem(const char *xpath,
1071 const void *list_entry)
1072{
5c1a8497
RW
1073 const struct rip_peer *peer = list_entry;
1074
1075 return yang_data_new_uint32(xpath, peer->recv_badpackets);
707656ec
RW
1076}
1077
1078/*
1079 * XPath: /frr-ripd:ripd/state/neighbors/neighbor/bad-routes-rcvd
1080 */
1081static struct yang_data *
1082ripd_state_neighbors_neighbor_bad_routes_rcvd_get_elem(const char *xpath,
1083 const void *list_entry)
1084{
5c1a8497
RW
1085 const struct rip_peer *peer = list_entry;
1086
1087 return yang_data_new_uint32(xpath, peer->recv_badroutes);
707656ec
RW
1088}
1089
1090/*
1091 * XPath: /frr-ripd:ripd/state/routes/route
1092 */
1a4bc045
RW
1093static const void *
1094ripd_state_routes_route_get_next(const void *parent_list_entry,
1095 const void *list_entry)
707656ec 1096{
6270ce38
RW
1097 struct route_node *rn;
1098
1099 if (rip == NULL)
1100 return NULL;
1101
1102 if (list_entry == NULL)
1103 rn = route_top(rip->table);
1104 else
1105 rn = route_next((struct route_node *)list_entry);
1106 while (rn && rn->info == NULL)
1107 rn = route_next(rn);
1108
1109 return rn;
707656ec
RW
1110}
1111
1112static int ripd_state_routes_route_get_keys(const void *list_entry,
1113 struct yang_list_keys *keys)
1114{
6270ce38
RW
1115 const struct route_node *rn = list_entry;
1116
1117 keys->num = 1;
80243aef 1118 (void)prefix2str(&rn->p, keys->key[0], sizeof(keys->key[0]));
6270ce38 1119
707656ec
RW
1120 return NB_OK;
1121}
1122
1123static const void *
1a4bc045
RW
1124ripd_state_routes_route_lookup_entry(const void *parent_list_entry,
1125 const struct yang_list_keys *keys)
707656ec 1126{
6270ce38
RW
1127 struct prefix prefix;
1128 struct route_node *rn;
1129
80243aef 1130 yang_str2ipv4p(keys->key[0], &prefix);
6270ce38
RW
1131
1132 rn = route_node_lookup(rip->table, &prefix);
1133 if (!rn || !rn->info)
1134 return NULL;
1135
1136 route_unlock_node(rn);
1137
1138 /*
1139 * TODO: we need to handle ECMP properly.
1140 */
1141 return listnode_head(rn->info);
707656ec
RW
1142}
1143
1144/*
1145 * XPath: /frr-ripd:ripd/state/routes/route/prefix
1146 */
1147static struct yang_data *
1148ripd_state_routes_route_prefix_get_elem(const char *xpath,
1149 const void *list_entry)
1150{
6270ce38
RW
1151 const struct rip_info *rinfo = list_entry;
1152
1153 return yang_data_new_ipv4p(xpath, &rinfo->rp->p);
707656ec
RW
1154}
1155
1156/*
1157 * XPath: /frr-ripd:ripd/state/routes/route/next-hop
1158 */
1159static struct yang_data *
1160ripd_state_routes_route_next_hop_get_elem(const char *xpath,
1161 const void *list_entry)
1162{
6270ce38
RW
1163 const struct rip_info *rinfo = list_entry;
1164
1165 switch (rinfo->nh.type) {
1166 case NEXTHOP_TYPE_IPV4:
1167 case NEXTHOP_TYPE_IPV4_IFINDEX:
1168 return yang_data_new_ipv4(xpath, &rinfo->nh.gate.ipv4);
1169 default:
1170 return NULL;
1171 }
707656ec
RW
1172}
1173
1174/*
1175 * XPath: /frr-ripd:ripd/state/routes/route/interface
1176 */
1177static struct yang_data *
1178ripd_state_routes_route_interface_get_elem(const char *xpath,
1179 const void *list_entry)
1180{
6270ce38
RW
1181 const struct rip_info *rinfo = list_entry;
1182
1183 switch (rinfo->nh.type) {
1184 case NEXTHOP_TYPE_IFINDEX:
1185 case NEXTHOP_TYPE_IPV4_IFINDEX:
1186 return yang_data_new_string(
1187 xpath, ifindex2ifname(rinfo->nh.ifindex, VRF_DEFAULT));
1188 default:
1189 return NULL;
1190 }
707656ec
RW
1191}
1192
1193/*
1194 * XPath: /frr-ripd:ripd/state/routes/route/metric
1195 */
1196static struct yang_data *
1197ripd_state_routes_route_metric_get_elem(const char *xpath,
1198 const void *list_entry)
1199{
6270ce38
RW
1200 const struct rip_info *rinfo = list_entry;
1201
1202 return yang_data_new_uint8(xpath, rinfo->metric);
707656ec
RW
1203}
1204
1205/*
1206 * XPath: /frr-ripd:clear-rip-route
1207 */
1208static int clear_rip_route_rpc(const char *xpath, const struct list *input,
1209 struct list *output)
1210{
1137aef4
RW
1211 struct route_node *rp;
1212 struct rip_info *rinfo;
1213 struct list *list;
1214 struct listnode *listnode;
1215
1216 /* Clear received RIP routes */
1217 for (rp = route_top(rip->table); rp; rp = route_next(rp)) {
1218 list = rp->info;
1219 if (!list)
1220 continue;
1221
1222 for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
1223 if (!rip_route_rte(rinfo))
1224 continue;
1225
1226 if (CHECK_FLAG(rinfo->flags, RIP_RTF_FIB))
1227 rip_zebra_ipv4_delete(rp);
1228 break;
1229 }
1230
1231 if (rinfo) {
1232 RIP_TIMER_OFF(rinfo->t_timeout);
1233 RIP_TIMER_OFF(rinfo->t_garbage_collect);
1234 listnode_delete(list, rinfo);
1235 rip_info_free(rinfo);
1236 }
1237
1238 if (list_isempty(list)) {
1239 list_delete(&list);
1240 rp->info = NULL;
1241 route_unlock_node(rp);
1242 }
1243 }
1244
707656ec
RW
1245 return NB_OK;
1246}
1247
fe339c95
RW
1248/*
1249 * XPath: /frr-ripd:authentication-type-failure
1250 */
1251void ripd_notif_send_auth_type_failure(const char *ifname)
1252{
1253 const char *xpath = "/frr-ripd:authentication-type-failure";
1254 struct list *arguments;
1255 char xpath_arg[XPATH_MAXLEN];
1256 struct yang_data *data;
1257
1258 arguments = yang_data_list_new();
1259
1260 snprintf(xpath_arg, sizeof(xpath_arg), "%s/interface-name", xpath);
1261 data = yang_data_new_string(xpath_arg, ifname);
1262 listnode_add(arguments, data);
1263
1264 nb_notification_send(xpath, arguments);
1265}
1266
1267/*
1268 * XPath: /frr-ripd:authentication-failure
1269 */
1270void ripd_notif_send_auth_failure(const char *ifname)
1271{
1272 const char *xpath = "/frr-ripd:authentication-failure";
1273 struct list *arguments;
1274 char xpath_arg[XPATH_MAXLEN];
1275 struct yang_data *data;
1276
1277 arguments = yang_data_list_new();
1278
1279 snprintf(xpath_arg, sizeof(xpath_arg), "%s/interface-name", xpath);
1280 data = yang_data_new_string(xpath_arg, ifname);
1281 listnode_add(arguments, data);
1282
1283 nb_notification_send(xpath, arguments);
1284}
1285
707656ec
RW
1286/* clang-format off */
1287const struct frr_yang_module_info frr_ripd_info = {
1288 .name = "frr-ripd",
1289 .nodes = {
1290 {
1291 .xpath = "/frr-ripd:ripd/instance",
1292 .cbs.create = ripd_instance_create,
1293 .cbs.delete = ripd_instance_delete,
8c9226c2 1294 .cbs.cli_show = cli_show_router_rip,
707656ec
RW
1295 },
1296 {
1297 .xpath = "/frr-ripd:ripd/instance/allow-ecmp",
1298 .cbs.modify = ripd_instance_allow_ecmp_modify,
edbf59d2 1299 .cbs.cli_show = cli_show_rip_allow_ecmp,
707656ec
RW
1300 },
1301 {
1302 .xpath = "/frr-ripd:ripd/instance/default-information-originate",
1303 .cbs.modify = ripd_instance_default_information_originate_modify,
0b0609ba 1304 .cbs.cli_show = cli_show_rip_default_information_originate,
707656ec
RW
1305 },
1306 {
1307 .xpath = "/frr-ripd:ripd/instance/default-metric",
1308 .cbs.modify = ripd_instance_default_metric_modify,
282ae30c 1309 .cbs.cli_show = cli_show_rip_default_metric,
707656ec
RW
1310 },
1311 {
1312 .xpath = "/frr-ripd:ripd/instance/distance/default",
1313 .cbs.modify = ripd_instance_distance_default_modify,
7f8a9cba 1314 .cbs.cli_show = cli_show_rip_distance,
707656ec
RW
1315 },
1316 {
1317 .xpath = "/frr-ripd:ripd/instance/distance/source",
1318 .cbs.create = ripd_instance_distance_source_create,
1319 .cbs.delete = ripd_instance_distance_source_delete,
23b23d8c 1320 .cbs.cli_show = cli_show_rip_distance_source,
707656ec
RW
1321 },
1322 {
1323 .xpath = "/frr-ripd:ripd/instance/distance/source/distance",
1324 .cbs.modify = ripd_instance_distance_source_distance_modify,
1325 },
1326 {
1327 .xpath = "/frr-ripd:ripd/instance/distance/source/access-list",
1328 .cbs.modify = ripd_instance_distance_source_access_list_modify,
1329 .cbs.delete = ripd_instance_distance_source_access_list_delete,
1330 },
1331 {
1332 .xpath = "/frr-ripd:ripd/instance/explicit-neighbor",
1333 .cbs.create = ripd_instance_explicit_neighbor_create,
1334 .cbs.delete = ripd_instance_explicit_neighbor_delete,
f0ab22fb 1335 .cbs.cli_show = cli_show_rip_neighbor,
707656ec
RW
1336 },
1337 {
1338 .xpath = "/frr-ripd:ripd/instance/network",
1339 .cbs.create = ripd_instance_network_create,
1340 .cbs.delete = ripd_instance_network_delete,
3d7a1be8 1341 .cbs.cli_show = cli_show_rip_network_prefix,
707656ec
RW
1342 },
1343 {
1344 .xpath = "/frr-ripd:ripd/instance/interface",
1345 .cbs.create = ripd_instance_interface_create,
1346 .cbs.delete = ripd_instance_interface_delete,
3d7a1be8 1347 .cbs.cli_show = cli_show_rip_network_interface,
707656ec
RW
1348 },
1349 {
1350 .xpath = "/frr-ripd:ripd/instance/offset-list",
1351 .cbs.create = ripd_instance_offset_list_create,
1352 .cbs.delete = ripd_instance_offset_list_delete,
8c942f65 1353 .cbs.cli_show = cli_show_rip_offset_list,
707656ec
RW
1354 },
1355 {
1356 .xpath = "/frr-ripd:ripd/instance/offset-list/access-list",
1357 .cbs.modify = ripd_instance_offset_list_access_list_modify,
1358 },
1359 {
1360 .xpath = "/frr-ripd:ripd/instance/offset-list/metric",
1361 .cbs.modify = ripd_instance_offset_list_metric_modify,
1362 },
1363 {
1364 .xpath = "/frr-ripd:ripd/instance/passive-default",
1365 .cbs.modify = ripd_instance_passive_default_modify,
44f2f852 1366 .cbs.cli_show = cli_show_rip_passive_default,
707656ec
RW
1367 },
1368 {
1369 .xpath = "/frr-ripd:ripd/instance/passive-interface",
1370 .cbs.create = ripd_instance_passive_interface_create,
1371 .cbs.delete = ripd_instance_passive_interface_delete,
44f2f852 1372 .cbs.cli_show = cli_show_rip_passive_interface,
707656ec
RW
1373 },
1374 {
1375 .xpath = "/frr-ripd:ripd/instance/non-passive-interface",
1376 .cbs.create = ripd_instance_non_passive_interface_create,
1377 .cbs.delete = ripd_instance_non_passive_interface_delete,
44f2f852 1378 .cbs.cli_show = cli_show_rip_non_passive_interface,
707656ec
RW
1379 },
1380 {
1381 .xpath = "/frr-ripd:ripd/instance/redistribute",
1382 .cbs.create = ripd_instance_redistribute_create,
1383 .cbs.delete = ripd_instance_redistribute_delete,
908f0020
RW
1384 .cbs.apply_finish = ripd_instance_redistribute_apply_finish,
1385 .cbs.cli_show = cli_show_rip_redistribute,
707656ec
RW
1386 },
1387 {
1388 .xpath = "/frr-ripd:ripd/instance/redistribute/route-map",
1389 .cbs.modify = ripd_instance_redistribute_route_map_modify,
1390 .cbs.delete = ripd_instance_redistribute_route_map_delete,
1391 },
1392 {
1393 .xpath = "/frr-ripd:ripd/instance/redistribute/metric",
1394 .cbs.modify = ripd_instance_redistribute_metric_modify,
1395 .cbs.delete = ripd_instance_redistribute_metric_delete,
1396 },
1397 {
1398 .xpath = "/frr-ripd:ripd/instance/static-route",
1399 .cbs.create = ripd_instance_static_route_create,
1400 .cbs.delete = ripd_instance_static_route_delete,
40687878 1401 .cbs.cli_show = cli_show_rip_route,
707656ec 1402 },
b745780b
RW
1403 {
1404 .xpath = "/frr-ripd:ripd/instance/timers",
1405 .cbs.apply_finish = ripd_instance_timers_apply_finish,
1406 .cbs.cli_show = cli_show_rip_timers,
1407 },
707656ec
RW
1408 {
1409 .xpath = "/frr-ripd:ripd/instance/timers/flush-interval",
1410 .cbs.modify = ripd_instance_timers_flush_interval_modify,
1411 },
1412 {
1413 .xpath = "/frr-ripd:ripd/instance/timers/holddown-interval",
1414 .cbs.modify = ripd_instance_timers_holddown_interval_modify,
1415 },
1416 {
1417 .xpath = "/frr-ripd:ripd/instance/timers/update-interval",
1418 .cbs.modify = ripd_instance_timers_update_interval_modify,
1419 },
90eff9da
RW
1420 {
1421 .xpath = "/frr-ripd:ripd/instance/version",
1422 .cbs.cli_show = cli_show_rip_version,
1423 },
707656ec
RW
1424 {
1425 .xpath = "/frr-ripd:ripd/instance/version/receive",
1426 .cbs.modify = ripd_instance_version_receive_modify,
1427 },
1428 {
1429 .xpath = "/frr-ripd:ripd/instance/version/send",
1430 .cbs.modify = ripd_instance_version_send_modify,
1431 },
1432 {
1433 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/split-horizon",
1434 .cbs.modify = lib_interface_rip_split_horizon_modify,
94b117b2 1435 .cbs.cli_show = cli_show_ip_rip_split_horizon,
707656ec
RW
1436 },
1437 {
1438 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/v2-broadcast",
1439 .cbs.modify = lib_interface_rip_v2_broadcast_modify,
94b117b2 1440 .cbs.cli_show = cli_show_ip_rip_v2_broadcast,
707656ec
RW
1441 },
1442 {
1443 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/version-receive",
1444 .cbs.modify = lib_interface_rip_version_receive_modify,
94b117b2 1445 .cbs.cli_show = cli_show_ip_rip_receive_version,
707656ec
RW
1446 },
1447 {
1448 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/version-send",
1449 .cbs.modify = lib_interface_rip_version_send_modify,
94b117b2
RW
1450 .cbs.cli_show = cli_show_ip_rip_send_version,
1451 },
1452 {
1453 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme",
1454 .cbs.cli_show = cli_show_ip_rip_authentication_scheme,
707656ec
RW
1455 },
1456 {
1457 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/mode",
1458 .cbs.modify = lib_interface_rip_authentication_scheme_mode_modify,
1459 },
1460 {
1461 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/md5-auth-length",
1462 .cbs.modify = lib_interface_rip_authentication_scheme_md5_auth_length_modify,
1463 .cbs.delete = lib_interface_rip_authentication_scheme_md5_auth_length_delete,
1464 },
1465 {
1466 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-password",
1467 .cbs.modify = lib_interface_rip_authentication_password_modify,
1468 .cbs.delete = lib_interface_rip_authentication_password_delete,
94b117b2 1469 .cbs.cli_show = cli_show_ip_rip_authentication_string,
707656ec
RW
1470 },
1471 {
1472 .xpath = "/frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain",
1473 .cbs.modify = lib_interface_rip_authentication_key_chain_modify,
1474 .cbs.delete = lib_interface_rip_authentication_key_chain_delete,
94b117b2 1475 .cbs.cli_show = cli_show_ip_rip_authentication_key_chain,
707656ec
RW
1476 },
1477 {
1478 .xpath = "/frr-ripd:ripd/state/neighbors/neighbor",
1479 .cbs.get_next = ripd_state_neighbors_neighbor_get_next,
1480 .cbs.get_keys = ripd_state_neighbors_neighbor_get_keys,
1481 .cbs.lookup_entry = ripd_state_neighbors_neighbor_lookup_entry,
1482 },
1483 {
1484 .xpath = "/frr-ripd:ripd/state/neighbors/neighbor/address",
1485 .cbs.get_elem = ripd_state_neighbors_neighbor_address_get_elem,
1486 },
1487 {
1488 .xpath = "/frr-ripd:ripd/state/neighbors/neighbor/last-update",
1489 .cbs.get_elem = ripd_state_neighbors_neighbor_last_update_get_elem,
1490 },
1491 {
1492 .xpath = "/frr-ripd:ripd/state/neighbors/neighbor/bad-packets-rcvd",
1493 .cbs.get_elem = ripd_state_neighbors_neighbor_bad_packets_rcvd_get_elem,
1494 },
1495 {
1496 .xpath = "/frr-ripd:ripd/state/neighbors/neighbor/bad-routes-rcvd",
1497 .cbs.get_elem = ripd_state_neighbors_neighbor_bad_routes_rcvd_get_elem,
1498 },
1499 {
1500 .xpath = "/frr-ripd:ripd/state/routes/route",
1501 .cbs.get_next = ripd_state_routes_route_get_next,
1502 .cbs.get_keys = ripd_state_routes_route_get_keys,
1503 .cbs.lookup_entry = ripd_state_routes_route_lookup_entry,
1504 },
1505 {
1506 .xpath = "/frr-ripd:ripd/state/routes/route/prefix",
1507 .cbs.get_elem = ripd_state_routes_route_prefix_get_elem,
1508 },
1509 {
1510 .xpath = "/frr-ripd:ripd/state/routes/route/next-hop",
1511 .cbs.get_elem = ripd_state_routes_route_next_hop_get_elem,
1512 },
1513 {
1514 .xpath = "/frr-ripd:ripd/state/routes/route/interface",
1515 .cbs.get_elem = ripd_state_routes_route_interface_get_elem,
1516 },
1517 {
1518 .xpath = "/frr-ripd:ripd/state/routes/route/metric",
1519 .cbs.get_elem = ripd_state_routes_route_metric_get_elem,
1520 },
1521 {
1522 .xpath = "/frr-ripd:clear-rip-route",
1523 .cbs.rpc = clear_rip_route_rpc,
1524 },
1525 {
1526 .xpath = NULL,
1527 },
1528 }
1529};