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