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