]> git.proxmox.com Git - mirror_frr.git/blame - eigrpd/eigrp_northbound.c
eigrpd: Add vrf_id to `struct eigrp`
[mirror_frr.git] / eigrpd / eigrp_northbound.c
CommitLineData
f25c244b
RZ
1/*
2 * EIGRP daemon northbound implementation.
3 *
4 * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
5 * Rafael Zalamena
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301 USA.
21 */
22
23#include <zebra.h>
24
25#include "lib/keychain.h"
26#include "lib/log.h"
27#include "lib/northbound.h"
28#include "lib/table.h"
29#include "lib/vrf.h"
30#include "lib/zclient.h"
31
32#include "eigrp_structs.h"
33#include "eigrpd.h"
34#include "eigrp_interface.h"
35#include "eigrp_network.h"
36#include "eigrp_zebra.h"
37
38/* Helper functions. */
39static void redistribute_get_metrics(const struct lyd_node *dnode,
40 struct eigrp_metrics *em)
41{
42 memset(em, 0, sizeof(*em));
43
44 if (yang_dnode_exists(dnode, "./bandwidth"))
45 em->bandwidth = yang_dnode_get_uint32(dnode, "./bandwidth");
46 if (yang_dnode_exists(dnode, "./delay"))
47 em->delay = yang_dnode_get_uint32(dnode, "./delay");
48#if 0 /* TODO: How does MTU work? */
49 if (yang_dnode_exists(dnode, "./mtu"))
50 em->mtu[0] = yang_dnode_get_uint32(dnode, "./mtu");
51#endif
52 if (yang_dnode_exists(dnode, "./load"))
53 em->load = yang_dnode_get_uint32(dnode, "./load");
54 if (yang_dnode_exists(dnode, "./reliability"))
55 em->reliability = yang_dnode_get_uint32(dnode, "./reliability");
56}
57
58static struct eigrp_interface *eigrp_interface_lookup(const struct eigrp *eigrp,
59 const char *ifname)
60{
61 struct eigrp_interface *eif;
62 struct listnode *ln;
63
64 for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, ln, eif)) {
65 if (strcmp(ifname, eif->ifp->name))
66 continue;
67
68 return eif;
69 }
70
71 return NULL;
72}
73
74/*
75 * XPath: /frr-eigrpd:eigrpd/instance
76 */
77static int eigrpd_instance_create(enum nb_event event,
78 const struct lyd_node *dnode,
79 union nb_resource *resource)
80{
81 struct eigrp *eigrp;
82
83 switch (event) {
84 case NB_EV_VALIDATE:
85 /* NOTHING */
86 break;
87 case NB_EV_PREPARE:
c371cd6b
DS
88 eigrp = eigrp_get(yang_dnode_get_string(dnode, "./asn"),
89 VRF_DEFAULT);
f25c244b
RZ
90 resource->ptr = eigrp;
91 break;
92 case NB_EV_ABORT:
93 eigrp_finish_final(resource->ptr);
94 break;
95 case NB_EV_APPLY:
96 nb_running_set_entry(dnode, resource->ptr);
97 break;
98 }
99
100 return NB_OK;
101}
102
103static int eigrpd_instance_destroy(enum nb_event event,
104 const struct lyd_node *dnode)
105{
106 struct eigrp *eigrp;
107
108 switch (event) {
109 case NB_EV_VALIDATE:
110 case NB_EV_PREPARE:
111 case NB_EV_ABORT:
112 /* NOTHING */
113 break;
114 case NB_EV_APPLY:
115 eigrp = nb_running_unset_entry(dnode);
116 eigrp_finish_final(eigrp);
117 break;
118 }
119
120 return NB_OK;
121}
122
123/*
124 * XPath: /frr-eigrpd:eigrpd/instance/router-id
125 */
126static int eigrpd_instance_router_id_modify(enum nb_event event,
127 const struct lyd_node *dnode,
128 union nb_resource *resource)
129{
130 struct eigrp *eigrp;
131
132 switch (event) {
133 case NB_EV_VALIDATE:
134 case NB_EV_PREPARE:
135 case NB_EV_ABORT:
136 /* NOTHING */
137 break;
138 case NB_EV_APPLY:
139 eigrp = nb_running_get_entry(dnode, NULL, true);
140 yang_dnode_get_ipv4(&eigrp->router_id_static, dnode, NULL);
141 break;
142 }
143
144 return NB_OK;
145}
146
147static int eigrpd_instance_router_id_destroy(enum nb_event event,
148 const struct lyd_node *dnode)
149{
150 struct eigrp *eigrp;
151
152 switch (event) {
153 case NB_EV_VALIDATE:
154 case NB_EV_PREPARE:
155 case NB_EV_ABORT:
156 /* NOTHING */
157 break;
158 case NB_EV_APPLY:
159 eigrp = nb_running_get_entry(dnode, NULL, true);
160 eigrp->router_id_static.s_addr = 0;
161 break;
162 }
163
164 return NB_OK;
165}
166
167/*
168 * XPath: /frr-eigrpd:eigrpd/instance/passive-interface
169 */
170static int
171eigrpd_instance_passive_interface_create(enum nb_event event,
172 const struct lyd_node *dnode,
173 union nb_resource *resource)
174{
175 struct eigrp_interface *eif;
176 struct eigrp *eigrp;
177 const char *ifname;
178
179 switch (event) {
180 case NB_EV_VALIDATE:
181 eigrp = nb_running_get_entry(dnode, NULL, false);
182 if (eigrp == NULL) {
183 /*
184 * XXX: we can't verify if the interface exists
185 * and is active until EIGRP is up.
186 */
187 break;
188 }
189
190 ifname = yang_dnode_get_string(dnode, NULL);
191 eif = eigrp_interface_lookup(eigrp, ifname);
192 if (eif == NULL)
193 return NB_ERR_INCONSISTENCY;
194 break;
195 case NB_EV_PREPARE:
196 case NB_EV_ABORT:
197 /* NOTHING */
198 break;
199 case NB_EV_APPLY:
200 eigrp = nb_running_get_entry(dnode, NULL, true);
201 ifname = yang_dnode_get_string(dnode, NULL);
202 eif = eigrp_interface_lookup(eigrp, ifname);
203 if (eif == NULL)
204 return NB_ERR_INCONSISTENCY;
205
206 eif->params.passive_interface = EIGRP_IF_PASSIVE;
207 break;
208 }
209
210 return NB_OK;
211}
212
213static int
214eigrpd_instance_passive_interface_destroy(enum nb_event event,
215 const struct lyd_node *dnode)
216{
217 struct eigrp_interface *eif;
218 struct eigrp *eigrp;
219 const char *ifname;
220
221 switch (event) {
222 case NB_EV_VALIDATE:
223 case NB_EV_PREPARE:
224 case NB_EV_ABORT:
225 /* NOTHING */
226 break;
227 case NB_EV_APPLY:
228 eigrp = nb_running_get_entry(dnode, NULL, true);
229 ifname = yang_dnode_get_string(dnode, NULL);
230 eif = eigrp_interface_lookup(eigrp, ifname);
231 if (eif == NULL)
232 break;
233
234 eif->params.passive_interface = EIGRP_IF_ACTIVE;
235 break;
236 }
237
238 return NB_OK;
239}
240
241/*
242 * XPath: /frr-eigrpd:eigrpd/instance/active-time
243 */
244static int eigrpd_instance_active_time_modify(enum nb_event event,
245 const struct lyd_node *dnode,
246 union nb_resource *resource)
247{
248 switch (event) {
249 case NB_EV_VALIDATE:
250 /* TODO: Not implemented. */
251 return NB_ERR_INCONSISTENCY;
252 case NB_EV_PREPARE:
253 case NB_EV_ABORT:
254 case NB_EV_APPLY:
255 /* NOTHING */
256 break;
257 }
258
259 return NB_OK;
260}
261
262/*
263 * XPath: /frr-eigrpd:eigrpd/instance/variance
264 */
265static int eigrpd_instance_variance_modify(enum nb_event event,
266 const struct lyd_node *dnode,
267 union nb_resource *resource)
268{
269 struct eigrp *eigrp;
270
271 switch (event) {
272 case NB_EV_VALIDATE:
273 case NB_EV_PREPARE:
274 case NB_EV_ABORT:
275 /* NOTHING */
276 break;
277 case NB_EV_APPLY:
278 eigrp = nb_running_get_entry(dnode, NULL, true);
279 eigrp->variance = yang_dnode_get_uint8(dnode, NULL);
280 break;
281 }
282
283 return NB_OK;
284}
285
286static int eigrpd_instance_variance_destroy(enum nb_event event,
287 const struct lyd_node *dnode)
288{
289 struct eigrp *eigrp;
290
291 switch (event) {
292 case NB_EV_VALIDATE:
293 case NB_EV_PREPARE:
294 case NB_EV_ABORT:
295 /* NOTHING */
296 break;
297 case NB_EV_APPLY:
298 eigrp = nb_running_get_entry(dnode, NULL, true);
299 eigrp->variance = EIGRP_VARIANCE_DEFAULT;
300 break;
301 }
302
303 return NB_OK;
304}
305
306/*
307 * XPath: /frr-eigrpd:eigrpd/instance/maximum-paths
308 */
309static int eigrpd_instance_maximum_paths_modify(enum nb_event event,
310 const struct lyd_node *dnode,
311 union nb_resource *resource)
312{
313 struct eigrp *eigrp;
314
315 switch (event) {
316 case NB_EV_VALIDATE:
317 case NB_EV_PREPARE:
318 case NB_EV_ABORT:
319 /* NOTHING */
320 break;
321 case NB_EV_APPLY:
322 eigrp = nb_running_get_entry(dnode, NULL, true);
323 eigrp->max_paths = yang_dnode_get_uint8(dnode, NULL);
324 break;
325 }
326
327 return NB_OK;
328}
329
330static int eigrpd_instance_maximum_paths_destroy(enum nb_event event,
331 const struct lyd_node *dnode)
332{
333 struct eigrp *eigrp;
334
335 switch (event) {
336 case NB_EV_VALIDATE:
337 case NB_EV_PREPARE:
338 case NB_EV_ABORT:
339 /* NOTHING */
340 break;
341 case NB_EV_APPLY:
342 eigrp = nb_running_get_entry(dnode, NULL, true);
343 eigrp->max_paths = EIGRP_MAX_PATHS_DEFAULT;
344 break;
345 }
346
347 return NB_OK;
348}
349
350/*
351 * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K1
352 */
353static int
354eigrpd_instance_metric_weights_K1_modify(enum nb_event event,
355 const struct lyd_node *dnode,
356 union nb_resource *resource)
357{
358 struct eigrp *eigrp;
359
360 switch (event) {
361 case NB_EV_VALIDATE:
362 case NB_EV_PREPARE:
363 case NB_EV_ABORT:
364 /* NOTHING */
365 break;
366 case NB_EV_APPLY:
367 eigrp = nb_running_get_entry(dnode, NULL, true);
368 eigrp->k_values[0] = yang_dnode_get_uint8(dnode, NULL);
369 break;
370 }
371
372 return NB_OK;
373}
374
375static int
376eigrpd_instance_metric_weights_K1_destroy(enum nb_event event,
377 const struct lyd_node *dnode)
378{
379 struct eigrp *eigrp;
380
381 switch (event) {
382 case NB_EV_VALIDATE:
383 case NB_EV_PREPARE:
384 case NB_EV_ABORT:
385 /* NOTHING */
386 break;
387 case NB_EV_APPLY:
388 eigrp = nb_running_get_entry(dnode, NULL, true);
389 eigrp->k_values[0] = EIGRP_K1_DEFAULT;
390 break;
391 }
392
393 return NB_OK;
394}
395
396/*
397 * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K2
398 */
399static int
400eigrpd_instance_metric_weights_K2_modify(enum nb_event event,
401 const struct lyd_node *dnode,
402 union nb_resource *resource)
403{
404 struct eigrp *eigrp;
405
406 switch (event) {
407 case NB_EV_VALIDATE:
408 case NB_EV_PREPARE:
409 case NB_EV_ABORT:
410 /* NOTHING */
411 break;
412 case NB_EV_APPLY:
413 eigrp = nb_running_get_entry(dnode, NULL, true);
414 eigrp->k_values[1] = yang_dnode_get_uint8(dnode, NULL);
415 break;
416 }
417
418 return NB_OK;
419}
420
421static int
422eigrpd_instance_metric_weights_K2_destroy(enum nb_event event,
423 const struct lyd_node *dnode)
424{
425 struct eigrp *eigrp;
426
427 switch (event) {
428 case NB_EV_VALIDATE:
429 case NB_EV_PREPARE:
430 case NB_EV_ABORT:
431 /* NOTHING */
432 break;
433 case NB_EV_APPLY:
434 eigrp = nb_running_get_entry(dnode, NULL, true);
435 eigrp->k_values[1] = EIGRP_K2_DEFAULT;
436 break;
437 }
438
439 return NB_OK;
440}
441
442/*
443 * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K3
444 */
445static int
446eigrpd_instance_metric_weights_K3_modify(enum nb_event event,
447 const struct lyd_node *dnode,
448 union nb_resource *resource)
449{
450 struct eigrp *eigrp;
451
452 switch (event) {
453 case NB_EV_VALIDATE:
454 case NB_EV_PREPARE:
455 case NB_EV_ABORT:
456 /* NOTHING */
457 break;
458 case NB_EV_APPLY:
459 eigrp = nb_running_get_entry(dnode, NULL, true);
460 eigrp->k_values[2] = yang_dnode_get_uint8(dnode, NULL);
461 break;
462 }
463
464 return NB_OK;
465}
466
467static int
468eigrpd_instance_metric_weights_K3_destroy(enum nb_event event,
469 const struct lyd_node *dnode)
470{
471 struct eigrp *eigrp;
472
473 switch (event) {
474 case NB_EV_VALIDATE:
475 case NB_EV_PREPARE:
476 case NB_EV_ABORT:
477 /* NOTHING */
478 break;
479 case NB_EV_APPLY:
480 eigrp = nb_running_get_entry(dnode, NULL, true);
481 eigrp->k_values[2] = EIGRP_K3_DEFAULT;
482 break;
483 }
484
485 return NB_OK;
486}
487
488/*
489 * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K4
490 */
491static int
492eigrpd_instance_metric_weights_K4_modify(enum nb_event event,
493 const struct lyd_node *dnode,
494 union nb_resource *resource)
495{
496 struct eigrp *eigrp;
497
498 switch (event) {
499 case NB_EV_VALIDATE:
500 case NB_EV_PREPARE:
501 case NB_EV_ABORT:
502 /* NOTHING */
503 break;
504 case NB_EV_APPLY:
505 eigrp = nb_running_get_entry(dnode, NULL, true);
506 eigrp->k_values[3] = yang_dnode_get_uint8(dnode, NULL);
507 break;
508 }
509
510 return NB_OK;
511}
512
513static int
514eigrpd_instance_metric_weights_K4_destroy(enum nb_event event,
515 const struct lyd_node *dnode)
516{
517 struct eigrp *eigrp;
518
519 switch (event) {
520 case NB_EV_VALIDATE:
521 case NB_EV_PREPARE:
522 case NB_EV_ABORT:
523 /* NOTHING */
524 break;
525 case NB_EV_APPLY:
526 eigrp = nb_running_get_entry(dnode, NULL, true);
527 eigrp->k_values[3] = EIGRP_K4_DEFAULT;
528 break;
529 }
530
531 return NB_OK;
532}
533
534/*
535 * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K5
536 */
537static int
538eigrpd_instance_metric_weights_K5_modify(enum nb_event event,
539 const struct lyd_node *dnode,
540 union nb_resource *resource)
541{
542 struct eigrp *eigrp;
543
544 switch (event) {
545 case NB_EV_VALIDATE:
546 case NB_EV_PREPARE:
547 case NB_EV_ABORT:
548 /* NOTHING */
549 break;
550 case NB_EV_APPLY:
551 eigrp = nb_running_get_entry(dnode, NULL, true);
552 eigrp->k_values[4] = yang_dnode_get_uint8(dnode, NULL);
553 break;
554 }
555
556 return NB_OK;
557}
558
559static int
560eigrpd_instance_metric_weights_K5_destroy(enum nb_event event,
561 const struct lyd_node *dnode)
562{
563 struct eigrp *eigrp;
564
565 switch (event) {
566 case NB_EV_VALIDATE:
567 case NB_EV_PREPARE:
568 case NB_EV_ABORT:
569 /* NOTHING */
570 break;
571 case NB_EV_APPLY:
572 eigrp = nb_running_get_entry(dnode, NULL, true);
573 eigrp->k_values[4] = EIGRP_K5_DEFAULT;
574 break;
575 }
576
577 return NB_OK;
578}
579
580/*
581 * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K6
582 */
583static int
584eigrpd_instance_metric_weights_K6_modify(enum nb_event event,
585 const struct lyd_node *dnode,
586 union nb_resource *resource)
587{
588 struct eigrp *eigrp;
589
590 switch (event) {
591 case NB_EV_VALIDATE:
592 case NB_EV_PREPARE:
593 case NB_EV_ABORT:
594 /* NOTHING */
595 break;
596 case NB_EV_APPLY:
597 eigrp = nb_running_get_entry(dnode, NULL, true);
598 eigrp->k_values[5] = yang_dnode_get_uint8(dnode, NULL);
599 break;
600 }
601
602 return NB_OK;
603}
604
605static int
606eigrpd_instance_metric_weights_K6_destroy(enum nb_event event,
607 const struct lyd_node *dnode)
608{
609 struct eigrp *eigrp;
610
611 switch (event) {
612 case NB_EV_VALIDATE:
613 case NB_EV_PREPARE:
614 case NB_EV_ABORT:
615 /* NOTHING */
616 break;
617 case NB_EV_APPLY:
618 eigrp = nb_running_get_entry(dnode, NULL, true);
619 eigrp->k_values[5] = EIGRP_K6_DEFAULT;
620 break;
621 }
622
623 return NB_OK;
624}
625
626/*
627 * XPath: /frr-eigrpd:eigrpd/instance/network
628 */
629static int eigrpd_instance_network_create(enum nb_event event,
630 const struct lyd_node *dnode,
631 union nb_resource *resource)
632{
633 struct route_node *rnode;
634 struct prefix prefix;
635 struct eigrp *eigrp;
636 int exists;
637
638 yang_dnode_get_ipv4p(&prefix, dnode, NULL);
639
640 switch (event) {
641 case NB_EV_VALIDATE:
642 eigrp = nb_running_get_entry(dnode, NULL, false);
643 /* If entry doesn't exist it means the list is empty. */
644 if (eigrp == NULL)
645 break;
646
647 rnode = route_node_get(eigrp->networks, &prefix);
648 exists = (rnode->info != NULL);
649 route_unlock_node(rnode);
650 if (exists)
651 return NB_ERR_INCONSISTENCY;
652 break;
653 case NB_EV_PREPARE:
654 case NB_EV_ABORT:
655 /* NOTHING */
656 break;
657 case NB_EV_APPLY:
658 eigrp = nb_running_get_entry(dnode, NULL, true);
659 if (eigrp_network_set(eigrp, &prefix) == 0)
660 return NB_ERR_INCONSISTENCY;
661 break;
662 }
663
664 return NB_OK;
665}
666
667static int eigrpd_instance_network_destroy(enum nb_event event,
668 const struct lyd_node *dnode)
669{
670 struct route_node *rnode;
671 struct prefix prefix;
672 struct eigrp *eigrp;
673 int exists = 0;
674
675 yang_dnode_get_ipv4p(&prefix, dnode, NULL);
676
677 switch (event) {
678 case NB_EV_VALIDATE:
679 eigrp = nb_running_get_entry(dnode, NULL, false);
680 /* If entry doesn't exist it means the list is empty. */
681 if (eigrp == NULL)
682 break;
683
684 rnode = route_node_get(eigrp->networks, &prefix);
685 exists = (rnode->info != NULL);
686 route_unlock_node(rnode);
687 if (exists == 0)
688 return NB_ERR_INCONSISTENCY;
689 break;
690 case NB_EV_PREPARE:
691 case NB_EV_ABORT:
692 /* NOTHING */
693 break;
694 case NB_EV_APPLY:
695 eigrp = nb_running_get_entry(dnode, NULL, true);
696 eigrp_network_unset(eigrp, &prefix);
697 break;
698 }
699
700 return NB_OK;
701}
702
703/*
704 * XPath: /frr-eigrpd:eigrpd/instance/neighbor
705 */
706static int eigrpd_instance_neighbor_create(enum nb_event event,
707 const struct lyd_node *dnode,
708 union nb_resource *resource)
709{
710 switch (event) {
711 case NB_EV_VALIDATE:
712 /* TODO: Not implemented. */
713 return NB_ERR_INCONSISTENCY;
714 case NB_EV_PREPARE:
715 case NB_EV_ABORT:
716 case NB_EV_APPLY:
717 /* NOTHING */
718 break;
719 }
720
721 return NB_OK;
722}
723
724static int eigrpd_instance_neighbor_destroy(enum nb_event event,
725 const struct lyd_node *dnode)
726{
727 switch (event) {
728 case NB_EV_VALIDATE:
729 /* TODO: Not implemented. */
730 return NB_ERR_INCONSISTENCY;
731 case NB_EV_PREPARE:
732 case NB_EV_ABORT:
733 case NB_EV_APPLY:
734 /* NOTHING */
735 break;
736 }
737
738 return NB_OK;
739}
740
741/*
742 * XPath: /frr-eigrpd:eigrpd/instance/redistribute
743 */
744static int eigrpd_instance_redistribute_create(enum nb_event event,
745 const struct lyd_node *dnode,
746 union nb_resource *resource)
747{
748 struct eigrp_metrics metrics;
749 struct eigrp *eigrp;
750 uint32_t proto;
751
752 switch (event) {
753 case NB_EV_VALIDATE:
754 proto = yang_dnode_get_enum(dnode, "./protocol");
755 if (vrf_bitmap_check(zclient->redist[AFI_IP][proto],
756 VRF_DEFAULT))
757 return NB_ERR_INCONSISTENCY;
758 break;
759 case NB_EV_PREPARE:
760 case NB_EV_ABORT:
761 /* NOTHING */
762 break;
763 case NB_EV_APPLY:
764 eigrp = nb_running_get_entry(dnode, NULL, true);
765 proto = yang_dnode_get_enum(dnode, "./protocol");
766 redistribute_get_metrics(dnode, &metrics);
767 eigrp_redistribute_set(eigrp, proto, metrics);
768 break;
769 }
770
771 return NB_OK;
772}
773
774static int eigrpd_instance_redistribute_destroy(enum nb_event event,
775 const struct lyd_node *dnode)
776{
777 struct eigrp *eigrp;
778 uint32_t proto;
779
780 switch (event) {
781 case NB_EV_VALIDATE:
782 case NB_EV_PREPARE:
783 case NB_EV_ABORT:
784 /* NOTHING */
785 break;
786 case NB_EV_APPLY:
787 eigrp = nb_running_get_entry(dnode, NULL, true);
788 proto = yang_dnode_get_enum(dnode, "./protocol");
789 eigrp_redistribute_unset(eigrp, proto);
790 break;
791 }
792
793 return NB_OK;
794}
795
796/*
797 * XPath: /frr-eigrpd:eigrpd/instance/redistribute/route-map
798 */
799static int
800eigrpd_instance_redistribute_route_map_modify(enum nb_event event,
801 const struct lyd_node *dnode,
802 union nb_resource *resource)
803{
804 switch (event) {
805 case NB_EV_VALIDATE:
806 /* TODO: Not implemented. */
807 return NB_ERR_INCONSISTENCY;
808 case NB_EV_PREPARE:
809 case NB_EV_ABORT:
810 case NB_EV_APPLY:
811 /* NOTHING */
812 break;
813 }
814
815 return NB_OK;
816}
817
818static int
819eigrpd_instance_redistribute_route_map_destroy(enum nb_event event,
820 const struct lyd_node *dnode)
821{
822 switch (event) {
823 case NB_EV_VALIDATE:
824 /* TODO: Not implemented. */
825 return NB_ERR_INCONSISTENCY;
826 case NB_EV_PREPARE:
827 case NB_EV_ABORT:
828 case NB_EV_APPLY:
829 /* NOTHING */
830 break;
831 }
832
833 return NB_OK;
834}
835
836/*
837 * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/bandwidth
838 */
839static int eigrpd_instance_redistribute_metrics_bandwidth_modify(
840 enum nb_event event, const struct lyd_node *dnode,
841 union nb_resource *resource)
842{
843 struct eigrp_metrics metrics;
844 struct eigrp *eigrp;
845 uint32_t proto;
846
847 switch (event) {
848 case NB_EV_VALIDATE:
849 case NB_EV_PREPARE:
850 case NB_EV_ABORT:
851 /* NOTHING */
852 break;
853 case NB_EV_APPLY:
854 eigrp = nb_running_get_entry(dnode, NULL, true);
855 proto = yang_dnode_get_enum(dnode, "../../protocol");
856 redistribute_get_metrics(dnode, &metrics);
857 eigrp_redistribute_set(eigrp, proto, metrics);
858 break;
859 }
860
861 return NB_OK;
862}
863
864static int eigrpd_instance_redistribute_metrics_bandwidth_destroy(
865 enum nb_event event, const struct lyd_node *dnode)
866{
867 struct eigrp_metrics metrics;
868 struct eigrp *eigrp;
869 uint32_t proto;
870
871 switch (event) {
872 case NB_EV_VALIDATE:
873 case NB_EV_PREPARE:
874 case NB_EV_ABORT:
875 /* NOTHING */
876 break;
877 case NB_EV_APPLY:
878 eigrp = nb_running_get_entry(dnode, NULL, true);
879 proto = yang_dnode_get_enum(dnode, "../../protocol");
880 redistribute_get_metrics(dnode, &metrics);
881 eigrp_redistribute_set(eigrp, proto, metrics);
882 break;
883 }
884
885 return NB_OK;
886}
887
888/*
889 * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/delay
890 */
891static int
892eigrpd_instance_redistribute_metrics_delay_modify(enum nb_event event,
893 const struct lyd_node *dnode,
894 union nb_resource *resource)
895{
896 return eigrpd_instance_redistribute_metrics_bandwidth_modify(event,
897 dnode,
898 resource);
899}
900
901static int
902eigrpd_instance_redistribute_metrics_delay_destroy(enum nb_event event,
903 const struct lyd_node *dnode)
904{
905 return eigrpd_instance_redistribute_metrics_bandwidth_destroy(event,
906 dnode);
907}
908
909/*
910 * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/reliability
911 */
912static int eigrpd_instance_redistribute_metrics_reliability_modify(
913 enum nb_event event, const struct lyd_node *dnode,
914 union nb_resource *resource)
915{
916 return eigrpd_instance_redistribute_metrics_bandwidth_modify(event,
917 dnode,
918 resource);
919}
920
921static int eigrpd_instance_redistribute_metrics_reliability_destroy(
922 enum nb_event event, const struct lyd_node *dnode)
923{
924 return eigrpd_instance_redistribute_metrics_bandwidth_destroy(event,
925 dnode);
926}
927
928/*
929 * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/load
930 */
931static int
932eigrpd_instance_redistribute_metrics_load_modify(enum nb_event event,
933 const struct lyd_node *dnode,
934 union nb_resource *resource)
935{
936 return eigrpd_instance_redistribute_metrics_bandwidth_modify(event,
937 dnode,
938 resource);
939}
940
941static int
942eigrpd_instance_redistribute_metrics_load_destroy(enum nb_event event,
943 const struct lyd_node *dnode)
944{
945 return eigrpd_instance_redistribute_metrics_bandwidth_destroy(event,
946 dnode);
947}
948
949/*
950 * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/mtu
951 */
952static int
953eigrpd_instance_redistribute_metrics_mtu_modify(enum nb_event event,
954 const struct lyd_node *dnode,
955 union nb_resource *resource)
956{
957 return eigrpd_instance_redistribute_metrics_bandwidth_modify(event,
958 dnode,
959 resource);
960}
961
962static int
963eigrpd_instance_redistribute_metrics_mtu_destroy(enum nb_event event,
964 const struct lyd_node *dnode)
965{
966 return eigrpd_instance_redistribute_metrics_bandwidth_destroy(event,
967 dnode);
968}
969
970/*
971 * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/delay
972 */
973static int lib_interface_eigrp_delay_modify(enum nb_event event,
974 const struct lyd_node *dnode,
975 union nb_resource *resource)
976{
977 struct eigrp_interface *ei;
978 struct interface *ifp;
979
980 switch (event) {
981 case NB_EV_VALIDATE:
982 ifp = nb_running_get_entry(dnode, NULL, false);
983 if (ifp == NULL) {
984 /*
985 * XXX: we can't verify if the interface exists
986 * and is active until EIGRP is up.
987 */
988 break;
989 }
990
991 ei = ifp->info;
992 if (ei == NULL)
993 return NB_ERR_INCONSISTENCY;
994 break;
995 case NB_EV_PREPARE:
996 case NB_EV_ABORT:
997 /* NOTHING */
998 break;
999 case NB_EV_APPLY:
1000 ifp = nb_running_get_entry(dnode, NULL, true);
1001 ei = ifp->info;
1002 if (ei == NULL)
1003 return NB_ERR_INCONSISTENCY;
1004
1005 ei->params.delay = yang_dnode_get_uint32(dnode, NULL);
1006 eigrp_if_reset(ifp);
1007 break;
1008 }
1009
1010 return NB_OK;
1011}
1012
1013/*
1014 * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/bandwidth
1015 */
1016static int lib_interface_eigrp_bandwidth_modify(enum nb_event event,
1017 const struct lyd_node *dnode,
1018 union nb_resource *resource)
1019{
1020 struct interface *ifp;
1021 struct eigrp_interface *ei;
1022
1023 switch (event) {
1024 case NB_EV_VALIDATE:
1025 ifp = nb_running_get_entry(dnode, NULL, false);
1026 if (ifp == NULL) {
1027 /*
1028 * XXX: we can't verify if the interface exists
1029 * and is active until EIGRP is up.
1030 */
1031 break;
1032 }
1033
1034 ei = ifp->info;
1035 if (ei == NULL)
1036 return NB_ERR_INCONSISTENCY;
1037 break;
1038 case NB_EV_PREPARE:
1039 case NB_EV_ABORT:
1040 /* NOTHING */
1041 break;
1042 case NB_EV_APPLY:
1043 ifp = nb_running_get_entry(dnode, NULL, true);
1044 ei = ifp->info;
1045 if (ei == NULL)
1046 return NB_ERR_INCONSISTENCY;
1047
1048 ei->params.bandwidth = yang_dnode_get_uint32(dnode, NULL);
1049 eigrp_if_reset(ifp);
1050 break;
1051 }
1052
1053 return NB_OK;
1054}
1055
1056/*
1057 * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/hello-interval
1058 */
1059static int
1060lib_interface_eigrp_hello_interval_modify(enum nb_event event,
1061 const struct lyd_node *dnode,
1062 union nb_resource *resource)
1063{
1064 struct interface *ifp;
1065 struct eigrp_interface *ei;
1066
1067 switch (event) {
1068 case NB_EV_VALIDATE:
1069 ifp = nb_running_get_entry(dnode, NULL, false);
1070 if (ifp == NULL) {
1071 /*
1072 * XXX: we can't verify if the interface exists
1073 * and is active until EIGRP is up.
1074 */
1075 break;
1076 }
1077
1078 ei = ifp->info;
1079 if (ei == NULL)
1080 return NB_ERR_INCONSISTENCY;
1081 break;
1082 case NB_EV_PREPARE:
1083 case NB_EV_ABORT:
1084 /* NOTHING */
1085 break;
1086 case NB_EV_APPLY:
1087 ifp = nb_running_get_entry(dnode, NULL, true);
1088 ei = ifp->info;
1089 if (ei == NULL)
1090 return NB_ERR_INCONSISTENCY;
1091
1092 ei->params.v_hello = yang_dnode_get_uint16(dnode, NULL);
1093 break;
1094 }
1095
1096 return NB_OK;
1097}
1098
1099/*
1100 * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/hold-time
1101 */
1102static int lib_interface_eigrp_hold_time_modify(enum nb_event event,
1103 const struct lyd_node *dnode,
1104 union nb_resource *resource)
1105{
1106 struct interface *ifp;
1107 struct eigrp_interface *ei;
1108
1109 switch (event) {
1110 case NB_EV_VALIDATE:
1111 ifp = nb_running_get_entry(dnode, NULL, false);
1112 if (ifp == NULL) {
1113 /*
1114 * XXX: we can't verify if the interface exists
1115 * and is active until EIGRP is up.
1116 */
1117 break;
1118 }
1119
1120 ei = ifp->info;
1121 if (ei == NULL)
1122 return NB_ERR_INCONSISTENCY;
1123 break;
1124 case NB_EV_PREPARE:
1125 case NB_EV_ABORT:
1126 /* NOTHING */
1127 break;
1128 case NB_EV_APPLY:
1129 ifp = nb_running_get_entry(dnode, NULL, true);
1130 ei = ifp->info;
1131 if (ei == NULL)
1132 return NB_ERR_INCONSISTENCY;
1133
1134 ei->params.v_wait = yang_dnode_get_uint16(dnode, NULL);
1135 break;
1136 }
1137
1138 return NB_OK;
1139}
1140
1141/*
1142 * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/split-horizon
1143 */
1144static int
1145lib_interface_eigrp_split_horizon_modify(enum nb_event event,
1146 const struct lyd_node *dnode,
1147 union nb_resource *resource)
1148{
1149 switch (event) {
1150 case NB_EV_VALIDATE:
1151 /* TODO: Not implemented. */
1152 return NB_ERR_INCONSISTENCY;
1153 case NB_EV_PREPARE:
1154 case NB_EV_ABORT:
1155 case NB_EV_APPLY:
1156 /* NOTHING */
1157 break;
1158 }
1159
1160 return NB_OK;
1161}
1162
1163/*
1164 * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance
1165 */
1166static int lib_interface_eigrp_instance_create(enum nb_event event,
1167 const struct lyd_node *dnode,
1168 union nb_resource *resource)
1169{
1170 struct eigrp_interface *eif;
1171 struct interface *ifp;
1172 struct eigrp *eigrp;
1173
1174 switch (event) {
1175 case NB_EV_VALIDATE:
1176 ifp = nb_running_get_entry(dnode, NULL, false);
1177 if (ifp == NULL) {
1178 /*
1179 * XXX: we can't verify if the interface exists
1180 * and is active until EIGRP is up.
1181 */
1182 break;
1183 }
1184
c371cd6b
DS
1185 eigrp = eigrp_get(yang_dnode_get_string(dnode, "./asn"),
1186 VRF_DEFAULT);
f25c244b
RZ
1187 eif = eigrp_interface_lookup(eigrp, ifp->name);
1188 if (eif == NULL)
1189 return NB_ERR_INCONSISTENCY;
1190 break;
1191 case NB_EV_PREPARE:
1192 case NB_EV_ABORT:
1193 /* NOTHING */
1194 break;
1195 case NB_EV_APPLY:
1196 ifp = nb_running_get_entry(dnode, NULL, true);
c371cd6b
DS
1197 eigrp = eigrp_get(yang_dnode_get_string(dnode, "./asn"),
1198 VRF_DEFAULT);
f25c244b
RZ
1199 eif = eigrp_interface_lookup(eigrp, ifp->name);
1200 if (eif == NULL)
1201 return NB_ERR_INCONSISTENCY;
1202
1203 nb_running_set_entry(dnode, eif);
1204 break;
1205 }
1206
1207 return NB_OK;
1208}
1209
1210static int lib_interface_eigrp_instance_destroy(enum nb_event event,
1211 const struct lyd_node *dnode)
1212{
1213 switch (event) {
1214 case NB_EV_VALIDATE:
1215 case NB_EV_PREPARE:
1216 case NB_EV_ABORT:
1217 /* NOTHING */
1218 break;
1219 case NB_EV_APPLY:
1220 nb_running_unset_entry(dnode);
1221 break;
1222 }
1223
1224 return NB_OK;
1225}
1226
1227/*
1228 * XPath:
1229 * /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/summarize-addresses
1230 */
1231static int lib_interface_eigrp_instance_summarize_addresses_create(
1232 enum nb_event event, const struct lyd_node *dnode,
1233 union nb_resource *resource)
1234{
1235 switch (event) {
1236 case NB_EV_VALIDATE:
1237 /* TODO: Not implemented. */
1238 return NB_ERR_INCONSISTENCY;
1239 case NB_EV_PREPARE:
1240 case NB_EV_ABORT:
1241 case NB_EV_APPLY:
1242 /* NOTHING */
1243 break;
1244 }
1245
1246 return NB_OK;
1247}
1248
1249static int lib_interface_eigrp_instance_summarize_addresses_destroy(
1250 enum nb_event event, const struct lyd_node *dnode)
1251{
1252 switch (event) {
1253 case NB_EV_VALIDATE:
1254 /* TODO: Not implemented. */
1255 return NB_ERR_INCONSISTENCY;
1256 case NB_EV_PREPARE:
1257 case NB_EV_ABORT:
1258 case NB_EV_APPLY:
1259 /* NOTHING */
1260 break;
1261 }
1262
1263 return NB_OK;
1264}
1265
1266/*
1267 * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/authentication
1268 */
1269static int
1270lib_interface_eigrp_instance_authentication_modify(enum nb_event event,
1271 const struct lyd_node *dnode,
1272 union nb_resource *resource)
1273{
1274 struct eigrp_interface *eif;
1275
1276 switch (event) {
1277 case NB_EV_VALIDATE:
1278 case NB_EV_PREPARE:
1279 case NB_EV_ABORT:
1280 /* NOTHING */
1281 break;
1282 case NB_EV_APPLY:
1283 eif = nb_running_get_entry(dnode, NULL, true);
1284 eif->params.auth_type = yang_dnode_get_enum(dnode, NULL);
1285 break;
1286 }
1287
1288 return NB_OK;
1289}
1290
1291/*
1292 * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/keychain
1293 */
1294static int
1295lib_interface_eigrp_instance_keychain_modify(enum nb_event event,
1296 const struct lyd_node *dnode,
1297 union nb_resource *resource)
1298{
1299 struct eigrp_interface *eif;
1300 struct keychain *keychain;
1301
1302 switch (event) {
1303 case NB_EV_VALIDATE:
1304 keychain = keychain_lookup(yang_dnode_get_string(dnode, NULL));
1305 if (keychain == NULL)
1306 return NB_ERR_INCONSISTENCY;
1307 break;
1308 case NB_EV_PREPARE:
1309 resource->ptr = strdup(yang_dnode_get_string(dnode, NULL));
1310 if (resource->ptr == NULL)
1311 return NB_ERR_RESOURCE;
1312 break;
1313 case NB_EV_ABORT:
1314 free(resource->ptr);
1315 resource->ptr = NULL;
1316 break;
1317 case NB_EV_APPLY:
1318 eif = nb_running_get_entry(dnode, NULL, true);
1319 if (eif->params.auth_keychain)
1320 free(eif->params.auth_keychain);
1321
1322 eif->params.auth_keychain = resource->ptr;
1323 break;
1324 }
1325
1326 return NB_OK;
1327}
1328
1329static int
1330lib_interface_eigrp_instance_keychain_destroy(enum nb_event event,
1331 const struct lyd_node *dnode)
1332{
1333 struct eigrp_interface *eif;
1334
1335 switch (event) {
1336 case NB_EV_VALIDATE:
1337 case NB_EV_PREPARE:
1338 case NB_EV_ABORT:
1339 /* NOTHING */
1340 break;
1341 case NB_EV_APPLY:
1342 eif = nb_running_get_entry(dnode, NULL, true);
1343 if (eif->params.auth_keychain)
1344 free(eif->params.auth_keychain);
1345
1346 eif->params.auth_keychain = NULL;
1347 break;
1348 }
1349
1350 return NB_OK;
1351}
1352
1353/* clang-format off */
1354const struct frr_yang_module_info frr_eigrpd_info = {
1355 .name = "frr-eigrpd",
1356 .nodes = {
1357 {
1358 .xpath = "/frr-eigrpd:eigrpd/instance",
1359 .cbs = {
1360 .create = eigrpd_instance_create,
1361 .destroy = eigrpd_instance_destroy,
1362 .cli_show = eigrp_cli_show_header,
1363 .cli_show_end = eigrp_cli_show_end_header,
1364 }
1365 },
1366 {
1367 .xpath = "/frr-eigrpd:eigrpd/instance/router-id",
1368 .cbs = {
1369 .modify = eigrpd_instance_router_id_modify,
1370 .destroy = eigrpd_instance_router_id_destroy,
1371 .cli_show = eigrp_cli_show_router_id,
1372 }
1373 },
1374 {
1375 .xpath = "/frr-eigrpd:eigrpd/instance/passive-interface",
1376 .cbs = {
1377 .create = eigrpd_instance_passive_interface_create,
1378 .destroy = eigrpd_instance_passive_interface_destroy,
1379 .cli_show = eigrp_cli_show_passive_interface,
1380 }
1381 },
1382 {
1383 .xpath = "/frr-eigrpd:eigrpd/instance/active-time",
1384 .cbs = {
1385 .modify = eigrpd_instance_active_time_modify,
1386 .cli_show = eigrp_cli_show_active_time,
1387 }
1388 },
1389 {
1390 .xpath = "/frr-eigrpd:eigrpd/instance/variance",
1391 .cbs = {
1392 .modify = eigrpd_instance_variance_modify,
1393 .destroy = eigrpd_instance_variance_destroy,
1394 .cli_show = eigrp_cli_show_variance,
1395 }
1396 },
1397 {
1398 .xpath = "/frr-eigrpd:eigrpd/instance/maximum-paths",
1399 .cbs = {
1400 .modify = eigrpd_instance_maximum_paths_modify,
1401 .destroy = eigrpd_instance_maximum_paths_destroy,
1402 .cli_show = eigrp_cli_show_maximum_paths,
1403 }
1404 },
1405 {
1406 .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights",
1407 .cbs = {
1408 .cli_show = eigrp_cli_show_metrics,
1409 }
1410 },
1411 {
1412 .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K1",
1413 .cbs = {
1414 .modify = eigrpd_instance_metric_weights_K1_modify,
1415 .destroy = eigrpd_instance_metric_weights_K1_destroy,
1416 }
1417 },
1418 {
1419 .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K2",
1420 .cbs = {
1421 .modify = eigrpd_instance_metric_weights_K2_modify,
1422 .destroy = eigrpd_instance_metric_weights_K2_destroy,
1423 }
1424 },
1425 {
1426 .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K3",
1427 .cbs = {
1428 .modify = eigrpd_instance_metric_weights_K3_modify,
1429 .destroy = eigrpd_instance_metric_weights_K3_destroy,
1430 }
1431 },
1432 {
1433 .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K4",
1434 .cbs = {
1435 .modify = eigrpd_instance_metric_weights_K4_modify,
1436 .destroy = eigrpd_instance_metric_weights_K4_destroy,
1437 }
1438 },
1439 {
1440 .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K5",
1441 .cbs = {
1442 .modify = eigrpd_instance_metric_weights_K5_modify,
1443 .destroy = eigrpd_instance_metric_weights_K5_destroy,
1444 }
1445 },
1446 {
1447 .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K6",
1448 .cbs = {
1449 .modify = eigrpd_instance_metric_weights_K6_modify,
1450 .destroy = eigrpd_instance_metric_weights_K6_destroy,
1451 }
1452 },
1453 {
1454 .xpath = "/frr-eigrpd:eigrpd/instance/network",
1455 .cbs = {
1456 .create = eigrpd_instance_network_create,
1457 .destroy = eigrpd_instance_network_destroy,
1458 .cli_show = eigrp_cli_show_network,
1459 }
1460 },
1461 {
1462 .xpath = "/frr-eigrpd:eigrpd/instance/neighbor",
1463 .cbs = {
1464 .create = eigrpd_instance_neighbor_create,
1465 .destroy = eigrpd_instance_neighbor_destroy,
1466 .cli_show = eigrp_cli_show_neighbor,
1467 }
1468 },
1469 {
1470 .xpath = "/frr-eigrpd:eigrpd/instance/redistribute",
1471 .cbs = {
1472 .create = eigrpd_instance_redistribute_create,
1473 .destroy = eigrpd_instance_redistribute_destroy,
1474 .cli_show = eigrp_cli_show_redistribute,
1475 }
1476 },
1477 {
1478 .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/route-map",
1479 .cbs = {
1480 .modify = eigrpd_instance_redistribute_route_map_modify,
1481 .destroy = eigrpd_instance_redistribute_route_map_destroy,
1482 }
1483 },
1484 {
1485 .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/metrics/bandwidth",
1486 .cbs = {
1487 .modify = eigrpd_instance_redistribute_metrics_bandwidth_modify,
1488 .destroy = eigrpd_instance_redistribute_metrics_bandwidth_destroy,
1489 }
1490 },
1491 {
1492 .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/metrics/delay",
1493 .cbs = {
1494 .modify = eigrpd_instance_redistribute_metrics_delay_modify,
1495 .destroy = eigrpd_instance_redistribute_metrics_delay_destroy,
1496 }
1497 },
1498 {
1499 .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/metrics/reliability",
1500 .cbs = {
1501 .modify = eigrpd_instance_redistribute_metrics_reliability_modify,
1502 .destroy = eigrpd_instance_redistribute_metrics_reliability_destroy,
1503 }
1504 },
1505 {
1506 .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/metrics/load",
1507 .cbs = {
1508 .modify = eigrpd_instance_redistribute_metrics_load_modify,
1509 .destroy = eigrpd_instance_redistribute_metrics_load_destroy,
1510 }
1511 },
1512 {
1513 .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/metrics/mtu",
1514 .cbs = {
1515 .modify = eigrpd_instance_redistribute_metrics_mtu_modify,
1516 .destroy = eigrpd_instance_redistribute_metrics_mtu_destroy,
1517 }
1518 },
1519 {
1520 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/delay",
1521 .cbs = {
1522 .modify = lib_interface_eigrp_delay_modify,
1523 .cli_show = eigrp_cli_show_delay,
1524 }
1525 },
1526 {
1527 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/bandwidth",
1528 .cbs = {
1529 .modify = lib_interface_eigrp_bandwidth_modify,
1530 .cli_show = eigrp_cli_show_bandwidth,
1531 }
1532 },
1533 {
1534 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/hello-interval",
1535 .cbs = {
1536 .modify = lib_interface_eigrp_hello_interval_modify,
1537 .cli_show = eigrp_cli_show_hello_interval,
1538 }
1539 },
1540 {
1541 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/hold-time",
1542 .cbs = {
1543 .modify = lib_interface_eigrp_hold_time_modify,
1544 .cli_show = eigrp_cli_show_hold_time,
1545 }
1546 },
1547 {
1548 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/split-horizon",
1549 .cbs = {
1550 .modify = lib_interface_eigrp_split_horizon_modify,
1551 }
1552 },
1553 {
1554 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/instance",
1555 .cbs = {
1556 .create = lib_interface_eigrp_instance_create,
1557 .destroy = lib_interface_eigrp_instance_destroy,
1558 }
1559 },
1560 {
1561 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/instance/summarize-addresses",
1562 .cbs = {
1563 .create = lib_interface_eigrp_instance_summarize_addresses_create,
1564 .destroy = lib_interface_eigrp_instance_summarize_addresses_destroy,
1565 .cli_show = eigrp_cli_show_summarize_address,
1566 }
1567 },
1568 {
1569 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/instance/authentication",
1570 .cbs = {
1571 .modify = lib_interface_eigrp_instance_authentication_modify,
1572 .cli_show = eigrp_cli_show_authentication,
1573 }
1574 },
1575 {
1576 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/instance/keychain",
1577 .cbs = {
1578 .modify = lib_interface_eigrp_instance_keychain_modify,
1579 .destroy = lib_interface_eigrp_instance_keychain_destroy,
1580 .cli_show = eigrp_cli_show_keychain,
1581 }
1582 },
1583 {
1584 .xpath = NULL,
1585 },
1586 }
1587};