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