]> git.proxmox.com Git - mirror_frr.git/blame - eigrpd/eigrp_northbound.c
eigrpd: Create a socket per vrf for communication
[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;
daa64bdf 749 const char *vrfname;
f25c244b
RZ
750 struct eigrp *eigrp;
751 uint32_t proto;
daa64bdf 752 vrf_id_t vrfid;
f25c244b
RZ
753
754 switch (event) {
755 case NB_EV_VALIDATE:
756 proto = yang_dnode_get_enum(dnode, "./protocol");
daa64bdf
DS
757 vrfname = yang_dnode_get_string(dnode, "../vrf");
758 vrfid = vrf_name_to_id(vrfname);
759 if (vrf_bitmap_check(zclient->redist[AFI_IP][proto], vrfid))
f25c244b
RZ
760 return NB_ERR_INCONSISTENCY;
761 break;
762 case NB_EV_PREPARE:
763 case NB_EV_ABORT:
764 /* NOTHING */
765 break;
766 case NB_EV_APPLY:
767 eigrp = nb_running_get_entry(dnode, NULL, true);
768 proto = yang_dnode_get_enum(dnode, "./protocol");
769 redistribute_get_metrics(dnode, &metrics);
770 eigrp_redistribute_set(eigrp, proto, metrics);
771 break;
772 }
773
774 return NB_OK;
775}
776
777static int eigrpd_instance_redistribute_destroy(enum nb_event event,
778 const struct lyd_node *dnode)
779{
780 struct eigrp *eigrp;
781 uint32_t proto;
782
783 switch (event) {
784 case NB_EV_VALIDATE:
785 case NB_EV_PREPARE:
786 case NB_EV_ABORT:
787 /* NOTHING */
788 break;
789 case NB_EV_APPLY:
790 eigrp = nb_running_get_entry(dnode, NULL, true);
791 proto = yang_dnode_get_enum(dnode, "./protocol");
792 eigrp_redistribute_unset(eigrp, proto);
793 break;
794 }
795
796 return NB_OK;
797}
798
799/*
800 * XPath: /frr-eigrpd:eigrpd/instance/redistribute/route-map
801 */
802static int
803eigrpd_instance_redistribute_route_map_modify(enum nb_event event,
804 const struct lyd_node *dnode,
805 union nb_resource *resource)
806{
807 switch (event) {
808 case NB_EV_VALIDATE:
809 /* TODO: Not implemented. */
810 return NB_ERR_INCONSISTENCY;
811 case NB_EV_PREPARE:
812 case NB_EV_ABORT:
813 case NB_EV_APPLY:
814 /* NOTHING */
815 break;
816 }
817
818 return NB_OK;
819}
820
821static int
822eigrpd_instance_redistribute_route_map_destroy(enum nb_event event,
823 const struct lyd_node *dnode)
824{
825 switch (event) {
826 case NB_EV_VALIDATE:
827 /* TODO: Not implemented. */
828 return NB_ERR_INCONSISTENCY;
829 case NB_EV_PREPARE:
830 case NB_EV_ABORT:
831 case NB_EV_APPLY:
832 /* NOTHING */
833 break;
834 }
835
836 return NB_OK;
837}
838
839/*
840 * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/bandwidth
841 */
842static int eigrpd_instance_redistribute_metrics_bandwidth_modify(
843 enum nb_event event, const struct lyd_node *dnode,
844 union nb_resource *resource)
845{
846 struct eigrp_metrics metrics;
847 struct eigrp *eigrp;
848 uint32_t proto;
849
850 switch (event) {
851 case NB_EV_VALIDATE:
852 case NB_EV_PREPARE:
853 case NB_EV_ABORT:
854 /* NOTHING */
855 break;
856 case NB_EV_APPLY:
857 eigrp = nb_running_get_entry(dnode, NULL, true);
858 proto = yang_dnode_get_enum(dnode, "../../protocol");
859 redistribute_get_metrics(dnode, &metrics);
860 eigrp_redistribute_set(eigrp, proto, metrics);
861 break;
862 }
863
864 return NB_OK;
865}
866
867static int eigrpd_instance_redistribute_metrics_bandwidth_destroy(
868 enum nb_event event, const struct lyd_node *dnode)
869{
870 struct eigrp_metrics metrics;
871 struct eigrp *eigrp;
872 uint32_t proto;
873
874 switch (event) {
875 case NB_EV_VALIDATE:
876 case NB_EV_PREPARE:
877 case NB_EV_ABORT:
878 /* NOTHING */
879 break;
880 case NB_EV_APPLY:
881 eigrp = nb_running_get_entry(dnode, NULL, true);
882 proto = yang_dnode_get_enum(dnode, "../../protocol");
883 redistribute_get_metrics(dnode, &metrics);
884 eigrp_redistribute_set(eigrp, proto, metrics);
885 break;
886 }
887
888 return NB_OK;
889}
890
891/*
892 * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/delay
893 */
894static int
895eigrpd_instance_redistribute_metrics_delay_modify(enum nb_event event,
896 const struct lyd_node *dnode,
897 union nb_resource *resource)
898{
899 return eigrpd_instance_redistribute_metrics_bandwidth_modify(event,
900 dnode,
901 resource);
902}
903
904static int
905eigrpd_instance_redistribute_metrics_delay_destroy(enum nb_event event,
906 const struct lyd_node *dnode)
907{
908 return eigrpd_instance_redistribute_metrics_bandwidth_destroy(event,
909 dnode);
910}
911
912/*
913 * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/reliability
914 */
915static int eigrpd_instance_redistribute_metrics_reliability_modify(
916 enum nb_event event, const struct lyd_node *dnode,
917 union nb_resource *resource)
918{
919 return eigrpd_instance_redistribute_metrics_bandwidth_modify(event,
920 dnode,
921 resource);
922}
923
924static int eigrpd_instance_redistribute_metrics_reliability_destroy(
925 enum nb_event event, const struct lyd_node *dnode)
926{
927 return eigrpd_instance_redistribute_metrics_bandwidth_destroy(event,
928 dnode);
929}
930
931/*
932 * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/load
933 */
934static int
935eigrpd_instance_redistribute_metrics_load_modify(enum nb_event event,
936 const struct lyd_node *dnode,
937 union nb_resource *resource)
938{
939 return eigrpd_instance_redistribute_metrics_bandwidth_modify(event,
940 dnode,
941 resource);
942}
943
944static int
945eigrpd_instance_redistribute_metrics_load_destroy(enum nb_event event,
946 const struct lyd_node *dnode)
947{
948 return eigrpd_instance_redistribute_metrics_bandwidth_destroy(event,
949 dnode);
950}
951
952/*
953 * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/mtu
954 */
955static int
956eigrpd_instance_redistribute_metrics_mtu_modify(enum nb_event event,
957 const struct lyd_node *dnode,
958 union nb_resource *resource)
959{
960 return eigrpd_instance_redistribute_metrics_bandwidth_modify(event,
961 dnode,
962 resource);
963}
964
965static int
966eigrpd_instance_redistribute_metrics_mtu_destroy(enum nb_event event,
967 const struct lyd_node *dnode)
968{
969 return eigrpd_instance_redistribute_metrics_bandwidth_destroy(event,
970 dnode);
971}
972
973/*
974 * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/delay
975 */
976static int lib_interface_eigrp_delay_modify(enum nb_event event,
977 const struct lyd_node *dnode,
978 union nb_resource *resource)
979{
980 struct eigrp_interface *ei;
981 struct interface *ifp;
982
983 switch (event) {
984 case NB_EV_VALIDATE:
985 ifp = nb_running_get_entry(dnode, NULL, false);
986 if (ifp == NULL) {
987 /*
988 * XXX: we can't verify if the interface exists
989 * and is active until EIGRP is up.
990 */
991 break;
992 }
993
994 ei = ifp->info;
995 if (ei == NULL)
996 return NB_ERR_INCONSISTENCY;
997 break;
998 case NB_EV_PREPARE:
999 case NB_EV_ABORT:
1000 /* NOTHING */
1001 break;
1002 case NB_EV_APPLY:
1003 ifp = nb_running_get_entry(dnode, NULL, true);
1004 ei = ifp->info;
1005 if (ei == NULL)
1006 return NB_ERR_INCONSISTENCY;
1007
1008 ei->params.delay = yang_dnode_get_uint32(dnode, NULL);
1009 eigrp_if_reset(ifp);
1010 break;
1011 }
1012
1013 return NB_OK;
1014}
1015
1016/*
1017 * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/bandwidth
1018 */
1019static int lib_interface_eigrp_bandwidth_modify(enum nb_event event,
1020 const struct lyd_node *dnode,
1021 union nb_resource *resource)
1022{
1023 struct interface *ifp;
1024 struct eigrp_interface *ei;
1025
1026 switch (event) {
1027 case NB_EV_VALIDATE:
1028 ifp = nb_running_get_entry(dnode, NULL, false);
1029 if (ifp == NULL) {
1030 /*
1031 * XXX: we can't verify if the interface exists
1032 * and is active until EIGRP is up.
1033 */
1034 break;
1035 }
1036
1037 ei = ifp->info;
1038 if (ei == NULL)
1039 return NB_ERR_INCONSISTENCY;
1040 break;
1041 case NB_EV_PREPARE:
1042 case NB_EV_ABORT:
1043 /* NOTHING */
1044 break;
1045 case NB_EV_APPLY:
1046 ifp = nb_running_get_entry(dnode, NULL, true);
1047 ei = ifp->info;
1048 if (ei == NULL)
1049 return NB_ERR_INCONSISTENCY;
1050
1051 ei->params.bandwidth = yang_dnode_get_uint32(dnode, NULL);
1052 eigrp_if_reset(ifp);
1053 break;
1054 }
1055
1056 return NB_OK;
1057}
1058
1059/*
1060 * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/hello-interval
1061 */
1062static int
1063lib_interface_eigrp_hello_interval_modify(enum nb_event event,
1064 const struct lyd_node *dnode,
1065 union nb_resource *resource)
1066{
1067 struct interface *ifp;
1068 struct eigrp_interface *ei;
1069
1070 switch (event) {
1071 case NB_EV_VALIDATE:
1072 ifp = nb_running_get_entry(dnode, NULL, false);
1073 if (ifp == NULL) {
1074 /*
1075 * XXX: we can't verify if the interface exists
1076 * and is active until EIGRP is up.
1077 */
1078 break;
1079 }
1080
1081 ei = ifp->info;
1082 if (ei == NULL)
1083 return NB_ERR_INCONSISTENCY;
1084 break;
1085 case NB_EV_PREPARE:
1086 case NB_EV_ABORT:
1087 /* NOTHING */
1088 break;
1089 case NB_EV_APPLY:
1090 ifp = nb_running_get_entry(dnode, NULL, true);
1091 ei = ifp->info;
1092 if (ei == NULL)
1093 return NB_ERR_INCONSISTENCY;
1094
1095 ei->params.v_hello = yang_dnode_get_uint16(dnode, NULL);
1096 break;
1097 }
1098
1099 return NB_OK;
1100}
1101
1102/*
1103 * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/hold-time
1104 */
1105static int lib_interface_eigrp_hold_time_modify(enum nb_event event,
1106 const struct lyd_node *dnode,
1107 union nb_resource *resource)
1108{
1109 struct interface *ifp;
1110 struct eigrp_interface *ei;
1111
1112 switch (event) {
1113 case NB_EV_VALIDATE:
1114 ifp = nb_running_get_entry(dnode, NULL, false);
1115 if (ifp == NULL) {
1116 /*
1117 * XXX: we can't verify if the interface exists
1118 * and is active until EIGRP is up.
1119 */
1120 break;
1121 }
1122
1123 ei = ifp->info;
1124 if (ei == NULL)
1125 return NB_ERR_INCONSISTENCY;
1126 break;
1127 case NB_EV_PREPARE:
1128 case NB_EV_ABORT:
1129 /* NOTHING */
1130 break;
1131 case NB_EV_APPLY:
1132 ifp = nb_running_get_entry(dnode, NULL, true);
1133 ei = ifp->info;
1134 if (ei == NULL)
1135 return NB_ERR_INCONSISTENCY;
1136
1137 ei->params.v_wait = yang_dnode_get_uint16(dnode, NULL);
1138 break;
1139 }
1140
1141 return NB_OK;
1142}
1143
1144/*
1145 * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/split-horizon
1146 */
1147static int
1148lib_interface_eigrp_split_horizon_modify(enum nb_event event,
1149 const struct lyd_node *dnode,
1150 union nb_resource *resource)
1151{
1152 switch (event) {
1153 case NB_EV_VALIDATE:
1154 /* TODO: Not implemented. */
1155 return NB_ERR_INCONSISTENCY;
1156 case NB_EV_PREPARE:
1157 case NB_EV_ABORT:
1158 case NB_EV_APPLY:
1159 /* NOTHING */
1160 break;
1161 }
1162
1163 return NB_OK;
1164}
1165
1166/*
1167 * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance
1168 */
1169static int lib_interface_eigrp_instance_create(enum nb_event event,
1170 const struct lyd_node *dnode,
1171 union nb_resource *resource)
1172{
1173 struct eigrp_interface *eif;
1174 struct interface *ifp;
1175 struct eigrp *eigrp;
1176
1177 switch (event) {
1178 case NB_EV_VALIDATE:
1179 ifp = nb_running_get_entry(dnode, NULL, false);
1180 if (ifp == NULL) {
1181 /*
1182 * XXX: we can't verify if the interface exists
1183 * and is active until EIGRP is up.
1184 */
1185 break;
1186 }
1187
c371cd6b
DS
1188 eigrp = eigrp_get(yang_dnode_get_string(dnode, "./asn"),
1189 VRF_DEFAULT);
f25c244b
RZ
1190 eif = eigrp_interface_lookup(eigrp, ifp->name);
1191 if (eif == NULL)
1192 return NB_ERR_INCONSISTENCY;
1193 break;
1194 case NB_EV_PREPARE:
1195 case NB_EV_ABORT:
1196 /* NOTHING */
1197 break;
1198 case NB_EV_APPLY:
1199 ifp = nb_running_get_entry(dnode, NULL, true);
c371cd6b
DS
1200 eigrp = eigrp_get(yang_dnode_get_string(dnode, "./asn"),
1201 VRF_DEFAULT);
f25c244b
RZ
1202 eif = eigrp_interface_lookup(eigrp, ifp->name);
1203 if (eif == NULL)
1204 return NB_ERR_INCONSISTENCY;
1205
1206 nb_running_set_entry(dnode, eif);
1207 break;
1208 }
1209
1210 return NB_OK;
1211}
1212
1213static int lib_interface_eigrp_instance_destroy(enum nb_event event,
1214 const struct lyd_node *dnode)
1215{
1216 switch (event) {
1217 case NB_EV_VALIDATE:
1218 case NB_EV_PREPARE:
1219 case NB_EV_ABORT:
1220 /* NOTHING */
1221 break;
1222 case NB_EV_APPLY:
1223 nb_running_unset_entry(dnode);
1224 break;
1225 }
1226
1227 return NB_OK;
1228}
1229
1230/*
1231 * XPath:
1232 * /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/summarize-addresses
1233 */
1234static int lib_interface_eigrp_instance_summarize_addresses_create(
1235 enum nb_event event, const struct lyd_node *dnode,
1236 union nb_resource *resource)
1237{
1238 switch (event) {
1239 case NB_EV_VALIDATE:
1240 /* TODO: Not implemented. */
1241 return NB_ERR_INCONSISTENCY;
1242 case NB_EV_PREPARE:
1243 case NB_EV_ABORT:
1244 case NB_EV_APPLY:
1245 /* NOTHING */
1246 break;
1247 }
1248
1249 return NB_OK;
1250}
1251
1252static int lib_interface_eigrp_instance_summarize_addresses_destroy(
1253 enum nb_event event, const struct lyd_node *dnode)
1254{
1255 switch (event) {
1256 case NB_EV_VALIDATE:
1257 /* TODO: Not implemented. */
1258 return NB_ERR_INCONSISTENCY;
1259 case NB_EV_PREPARE:
1260 case NB_EV_ABORT:
1261 case NB_EV_APPLY:
1262 /* NOTHING */
1263 break;
1264 }
1265
1266 return NB_OK;
1267}
1268
1269/*
1270 * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/authentication
1271 */
1272static int
1273lib_interface_eigrp_instance_authentication_modify(enum nb_event event,
1274 const struct lyd_node *dnode,
1275 union nb_resource *resource)
1276{
1277 struct eigrp_interface *eif;
1278
1279 switch (event) {
1280 case NB_EV_VALIDATE:
1281 case NB_EV_PREPARE:
1282 case NB_EV_ABORT:
1283 /* NOTHING */
1284 break;
1285 case NB_EV_APPLY:
1286 eif = nb_running_get_entry(dnode, NULL, true);
1287 eif->params.auth_type = yang_dnode_get_enum(dnode, NULL);
1288 break;
1289 }
1290
1291 return NB_OK;
1292}
1293
1294/*
1295 * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/keychain
1296 */
1297static int
1298lib_interface_eigrp_instance_keychain_modify(enum nb_event event,
1299 const struct lyd_node *dnode,
1300 union nb_resource *resource)
1301{
1302 struct eigrp_interface *eif;
1303 struct keychain *keychain;
1304
1305 switch (event) {
1306 case NB_EV_VALIDATE:
1307 keychain = keychain_lookup(yang_dnode_get_string(dnode, NULL));
1308 if (keychain == NULL)
1309 return NB_ERR_INCONSISTENCY;
1310 break;
1311 case NB_EV_PREPARE:
1312 resource->ptr = strdup(yang_dnode_get_string(dnode, NULL));
1313 if (resource->ptr == NULL)
1314 return NB_ERR_RESOURCE;
1315 break;
1316 case NB_EV_ABORT:
1317 free(resource->ptr);
1318 resource->ptr = NULL;
1319 break;
1320 case NB_EV_APPLY:
1321 eif = nb_running_get_entry(dnode, NULL, true);
1322 if (eif->params.auth_keychain)
1323 free(eif->params.auth_keychain);
1324
1325 eif->params.auth_keychain = resource->ptr;
1326 break;
1327 }
1328
1329 return NB_OK;
1330}
1331
1332static int
1333lib_interface_eigrp_instance_keychain_destroy(enum nb_event event,
1334 const struct lyd_node *dnode)
1335{
1336 struct eigrp_interface *eif;
1337
1338 switch (event) {
1339 case NB_EV_VALIDATE:
1340 case NB_EV_PREPARE:
1341 case NB_EV_ABORT:
1342 /* NOTHING */
1343 break;
1344 case NB_EV_APPLY:
1345 eif = nb_running_get_entry(dnode, NULL, true);
1346 if (eif->params.auth_keychain)
1347 free(eif->params.auth_keychain);
1348
1349 eif->params.auth_keychain = NULL;
1350 break;
1351 }
1352
1353 return NB_OK;
1354}
1355
1356/* clang-format off */
1357const struct frr_yang_module_info frr_eigrpd_info = {
1358 .name = "frr-eigrpd",
1359 .nodes = {
1360 {
1361 .xpath = "/frr-eigrpd:eigrpd/instance",
1362 .cbs = {
1363 .create = eigrpd_instance_create,
1364 .destroy = eigrpd_instance_destroy,
1365 .cli_show = eigrp_cli_show_header,
1366 .cli_show_end = eigrp_cli_show_end_header,
1367 }
1368 },
1369 {
1370 .xpath = "/frr-eigrpd:eigrpd/instance/router-id",
1371 .cbs = {
1372 .modify = eigrpd_instance_router_id_modify,
1373 .destroy = eigrpd_instance_router_id_destroy,
1374 .cli_show = eigrp_cli_show_router_id,
1375 }
1376 },
1377 {
1378 .xpath = "/frr-eigrpd:eigrpd/instance/passive-interface",
1379 .cbs = {
1380 .create = eigrpd_instance_passive_interface_create,
1381 .destroy = eigrpd_instance_passive_interface_destroy,
1382 .cli_show = eigrp_cli_show_passive_interface,
1383 }
1384 },
1385 {
1386 .xpath = "/frr-eigrpd:eigrpd/instance/active-time",
1387 .cbs = {
1388 .modify = eigrpd_instance_active_time_modify,
1389 .cli_show = eigrp_cli_show_active_time,
1390 }
1391 },
1392 {
1393 .xpath = "/frr-eigrpd:eigrpd/instance/variance",
1394 .cbs = {
1395 .modify = eigrpd_instance_variance_modify,
1396 .destroy = eigrpd_instance_variance_destroy,
1397 .cli_show = eigrp_cli_show_variance,
1398 }
1399 },
1400 {
1401 .xpath = "/frr-eigrpd:eigrpd/instance/maximum-paths",
1402 .cbs = {
1403 .modify = eigrpd_instance_maximum_paths_modify,
1404 .destroy = eigrpd_instance_maximum_paths_destroy,
1405 .cli_show = eigrp_cli_show_maximum_paths,
1406 }
1407 },
1408 {
1409 .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights",
1410 .cbs = {
1411 .cli_show = eigrp_cli_show_metrics,
1412 }
1413 },
1414 {
1415 .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K1",
1416 .cbs = {
1417 .modify = eigrpd_instance_metric_weights_K1_modify,
1418 .destroy = eigrpd_instance_metric_weights_K1_destroy,
1419 }
1420 },
1421 {
1422 .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K2",
1423 .cbs = {
1424 .modify = eigrpd_instance_metric_weights_K2_modify,
1425 .destroy = eigrpd_instance_metric_weights_K2_destroy,
1426 }
1427 },
1428 {
1429 .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K3",
1430 .cbs = {
1431 .modify = eigrpd_instance_metric_weights_K3_modify,
1432 .destroy = eigrpd_instance_metric_weights_K3_destroy,
1433 }
1434 },
1435 {
1436 .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K4",
1437 .cbs = {
1438 .modify = eigrpd_instance_metric_weights_K4_modify,
1439 .destroy = eigrpd_instance_metric_weights_K4_destroy,
1440 }
1441 },
1442 {
1443 .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K5",
1444 .cbs = {
1445 .modify = eigrpd_instance_metric_weights_K5_modify,
1446 .destroy = eigrpd_instance_metric_weights_K5_destroy,
1447 }
1448 },
1449 {
1450 .xpath = "/frr-eigrpd:eigrpd/instance/metric-weights/K6",
1451 .cbs = {
1452 .modify = eigrpd_instance_metric_weights_K6_modify,
1453 .destroy = eigrpd_instance_metric_weights_K6_destroy,
1454 }
1455 },
1456 {
1457 .xpath = "/frr-eigrpd:eigrpd/instance/network",
1458 .cbs = {
1459 .create = eigrpd_instance_network_create,
1460 .destroy = eigrpd_instance_network_destroy,
1461 .cli_show = eigrp_cli_show_network,
1462 }
1463 },
1464 {
1465 .xpath = "/frr-eigrpd:eigrpd/instance/neighbor",
1466 .cbs = {
1467 .create = eigrpd_instance_neighbor_create,
1468 .destroy = eigrpd_instance_neighbor_destroy,
1469 .cli_show = eigrp_cli_show_neighbor,
1470 }
1471 },
1472 {
1473 .xpath = "/frr-eigrpd:eigrpd/instance/redistribute",
1474 .cbs = {
1475 .create = eigrpd_instance_redistribute_create,
1476 .destroy = eigrpd_instance_redistribute_destroy,
1477 .cli_show = eigrp_cli_show_redistribute,
1478 }
1479 },
1480 {
1481 .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/route-map",
1482 .cbs = {
1483 .modify = eigrpd_instance_redistribute_route_map_modify,
1484 .destroy = eigrpd_instance_redistribute_route_map_destroy,
1485 }
1486 },
1487 {
1488 .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/metrics/bandwidth",
1489 .cbs = {
1490 .modify = eigrpd_instance_redistribute_metrics_bandwidth_modify,
1491 .destroy = eigrpd_instance_redistribute_metrics_bandwidth_destroy,
1492 }
1493 },
1494 {
1495 .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/metrics/delay",
1496 .cbs = {
1497 .modify = eigrpd_instance_redistribute_metrics_delay_modify,
1498 .destroy = eigrpd_instance_redistribute_metrics_delay_destroy,
1499 }
1500 },
1501 {
1502 .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/metrics/reliability",
1503 .cbs = {
1504 .modify = eigrpd_instance_redistribute_metrics_reliability_modify,
1505 .destroy = eigrpd_instance_redistribute_metrics_reliability_destroy,
1506 }
1507 },
1508 {
1509 .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/metrics/load",
1510 .cbs = {
1511 .modify = eigrpd_instance_redistribute_metrics_load_modify,
1512 .destroy = eigrpd_instance_redistribute_metrics_load_destroy,
1513 }
1514 },
1515 {
1516 .xpath = "/frr-eigrpd:eigrpd/instance/redistribute/metrics/mtu",
1517 .cbs = {
1518 .modify = eigrpd_instance_redistribute_metrics_mtu_modify,
1519 .destroy = eigrpd_instance_redistribute_metrics_mtu_destroy,
1520 }
1521 },
1522 {
1523 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/delay",
1524 .cbs = {
1525 .modify = lib_interface_eigrp_delay_modify,
1526 .cli_show = eigrp_cli_show_delay,
1527 }
1528 },
1529 {
1530 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/bandwidth",
1531 .cbs = {
1532 .modify = lib_interface_eigrp_bandwidth_modify,
1533 .cli_show = eigrp_cli_show_bandwidth,
1534 }
1535 },
1536 {
1537 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/hello-interval",
1538 .cbs = {
1539 .modify = lib_interface_eigrp_hello_interval_modify,
1540 .cli_show = eigrp_cli_show_hello_interval,
1541 }
1542 },
1543 {
1544 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/hold-time",
1545 .cbs = {
1546 .modify = lib_interface_eigrp_hold_time_modify,
1547 .cli_show = eigrp_cli_show_hold_time,
1548 }
1549 },
1550 {
1551 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/split-horizon",
1552 .cbs = {
1553 .modify = lib_interface_eigrp_split_horizon_modify,
1554 }
1555 },
1556 {
1557 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/instance",
1558 .cbs = {
1559 .create = lib_interface_eigrp_instance_create,
1560 .destroy = lib_interface_eigrp_instance_destroy,
1561 }
1562 },
1563 {
1564 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/instance/summarize-addresses",
1565 .cbs = {
1566 .create = lib_interface_eigrp_instance_summarize_addresses_create,
1567 .destroy = lib_interface_eigrp_instance_summarize_addresses_destroy,
1568 .cli_show = eigrp_cli_show_summarize_address,
1569 }
1570 },
1571 {
1572 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/instance/authentication",
1573 .cbs = {
1574 .modify = lib_interface_eigrp_instance_authentication_modify,
1575 .cli_show = eigrp_cli_show_authentication,
1576 }
1577 },
1578 {
1579 .xpath = "/frr-interface:lib/interface/frr-eigrpd:eigrp/instance/keychain",
1580 .cbs = {
1581 .modify = lib_interface_eigrp_instance_keychain_modify,
1582 .destroy = lib_interface_eigrp_instance_keychain_destroy,
1583 .cli_show = eigrp_cli_show_keychain,
1584 }
1585 },
1586 {
1587 .xpath = NULL,
1588 },
1589 }
1590};