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