]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_nb_config.c
Merge pull request #7368 from eololab/add-pidfile-in-frr.service
[mirror_frr.git] / zebra / zebra_nb_config.c
1 /*
2 * Copyright (C) 2019 Cumulus Networks, Inc.
3 * Chirag Shah
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include <zebra.h>
21
22 #include "lib/log.h"
23 #include "lib/northbound.h"
24 #include "lib/printfrr.h"
25 #include "libfrr.h"
26 #include "lib/command.h"
27 #include "lib/routemap.h"
28 #include "zebra/zebra_nb.h"
29 #include "zebra/rib.h"
30 #include "zebra_nb.h"
31 #include "zebra/interface.h"
32 #include "zebra/connected.h"
33 #include "zebra/zebra_router.h"
34 #include "zebra/debug.h"
35 #include "zebra/zebra_vxlan_private.h"
36 #include "zebra/zebra_vxlan.h"
37
38 /*
39 * XPath: /frr-zebra:zebra/mcast-rpf-lookup
40 */
41 int zebra_mcast_rpf_lookup_modify(struct nb_cb_modify_args *args)
42 {
43 switch (args->event) {
44 case NB_EV_VALIDATE:
45 case NB_EV_PREPARE:
46 case NB_EV_ABORT:
47 case NB_EV_APPLY:
48 /* TODO: implement me. */
49 break;
50 }
51
52 return NB_OK;
53 }
54
55 /*
56 * XPath: /frr-zebra:zebra/ip-forwarding
57 */
58 int zebra_ip_forwarding_modify(struct nb_cb_modify_args *args)
59 {
60 switch (args->event) {
61 case NB_EV_VALIDATE:
62 case NB_EV_PREPARE:
63 case NB_EV_ABORT:
64 case NB_EV_APPLY:
65 /* TODO: implement me. */
66 break;
67 }
68
69 return NB_OK;
70 }
71
72 int zebra_ip_forwarding_destroy(struct nb_cb_destroy_args *args)
73 {
74 switch (args->event) {
75 case NB_EV_VALIDATE:
76 case NB_EV_PREPARE:
77 case NB_EV_ABORT:
78 case NB_EV_APPLY:
79 /* TODO: implement me. */
80 break;
81 }
82
83 return NB_OK;
84 }
85
86 /*
87 * XPath: /frr-zebra:zebra/ipv6-forwarding
88 */
89 int zebra_ipv6_forwarding_modify(struct nb_cb_modify_args *args)
90 {
91 switch (args->event) {
92 case NB_EV_VALIDATE:
93 case NB_EV_PREPARE:
94 case NB_EV_ABORT:
95 case NB_EV_APPLY:
96 /* TODO: implement me. */
97 break;
98 }
99
100 return NB_OK;
101 }
102
103 int zebra_ipv6_forwarding_destroy(struct nb_cb_destroy_args *args)
104 {
105 switch (args->event) {
106 case NB_EV_VALIDATE:
107 case NB_EV_PREPARE:
108 case NB_EV_ABORT:
109 case NB_EV_APPLY:
110 /* TODO: implement me. */
111 break;
112 }
113
114 return NB_OK;
115 }
116
117 /*
118 * XPath: /frr-zebra:zebra/workqueue-hold-timer
119 */
120 int zebra_workqueue_hold_timer_modify(struct nb_cb_modify_args *args)
121 {
122 switch (args->event) {
123 case NB_EV_VALIDATE:
124 case NB_EV_PREPARE:
125 case NB_EV_ABORT:
126 case NB_EV_APPLY:
127 /* TODO: implement me. */
128 break;
129 }
130
131 return NB_OK;
132 }
133
134 /*
135 * XPath: /frr-zebra:zebra/zapi-packets
136 */
137 int zebra_zapi_packets_modify(struct nb_cb_modify_args *args)
138 {
139 switch (args->event) {
140 case NB_EV_VALIDATE:
141 case NB_EV_PREPARE:
142 case NB_EV_ABORT:
143 case NB_EV_APPLY:
144 /* TODO: implement me. */
145 break;
146 }
147
148 return NB_OK;
149 }
150
151 /*
152 * XPath: /frr-zebra:zebra/import-kernel-table/table-id
153 */
154 int zebra_import_kernel_table_table_id_modify(struct nb_cb_modify_args *args)
155 {
156 switch (args->event) {
157 case NB_EV_VALIDATE:
158 case NB_EV_PREPARE:
159 case NB_EV_ABORT:
160 case NB_EV_APPLY:
161 /* TODO: implement me. */
162 break;
163 }
164
165 return NB_OK;
166 }
167
168 int zebra_import_kernel_table_table_id_destroy(struct nb_cb_destroy_args *args)
169 {
170 switch (args->event) {
171 case NB_EV_VALIDATE:
172 case NB_EV_PREPARE:
173 case NB_EV_ABORT:
174 case NB_EV_APPLY:
175 /* TODO: implement me. */
176 break;
177 }
178
179 return NB_OK;
180 }
181
182 /*
183 * XPath: /frr-zebra:zebra/import-kernel-table/distance
184 */
185 int zebra_import_kernel_table_distance_modify(struct nb_cb_modify_args *args)
186 {
187 switch (args->event) {
188 case NB_EV_VALIDATE:
189 case NB_EV_PREPARE:
190 case NB_EV_ABORT:
191 case NB_EV_APPLY:
192 /* TODO: implement me. */
193 break;
194 }
195
196 return NB_OK;
197 }
198
199 /*
200 * XPath: /frr-zebra:zebra/import-kernel-table/route-map
201 */
202 int zebra_import_kernel_table_route_map_modify(struct nb_cb_modify_args *args)
203 {
204 switch (args->event) {
205 case NB_EV_VALIDATE:
206 case NB_EV_PREPARE:
207 case NB_EV_ABORT:
208 case NB_EV_APPLY:
209 /* TODO: implement me. */
210 break;
211 }
212
213 return NB_OK;
214 }
215
216 int zebra_import_kernel_table_route_map_destroy(struct nb_cb_destroy_args *args)
217 {
218 switch (args->event) {
219 case NB_EV_VALIDATE:
220 case NB_EV_PREPARE:
221 case NB_EV_ABORT:
222 case NB_EV_APPLY:
223 /* TODO: implement me. */
224 break;
225 }
226
227 return NB_OK;
228 }
229
230 /*
231 * XPath: /frr-zebra:zebra/allow-external-route-update
232 */
233 int zebra_allow_external_route_update_create(struct nb_cb_create_args *args)
234 {
235 switch (args->event) {
236 case NB_EV_VALIDATE:
237 case NB_EV_PREPARE:
238 case NB_EV_ABORT:
239 case NB_EV_APPLY:
240 /* TODO: implement me. */
241 break;
242 }
243
244 return NB_OK;
245 }
246
247 int zebra_allow_external_route_update_destroy(struct nb_cb_destroy_args *args)
248 {
249 switch (args->event) {
250 case NB_EV_VALIDATE:
251 case NB_EV_PREPARE:
252 case NB_EV_ABORT:
253 case NB_EV_APPLY:
254 /* TODO: implement me. */
255 break;
256 }
257
258 return NB_OK;
259 }
260
261 /*
262 * XPath: /frr-zebra:zebra/dplane-queue-limit
263 */
264 int zebra_dplane_queue_limit_modify(struct nb_cb_modify_args *args)
265 {
266 switch (args->event) {
267 case NB_EV_VALIDATE:
268 case NB_EV_PREPARE:
269 case NB_EV_ABORT:
270 case NB_EV_APPLY:
271 /* TODO: implement me. */
272 break;
273 }
274
275 return NB_OK;
276 }
277
278 /*
279 * XPath: /frr-zebra:zebra/debugs/debug-events
280 */
281 int zebra_debugs_debug_events_modify(struct nb_cb_modify_args *args)
282 {
283 switch (args->event) {
284 case NB_EV_VALIDATE:
285 case NB_EV_PREPARE:
286 case NB_EV_ABORT:
287 case NB_EV_APPLY:
288 /* TODO: implement me. */
289 break;
290 }
291
292 return NB_OK;
293 }
294
295 int zebra_debugs_debug_events_destroy(struct nb_cb_destroy_args *args)
296 {
297 switch (args->event) {
298 case NB_EV_VALIDATE:
299 case NB_EV_PREPARE:
300 case NB_EV_ABORT:
301 case NB_EV_APPLY:
302 /* TODO: implement me. */
303 break;
304 }
305
306 return NB_OK;
307 }
308
309 /*
310 * XPath: /frr-zebra:zebra/debugs/debug-zapi-send
311 */
312 int zebra_debugs_debug_zapi_send_modify(struct nb_cb_modify_args *args)
313 {
314 switch (args->event) {
315 case NB_EV_VALIDATE:
316 case NB_EV_PREPARE:
317 case NB_EV_ABORT:
318 case NB_EV_APPLY:
319 /* TODO: implement me. */
320 break;
321 }
322
323 return NB_OK;
324 }
325
326 int zebra_debugs_debug_zapi_send_destroy(struct nb_cb_destroy_args *args)
327 {
328 switch (args->event) {
329 case NB_EV_VALIDATE:
330 case NB_EV_PREPARE:
331 case NB_EV_ABORT:
332 case NB_EV_APPLY:
333 /* TODO: implement me. */
334 break;
335 }
336
337 return NB_OK;
338 }
339
340 /*
341 * XPath: /frr-zebra:zebra/debugs/debug-zapi-recv
342 */
343 int zebra_debugs_debug_zapi_recv_modify(struct nb_cb_modify_args *args)
344 {
345 switch (args->event) {
346 case NB_EV_VALIDATE:
347 case NB_EV_PREPARE:
348 case NB_EV_ABORT:
349 case NB_EV_APPLY:
350 /* TODO: implement me. */
351 break;
352 }
353
354 return NB_OK;
355 }
356
357 int zebra_debugs_debug_zapi_recv_destroy(struct nb_cb_destroy_args *args)
358 {
359 switch (args->event) {
360 case NB_EV_VALIDATE:
361 case NB_EV_PREPARE:
362 case NB_EV_ABORT:
363 case NB_EV_APPLY:
364 /* TODO: implement me. */
365 break;
366 }
367
368 return NB_OK;
369 }
370
371 /*
372 * XPath: /frr-zebra:zebra/debugs/debug-zapi-detail
373 */
374 int zebra_debugs_debug_zapi_detail_modify(struct nb_cb_modify_args *args)
375 {
376 switch (args->event) {
377 case NB_EV_VALIDATE:
378 case NB_EV_PREPARE:
379 case NB_EV_ABORT:
380 case NB_EV_APPLY:
381 /* TODO: implement me. */
382 break;
383 }
384
385 return NB_OK;
386 }
387
388 int zebra_debugs_debug_zapi_detail_destroy(struct nb_cb_destroy_args *args)
389 {
390 switch (args->event) {
391 case NB_EV_VALIDATE:
392 case NB_EV_PREPARE:
393 case NB_EV_ABORT:
394 case NB_EV_APPLY:
395 /* TODO: implement me. */
396 break;
397 }
398
399 return NB_OK;
400 }
401
402 /*
403 * XPath: /frr-zebra:zebra/debugs/debug-kernel
404 */
405 int zebra_debugs_debug_kernel_modify(struct nb_cb_modify_args *args)
406 {
407 switch (args->event) {
408 case NB_EV_VALIDATE:
409 case NB_EV_PREPARE:
410 case NB_EV_ABORT:
411 case NB_EV_APPLY:
412 /* TODO: implement me. */
413 break;
414 }
415
416 return NB_OK;
417 }
418
419 int zebra_debugs_debug_kernel_destroy(struct nb_cb_destroy_args *args)
420 {
421 switch (args->event) {
422 case NB_EV_VALIDATE:
423 case NB_EV_PREPARE:
424 case NB_EV_ABORT:
425 case NB_EV_APPLY:
426 /* TODO: implement me. */
427 break;
428 }
429
430 return NB_OK;
431 }
432
433 /*
434 * XPath: /frr-zebra:zebra/debugs/debug-kernel-msg-send
435 */
436 int zebra_debugs_debug_kernel_msg_send_modify(struct nb_cb_modify_args *args)
437 {
438 switch (args->event) {
439 case NB_EV_VALIDATE:
440 case NB_EV_PREPARE:
441 case NB_EV_ABORT:
442 case NB_EV_APPLY:
443 /* TODO: implement me. */
444 break;
445 }
446
447 return NB_OK;
448 }
449
450 int zebra_debugs_debug_kernel_msg_send_destroy(struct nb_cb_destroy_args *args)
451 {
452 switch (args->event) {
453 case NB_EV_VALIDATE:
454 case NB_EV_PREPARE:
455 case NB_EV_ABORT:
456 case NB_EV_APPLY:
457 /* TODO: implement me. */
458 break;
459 }
460
461 return NB_OK;
462 }
463
464 /*
465 * XPath: /frr-zebra:zebra/debugs/debug-kernel-msg-recv
466 */
467 int zebra_debugs_debug_kernel_msg_recv_modify(struct nb_cb_modify_args *args)
468 {
469 switch (args->event) {
470 case NB_EV_VALIDATE:
471 case NB_EV_PREPARE:
472 case NB_EV_ABORT:
473 case NB_EV_APPLY:
474 /* TODO: implement me. */
475 break;
476 }
477
478 return NB_OK;
479 }
480
481 int zebra_debugs_debug_kernel_msg_recv_destroy(struct nb_cb_destroy_args *args)
482 {
483 switch (args->event) {
484 case NB_EV_VALIDATE:
485 case NB_EV_PREPARE:
486 case NB_EV_ABORT:
487 case NB_EV_APPLY:
488 /* TODO: implement me. */
489 break;
490 }
491
492 return NB_OK;
493 }
494
495 /*
496 * XPath: /frr-zebra:zebra/debugs/debug-rib
497 */
498 int zebra_debugs_debug_rib_modify(struct nb_cb_modify_args *args)
499 {
500 switch (args->event) {
501 case NB_EV_VALIDATE:
502 case NB_EV_PREPARE:
503 case NB_EV_ABORT:
504 case NB_EV_APPLY:
505 /* TODO: implement me. */
506 break;
507 }
508
509 return NB_OK;
510 }
511
512 int zebra_debugs_debug_rib_destroy(struct nb_cb_destroy_args *args)
513 {
514 switch (args->event) {
515 case NB_EV_VALIDATE:
516 case NB_EV_PREPARE:
517 case NB_EV_ABORT:
518 case NB_EV_APPLY:
519 /* TODO: implement me. */
520 break;
521 }
522
523 return NB_OK;
524 }
525
526 /*
527 * XPath: /frr-zebra:zebra/debugs/debug-rib-detail
528 */
529 int zebra_debugs_debug_rib_detail_modify(struct nb_cb_modify_args *args)
530 {
531 switch (args->event) {
532 case NB_EV_VALIDATE:
533 case NB_EV_PREPARE:
534 case NB_EV_ABORT:
535 case NB_EV_APPLY:
536 /* TODO: implement me. */
537 break;
538 }
539
540 return NB_OK;
541 }
542
543 int zebra_debugs_debug_rib_detail_destroy(struct nb_cb_destroy_args *args)
544 {
545 switch (args->event) {
546 case NB_EV_VALIDATE:
547 case NB_EV_PREPARE:
548 case NB_EV_ABORT:
549 case NB_EV_APPLY:
550 /* TODO: implement me. */
551 break;
552 }
553
554 return NB_OK;
555 }
556
557 /*
558 * XPath: /frr-zebra:zebra/debugs/debug-fpm
559 */
560 int zebra_debugs_debug_fpm_modify(struct nb_cb_modify_args *args)
561 {
562 switch (args->event) {
563 case NB_EV_VALIDATE:
564 case NB_EV_PREPARE:
565 case NB_EV_ABORT:
566 case NB_EV_APPLY:
567 /* TODO: implement me. */
568 break;
569 }
570
571 return NB_OK;
572 }
573
574 int zebra_debugs_debug_fpm_destroy(struct nb_cb_destroy_args *args)
575 {
576 switch (args->event) {
577 case NB_EV_VALIDATE:
578 case NB_EV_PREPARE:
579 case NB_EV_ABORT:
580 case NB_EV_APPLY:
581 /* TODO: implement me. */
582 break;
583 }
584
585 return NB_OK;
586 }
587
588 /*
589 * XPath: /frr-zebra:zebra/debugs/debug-nht
590 */
591 int zebra_debugs_debug_nht_modify(struct nb_cb_modify_args *args)
592 {
593 switch (args->event) {
594 case NB_EV_VALIDATE:
595 case NB_EV_PREPARE:
596 case NB_EV_ABORT:
597 case NB_EV_APPLY:
598 /* TODO: implement me. */
599 break;
600 }
601
602 return NB_OK;
603 }
604
605 int zebra_debugs_debug_nht_destroy(struct nb_cb_destroy_args *args)
606 {
607 switch (args->event) {
608 case NB_EV_VALIDATE:
609 case NB_EV_PREPARE:
610 case NB_EV_ABORT:
611 case NB_EV_APPLY:
612 /* TODO: implement me. */
613 break;
614 }
615
616 return NB_OK;
617 }
618
619 /*
620 * XPath: /frr-zebra:zebra/debugs/debug-nht-detail
621 */
622 int zebra_debugs_debug_nht_detail_modify(struct nb_cb_modify_args *args)
623 {
624 switch (args->event) {
625 case NB_EV_VALIDATE:
626 case NB_EV_PREPARE:
627 case NB_EV_ABORT:
628 case NB_EV_APPLY:
629 /* TODO: implement me. */
630 break;
631 }
632
633 return NB_OK;
634 }
635
636 int zebra_debugs_debug_nht_detail_destroy(struct nb_cb_destroy_args *args)
637 {
638 switch (args->event) {
639 case NB_EV_VALIDATE:
640 case NB_EV_PREPARE:
641 case NB_EV_ABORT:
642 case NB_EV_APPLY:
643 /* TODO: implement me. */
644 break;
645 }
646
647 return NB_OK;
648 }
649
650 /*
651 * XPath: /frr-zebra:zebra/debugs/debug-mpls
652 */
653 int zebra_debugs_debug_mpls_modify(struct nb_cb_modify_args *args)
654 {
655 switch (args->event) {
656 case NB_EV_VALIDATE:
657 case NB_EV_PREPARE:
658 case NB_EV_ABORT:
659 case NB_EV_APPLY:
660 /* TODO: implement me. */
661 break;
662 }
663
664 return NB_OK;
665 }
666
667 int zebra_debugs_debug_mpls_destroy(struct nb_cb_destroy_args *args)
668 {
669 switch (args->event) {
670 case NB_EV_VALIDATE:
671 case NB_EV_PREPARE:
672 case NB_EV_ABORT:
673 case NB_EV_APPLY:
674 /* TODO: implement me. */
675 break;
676 }
677
678 return NB_OK;
679 }
680
681 /*
682 * XPath: /frr-zebra:zebra/debugs/debug-vxlan
683 */
684 int zebra_debugs_debug_vxlan_modify(struct nb_cb_modify_args *args)
685 {
686 switch (args->event) {
687 case NB_EV_VALIDATE:
688 case NB_EV_PREPARE:
689 case NB_EV_ABORT:
690 case NB_EV_APPLY:
691 /* TODO: implement me. */
692 break;
693 }
694
695 return NB_OK;
696 }
697
698 int zebra_debugs_debug_vxlan_destroy(struct nb_cb_destroy_args *args)
699 {
700 switch (args->event) {
701 case NB_EV_VALIDATE:
702 case NB_EV_PREPARE:
703 case NB_EV_ABORT:
704 case NB_EV_APPLY:
705 /* TODO: implement me. */
706 break;
707 }
708
709 return NB_OK;
710 }
711
712 /*
713 * XPath: /frr-zebra:zebra/debugs/debug-pw
714 */
715 int zebra_debugs_debug_pw_modify(struct nb_cb_modify_args *args)
716 {
717 switch (args->event) {
718 case NB_EV_VALIDATE:
719 case NB_EV_PREPARE:
720 case NB_EV_ABORT:
721 case NB_EV_APPLY:
722 /* TODO: implement me. */
723 break;
724 }
725
726 return NB_OK;
727 }
728
729 int zebra_debugs_debug_pw_destroy(struct nb_cb_destroy_args *args)
730 {
731 switch (args->event) {
732 case NB_EV_VALIDATE:
733 case NB_EV_PREPARE:
734 case NB_EV_ABORT:
735 case NB_EV_APPLY:
736 /* TODO: implement me. */
737 break;
738 }
739
740 return NB_OK;
741 }
742
743 /*
744 * XPath: /frr-zebra:zebra/debugs/debug-dplane
745 */
746 int zebra_debugs_debug_dplane_modify(struct nb_cb_modify_args *args)
747 {
748 switch (args->event) {
749 case NB_EV_VALIDATE:
750 case NB_EV_PREPARE:
751 case NB_EV_ABORT:
752 case NB_EV_APPLY:
753 /* TODO: implement me. */
754 break;
755 }
756
757 return NB_OK;
758 }
759
760 int zebra_debugs_debug_dplane_destroy(struct nb_cb_destroy_args *args)
761 {
762 switch (args->event) {
763 case NB_EV_VALIDATE:
764 case NB_EV_PREPARE:
765 case NB_EV_ABORT:
766 case NB_EV_APPLY:
767 /* TODO: implement me. */
768 break;
769 }
770
771 return NB_OK;
772 }
773
774 /*
775 * XPath: /frr-zebra:zebra/debugs/debug-dplane-detail
776 */
777 int zebra_debugs_debug_dplane_detail_modify(struct nb_cb_modify_args *args)
778 {
779 switch (args->event) {
780 case NB_EV_VALIDATE:
781 case NB_EV_PREPARE:
782 case NB_EV_ABORT:
783 case NB_EV_APPLY:
784 /* TODO: implement me. */
785 break;
786 }
787
788 return NB_OK;
789 }
790
791 int zebra_debugs_debug_dplane_detail_destroy(struct nb_cb_destroy_args *args)
792 {
793 switch (args->event) {
794 case NB_EV_VALIDATE:
795 case NB_EV_PREPARE:
796 case NB_EV_ABORT:
797 case NB_EV_APPLY:
798 /* TODO: implement me. */
799 break;
800 }
801
802 return NB_OK;
803 }
804
805 /*
806 * XPath: /frr-zebra:zebra/debugs/debug-mlag
807 */
808 int zebra_debugs_debug_mlag_modify(struct nb_cb_modify_args *args)
809 {
810 switch (args->event) {
811 case NB_EV_VALIDATE:
812 case NB_EV_PREPARE:
813 case NB_EV_ABORT:
814 case NB_EV_APPLY:
815 /* TODO: implement me. */
816 break;
817 }
818
819 return NB_OK;
820 }
821
822 int zebra_debugs_debug_mlag_destroy(struct nb_cb_destroy_args *args)
823 {
824 switch (args->event) {
825 case NB_EV_VALIDATE:
826 case NB_EV_PREPARE:
827 case NB_EV_ABORT:
828 case NB_EV_APPLY:
829 /* TODO: implement me. */
830 break;
831 }
832
833 return NB_OK;
834 }
835
836 /*
837 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip-addrs
838 */
839 int lib_interface_zebra_ip_addrs_create(struct nb_cb_create_args *args)
840 {
841 struct interface *ifp;
842 struct prefix prefix;
843
844 ifp = nb_running_get_entry(args->dnode, NULL, true);
845 // addr_family = yang_dnode_get_enum(dnode, "./address-family");
846 yang_dnode_get_prefix(&prefix, args->dnode, "./ip-prefix");
847 apply_mask(&prefix);
848
849 switch (args->event) {
850 case NB_EV_VALIDATE:
851 if (prefix.family == AF_INET
852 && ipv4_martian(&prefix.u.prefix4)) {
853 snprintfrr(args->errmsg, args->errmsg_len,
854 "invalid address %pFX", &prefix);
855 return NB_ERR_VALIDATION;
856 } else if (prefix.family == AF_INET6
857 && ipv6_martian(&prefix.u.prefix6)) {
858 snprintfrr(args->errmsg, args->errmsg_len,
859 "invalid address %pFX", &prefix);
860 return NB_ERR_VALIDATION;
861 }
862 break;
863 case NB_EV_PREPARE:
864 case NB_EV_ABORT:
865 break;
866 case NB_EV_APPLY:
867 if (prefix.family == AF_INET)
868 if_ip_address_install(ifp, &prefix, NULL, NULL);
869 else if (prefix.family == AF_INET6)
870 if_ipv6_address_install(ifp, &prefix, NULL);
871
872 break;
873 }
874
875 return NB_OK;
876 }
877
878 int lib_interface_zebra_ip_addrs_destroy(struct nb_cb_destroy_args *args)
879 {
880 struct interface *ifp;
881 struct prefix prefix;
882 struct connected *ifc;
883
884 ifp = nb_running_get_entry(args->dnode, NULL, true);
885 yang_dnode_get_prefix(&prefix, args->dnode, "./ip-prefix");
886 apply_mask(&prefix);
887
888 switch (args->event) {
889 case NB_EV_VALIDATE:
890 if (prefix.family == AF_INET) {
891 /* Check current interface address. */
892 ifc = connected_check_ptp(ifp, &prefix, NULL);
893 if (!ifc) {
894 snprintf(args->errmsg, args->errmsg_len,
895 "interface %s Can't find address\n",
896 ifp->name);
897 return NB_ERR_VALIDATION;
898 }
899 } else if (prefix.family == AF_INET6) {
900 /* Check current interface address. */
901 ifc = connected_check(ifp, &prefix);
902 if (!ifc) {
903 snprintf(args->errmsg, args->errmsg_len,
904 "interface can't find address %s",
905 ifp->name);
906 return NB_ERR_VALIDATION;
907 }
908 } else
909 return NB_ERR_VALIDATION;
910
911 /* This is not configured address. */
912 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) {
913 snprintf(args->errmsg, args->errmsg_len,
914 "interface %s not configured", ifp->name);
915 return NB_ERR_VALIDATION;
916 }
917
918 /* This is not real address or interface is not active. */
919 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
920 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
921 listnode_delete(ifp->connected, ifc);
922 connected_free(&ifc);
923 return NB_ERR_VALIDATION;
924 }
925 break;
926 case NB_EV_PREPARE:
927 case NB_EV_ABORT:
928 break;
929 case NB_EV_APPLY:
930 if_ip_address_uinstall(ifp, &prefix);
931 break;
932 }
933
934 return NB_OK;
935 }
936
937 /*
938 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip-addrs/label
939 */
940 int lib_interface_zebra_ip_addrs_label_modify(struct nb_cb_modify_args *args)
941 {
942 switch (args->event) {
943 case NB_EV_VALIDATE:
944 case NB_EV_PREPARE:
945 case NB_EV_ABORT:
946 case NB_EV_APPLY:
947 /* TODO: implement me. */
948 break;
949 }
950
951 return NB_OK;
952 }
953
954 int lib_interface_zebra_ip_addrs_label_destroy(struct nb_cb_destroy_args *args)
955 {
956 switch (args->event) {
957 case NB_EV_VALIDATE:
958 case NB_EV_PREPARE:
959 case NB_EV_ABORT:
960 case NB_EV_APPLY:
961 /* TODO: implement me. */
962 break;
963 }
964
965 return NB_OK;
966 }
967
968 /*
969 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip-addrs/ip4-peer
970 */
971 int lib_interface_zebra_ip_addrs_ip4_peer_modify(struct nb_cb_modify_args *args)
972 {
973 switch (args->event) {
974 case NB_EV_VALIDATE:
975 case NB_EV_PREPARE:
976 case NB_EV_ABORT:
977 case NB_EV_APPLY:
978 /* TODO: implement me. */
979 break;
980 }
981
982 return NB_OK;
983 }
984
985 int lib_interface_zebra_ip_addrs_ip4_peer_destroy(
986 struct nb_cb_destroy_args *args)
987 {
988 switch (args->event) {
989 case NB_EV_VALIDATE:
990 case NB_EV_PREPARE:
991 case NB_EV_ABORT:
992 case NB_EV_APPLY:
993 /* TODO: implement me. */
994 break;
995 }
996
997 return NB_OK;
998 }
999
1000 /*
1001 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/multicast
1002 */
1003 int lib_interface_zebra_multicast_modify(struct nb_cb_modify_args *args)
1004 {
1005 if (args->event != NB_EV_APPLY)
1006 return NB_OK;
1007
1008 struct interface *ifp;
1009
1010 ifp = nb_running_get_entry(args->dnode, NULL, true);
1011
1012 if_multicast_set(ifp);
1013
1014 return NB_OK;
1015 }
1016
1017 int lib_interface_zebra_multicast_destroy(struct nb_cb_destroy_args *args)
1018 {
1019 if (args->event != NB_EV_APPLY)
1020 return NB_OK;
1021
1022 struct interface *ifp;
1023
1024 ifp = nb_running_get_entry(args->dnode, NULL, true);
1025
1026 if_multicast_unset(ifp);
1027
1028 return NB_OK;
1029 }
1030
1031 /*
1032 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-detect
1033 */
1034 int lib_interface_zebra_link_detect_modify(struct nb_cb_modify_args *args)
1035 {
1036 if (args->event != NB_EV_APPLY)
1037 return NB_OK;
1038
1039 struct interface *ifp;
1040 bool link_detect;
1041
1042 ifp = nb_running_get_entry(args->dnode, NULL, true);
1043 link_detect = yang_dnode_get_bool(args->dnode, "./link-detect");
1044
1045 if_linkdetect(ifp, link_detect);
1046
1047 return NB_OK;
1048 }
1049
1050 int lib_interface_zebra_link_detect_destroy(struct nb_cb_destroy_args *args)
1051 {
1052 if (args->event != NB_EV_APPLY)
1053 return NB_OK;
1054
1055 struct interface *ifp;
1056 bool link_detect;
1057
1058 ifp = nb_running_get_entry(args->dnode, NULL, true);
1059 link_detect = yang_dnode_get_bool(args->dnode, "./link-detect");
1060
1061 if_linkdetect(ifp, link_detect);
1062
1063 return NB_OK;
1064 }
1065
1066 /*
1067 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/shutdown
1068 */
1069 int lib_interface_zebra_shutdown_modify(struct nb_cb_modify_args *args)
1070 {
1071 struct interface *ifp;
1072
1073 ifp = nb_running_get_entry(args->dnode, NULL, true);
1074
1075 if_shutdown(ifp);
1076
1077 return NB_OK;
1078 }
1079
1080 int lib_interface_zebra_shutdown_destroy(struct nb_cb_destroy_args *args)
1081 {
1082 struct interface *ifp;
1083
1084 ifp = nb_running_get_entry(args->dnode, NULL, true);
1085
1086 if_no_shutdown(ifp);
1087
1088 return NB_OK;
1089 }
1090
1091 /*
1092 * XPath: /frr-interface:lib/interface/frr-zebra:zebra/bandwidth
1093 */
1094 int lib_interface_zebra_bandwidth_modify(struct nb_cb_modify_args *args)
1095 {
1096 if (args->event != NB_EV_APPLY)
1097 return NB_OK;
1098
1099 struct interface *ifp;
1100 uint32_t bandwidth;
1101
1102 ifp = nb_running_get_entry(args->dnode, NULL, true);
1103 bandwidth = yang_dnode_get_uint32(args->dnode, "./bandwidth");
1104
1105 ifp->bandwidth = bandwidth;
1106
1107 /* force protocols to recalculate routes due to cost change */
1108 if (if_is_operative(ifp))
1109 zebra_interface_up_update(ifp);
1110
1111 return NB_OK;
1112 }
1113
1114 int lib_interface_zebra_bandwidth_destroy(struct nb_cb_destroy_args *args)
1115 {
1116 if (args->event != NB_EV_APPLY)
1117 return NB_OK;
1118
1119 struct interface *ifp;
1120
1121 ifp = nb_running_get_entry(args->dnode, NULL, true);
1122
1123 ifp->bandwidth = 0;
1124
1125 /* force protocols to recalculate routes due to cost change */
1126 if (if_is_operative(ifp))
1127 zebra_interface_up_update(ifp);
1128
1129 return NB_OK;
1130 }
1131
1132 /*
1133 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/ribs/rib
1134 */
1135 int lib_vrf_zebra_ribs_rib_create(struct nb_cb_create_args *args)
1136 {
1137 struct vrf *vrf;
1138 afi_t afi;
1139 safi_t safi;
1140 struct zebra_vrf *zvrf;
1141 struct zebra_router_table *zrt;
1142 uint32_t table_id;
1143 const char *afi_safi_name;
1144
1145 vrf = nb_running_get_entry(args->dnode, NULL, false);
1146 zvrf = vrf_info_lookup(vrf->vrf_id);
1147 table_id = yang_dnode_get_uint32(args->dnode, "./table-id");
1148 if (!table_id)
1149 table_id = zvrf->table_id;
1150
1151 afi_safi_name = yang_dnode_get_string(args->dnode, "./afi-safi-name");
1152 yang_afi_safi_identity2value(afi_safi_name, &afi, &safi);
1153
1154 zrt = zebra_router_find_zrt(zvrf, table_id, afi, safi);
1155
1156 switch (args->event) {
1157 case NB_EV_VALIDATE:
1158 if (!zrt) {
1159 snprintf(args->errmsg, args->errmsg_len,
1160 "vrf %s table is not found.", vrf->name);
1161 return NB_ERR_VALIDATION;
1162 }
1163 break;
1164 case NB_EV_PREPARE:
1165 case NB_EV_ABORT:
1166 break;
1167 case NB_EV_APPLY:
1168
1169 nb_running_set_entry(args->dnode, zrt);
1170
1171 break;
1172 }
1173
1174 return NB_OK;
1175 }
1176
1177 int lib_vrf_zebra_ribs_rib_destroy(struct nb_cb_destroy_args *args)
1178 {
1179 if (args->event != NB_EV_APPLY)
1180 return NB_OK;
1181
1182 nb_running_unset_entry(args->dnode);
1183
1184 return NB_OK;
1185 }
1186
1187 /*
1188 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/l3vni-id
1189 */
1190 int lib_vrf_zebra_l3vni_id_modify(struct nb_cb_modify_args *args)
1191 {
1192 struct vrf *vrf;
1193 struct zebra_vrf *zvrf;
1194 vni_t vni = 0;
1195 zebra_l3vni_t *zl3vni = NULL;
1196 struct zebra_vrf *zvrf_evpn = NULL;
1197 char err[ERR_STR_SZ];
1198 bool pfx_only = false;
1199 const struct lyd_node *pn_dnode;
1200 const char *vrfname;
1201
1202 switch (args->event) {
1203 case NB_EV_PREPARE:
1204 case NB_EV_ABORT:
1205 return NB_OK;
1206 case NB_EV_VALIDATE:
1207 zvrf_evpn = zebra_vrf_get_evpn();
1208 if (!zvrf_evpn) {
1209 snprintf(args->errmsg, args->errmsg_len,
1210 "evpn vrf is not present.");
1211 return NB_ERR_VALIDATION;
1212 }
1213 vni = yang_dnode_get_uint32(args->dnode, NULL);
1214 /* Get vrf info from parent node, reject configuration
1215 * if zebra vrf already mapped to different vni id.
1216 */
1217 pn_dnode = yang_dnode_get_parent(args->dnode, "vrf");
1218 if (pn_dnode) {
1219 vrfname = yang_dnode_get_string(pn_dnode, "./name");
1220 zvrf = zebra_vrf_lookup_by_name(vrfname);
1221 if (!zvrf) {
1222 snprintf(args->errmsg, args->errmsg_len,
1223 "zebra vrf info not found for vrf:%s.",
1224 vrfname);
1225 return NB_ERR_VALIDATION;
1226 }
1227 if (zvrf->l3vni && zvrf->l3vni != vni) {
1228 snprintf(
1229 args->errmsg, args->errmsg_len,
1230 "vni %u cannot be configured as vni %u is already configured under the vrf",
1231 vni, zvrf->l3vni);
1232 return NB_ERR_VALIDATION;
1233 }
1234 }
1235
1236 /* Check if this VNI is already present in the system */
1237 zl3vni = zl3vni_lookup(vni);
1238 if (zl3vni) {
1239 snprintf(args->errmsg, args->errmsg_len,
1240 "VNI %u is already configured as L3-VNI", vni);
1241 return NB_ERR_VALIDATION;
1242 }
1243
1244 break;
1245 case NB_EV_APPLY:
1246
1247 vrf = nb_running_get_entry(args->dnode, NULL, true);
1248 zvrf = zebra_vrf_lookup_by_name(vrf->name);
1249 vni = yang_dnode_get_uint32(args->dnode, NULL);
1250 /* Note: This covers lib_vrf_zebra_prefix_only_modify() config
1251 * along with l3vni config
1252 */
1253 pfx_only = yang_dnode_get_bool(args->dnode, "../prefix-only");
1254
1255 if (zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
1256 pfx_only ? 1 : 0, 1)
1257 != 0) {
1258 if (IS_ZEBRA_DEBUG_VXLAN)
1259 snprintf(
1260 args->errmsg, args->errmsg_len,
1261 "vrf vni %u mapping failed with error: %s",
1262 vni, err);
1263 return NB_ERR;
1264 }
1265
1266 /* Mark as having FRR configuration */
1267 vrf_set_user_cfged(vrf);
1268
1269 break;
1270 }
1271
1272 return NB_OK;
1273 }
1274
1275 int lib_vrf_zebra_l3vni_id_destroy(struct nb_cb_destroy_args *args)
1276 {
1277 struct vrf *vrf;
1278 struct zebra_vrf *zvrf;
1279 vni_t vni = 0;
1280 char err[ERR_STR_SZ];
1281 uint8_t filter = 0;
1282
1283 switch (args->event) {
1284 case NB_EV_PREPARE:
1285 case NB_EV_ABORT:
1286 case NB_EV_VALIDATE:
1287 return NB_OK;
1288 case NB_EV_APPLY:
1289 vrf = nb_running_get_entry(args->dnode, NULL, true);
1290 zvrf = zebra_vrf_lookup_by_name(vrf->name);
1291 vni = yang_dnode_get_uint32(args->dnode, NULL);
1292
1293 if (!zl3vni_lookup(vni))
1294 return NB_OK;
1295
1296 if (zvrf->l3vni != vni) {
1297 snprintf(args->errmsg, args->errmsg_len,
1298 "vrf %s has different vni %u mapped",
1299 vrf->name, zvrf->l3vni);
1300 return NB_ERR;
1301 }
1302
1303 if (is_l3vni_for_prefix_routes_only(zvrf->l3vni))
1304 filter = 1;
1305
1306 if (zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
1307 filter, 0)
1308 != 0) {
1309 if (IS_ZEBRA_DEBUG_VXLAN)
1310 zlog_debug(
1311 "vrf vni %u unmapping failed with error: %s",
1312 vni, err);
1313 return NB_ERR;
1314 }
1315
1316 /* If no other FRR config for this VRF, mark accordingly. */
1317 if (!zebra_vrf_has_config(zvrf))
1318 vrf_reset_user_cfged(vrf);
1319
1320 break;
1321 }
1322
1323 return NB_OK;
1324 }
1325
1326 /*
1327 * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/prefix-only
1328 */
1329 int lib_vrf_zebra_prefix_only_modify(struct nb_cb_modify_args *args)
1330 {
1331 switch (args->event) {
1332 case NB_EV_VALIDATE:
1333 case NB_EV_PREPARE:
1334 case NB_EV_ABORT:
1335 case NB_EV_APPLY:
1336 /* TODO: implement me. */
1337 break;
1338 }
1339
1340 return NB_OK;
1341 }
1342
1343 /*
1344 * XPath:
1345 * /frr-route-map:lib/route-map/entry/match-condition/frr-zebra:ipv4-prefix-length
1346 */
1347 int lib_route_map_entry_match_condition_ipv4_prefix_length_modify(
1348 struct nb_cb_modify_args *args)
1349 {
1350 struct routemap_hook_context *rhc;
1351 const char *length;
1352 int condition, rv;
1353
1354 if (args->event != NB_EV_APPLY)
1355 return NB_OK;
1356
1357 /* Add configuration. */
1358 rhc = nb_running_get_entry(args->dnode, NULL, true);
1359 length = yang_dnode_get_string(args->dnode, NULL);
1360 condition =
1361 yang_dnode_get_enum(args->dnode, "../frr-route-map:condition");
1362
1363 /* Set destroy information. */
1364 switch (condition) {
1365 case 100: /* ipv4-prefix-length */
1366 rhc->rhc_rule = "ip address prefix-len";
1367 break;
1368
1369 case 102: /* ipv4-next-hop-prefix-length */
1370 rhc->rhc_rule = "ip next-hop prefix-len";
1371 break;
1372 }
1373 rhc->rhc_mhook = generic_match_delete;
1374 rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
1375
1376 rv = generic_match_add(NULL, rhc->rhc_rmi, rhc->rhc_rule, length,
1377 RMAP_EVENT_MATCH_ADDED);
1378 if (rv != CMD_SUCCESS) {
1379 rhc->rhc_mhook = NULL;
1380 return NB_ERR_INCONSISTENCY;
1381 }
1382
1383 return NB_OK;
1384 }
1385
1386 int lib_route_map_entry_match_condition_ipv4_prefix_length_destroy(
1387 struct nb_cb_destroy_args *args)
1388 {
1389 return lib_route_map_entry_match_destroy(args);
1390 }
1391
1392 /*
1393 * XPath:
1394 * /frr-route-map:lib/route-map/entry/match-condition/frr-zebra:ipv6-prefix-length
1395 */
1396 int lib_route_map_entry_match_condition_ipv6_prefix_length_modify(
1397 struct nb_cb_modify_args *args)
1398 {
1399 struct routemap_hook_context *rhc;
1400 const char *length;
1401 int rv;
1402
1403 if (args->event != NB_EV_APPLY)
1404 return NB_OK;
1405
1406 /* Add configuration. */
1407 rhc = nb_running_get_entry(args->dnode, NULL, true);
1408 length = yang_dnode_get_string(args->dnode, NULL);
1409
1410 /* Set destroy information. */
1411 rhc->rhc_mhook = generic_match_delete;
1412 rhc->rhc_rule = "ipv6 address prefix-len";
1413 rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
1414
1415 rv = generic_match_add(NULL, rhc->rhc_rmi, "ipv6 address prefix-len",
1416 length, RMAP_EVENT_MATCH_ADDED);
1417 if (rv != CMD_SUCCESS) {
1418 rhc->rhc_mhook = NULL;
1419 return NB_ERR_INCONSISTENCY;
1420 }
1421
1422 return NB_OK;
1423 }
1424
1425 int lib_route_map_entry_match_condition_ipv6_prefix_length_destroy(
1426 struct nb_cb_destroy_args *args)
1427 {
1428 return lib_route_map_entry_match_destroy(args);
1429 }
1430
1431 /*
1432 * XPath:
1433 * /frr-route-map:lib/route-map/entry/match-condition/frr-zebra:source-protocol
1434 */
1435 int lib_route_map_entry_match_condition_source_protocol_modify(
1436 struct nb_cb_modify_args *args)
1437 {
1438 struct routemap_hook_context *rhc;
1439 const char *type;
1440 int rv;
1441
1442 switch (args->event) {
1443 case NB_EV_VALIDATE:
1444 type = yang_dnode_get_string(args->dnode, NULL);
1445 if (proto_name2num(type) == -1) {
1446 snprintf(args->errmsg, args->errmsg_len,
1447 "invalid protocol: %s", type);
1448 return NB_ERR_VALIDATION;
1449 }
1450 return NB_OK;
1451 case NB_EV_PREPARE:
1452 case NB_EV_ABORT:
1453 return NB_OK;
1454 case NB_EV_APPLY:
1455 /* NOTHING */
1456 break;
1457 }
1458
1459 /* Add configuration. */
1460 rhc = nb_running_get_entry(args->dnode, NULL, true);
1461 type = yang_dnode_get_string(args->dnode, NULL);
1462
1463 /* Set destroy information. */
1464 rhc->rhc_mhook = generic_match_delete;
1465 rhc->rhc_rule = "source-protocol";
1466 rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
1467
1468 rv = generic_match_add(NULL, rhc->rhc_rmi, "source-protocol", type,
1469 RMAP_EVENT_MATCH_ADDED);
1470 if (rv != CMD_SUCCESS) {
1471 rhc->rhc_mhook = NULL;
1472 return NB_ERR_INCONSISTENCY;
1473 }
1474
1475 return NB_OK;
1476 }
1477
1478 int lib_route_map_entry_match_condition_source_protocol_destroy(
1479 struct nb_cb_destroy_args *args)
1480 {
1481 return lib_route_map_entry_match_destroy(args);
1482 }
1483
1484 /*
1485 * XPath:
1486 * /frr-route-map:lib/route-map/entry/match-condition/frr-zebra:source-instance
1487 */
1488 int lib_route_map_entry_match_condition_source_instance_modify(
1489 struct nb_cb_modify_args *args)
1490 {
1491 struct routemap_hook_context *rhc;
1492 const char *type;
1493 int rv;
1494
1495 if (args->event != NB_EV_APPLY)
1496 return NB_OK;
1497
1498 /* Add configuration. */
1499 rhc = nb_running_get_entry(args->dnode, NULL, true);
1500 type = yang_dnode_get_string(args->dnode, NULL);
1501
1502 /* Set destroy information. */
1503 rhc->rhc_mhook = generic_match_delete;
1504 rhc->rhc_rule = "source-instance";
1505 rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
1506
1507 rv = generic_match_add(NULL, rhc->rhc_rmi, "source-instance", type,
1508 RMAP_EVENT_MATCH_ADDED);
1509 if (rv != CMD_SUCCESS) {
1510 rhc->rhc_mhook = NULL;
1511 return NB_ERR_INCONSISTENCY;
1512 }
1513
1514 return NB_OK;
1515 }
1516
1517 int lib_route_map_entry_match_condition_source_instance_destroy(
1518 struct nb_cb_destroy_args *args)
1519 {
1520 return lib_route_map_entry_match_destroy(args);
1521 }
1522
1523 /*
1524 * XPath: /frr-route-map:lib/route-map/entry/set-action/frr-zebra:source-v4
1525 */
1526 int lib_route_map_entry_set_action_source_v4_modify(
1527 struct nb_cb_modify_args *args)
1528 {
1529 struct routemap_hook_context *rhc;
1530 struct interface *pif = NULL;
1531 const char *source;
1532 struct vrf *vrf;
1533 struct prefix p;
1534 int rv;
1535
1536 switch (args->event) {
1537 case NB_EV_VALIDATE:
1538 memset(&p, 0, sizeof(p));
1539 yang_dnode_get_ipv4p(&p, args->dnode, NULL);
1540 if (zebra_check_addr(&p) == 0) {
1541 snprintf(args->errmsg, args->errmsg_len,
1542 "invalid IPv4 address: %s",
1543 yang_dnode_get_string(args->dnode, NULL));
1544 return NB_ERR_VALIDATION;
1545 }
1546
1547 RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
1548 pif = if_lookup_exact_address(&p.u.prefix4, AF_INET,
1549 vrf->vrf_id);
1550 if (pif != NULL)
1551 break;
1552 }
1553 /*
1554 * On startup the local address *may* not have come up
1555 * yet. We need to allow startup configuration of
1556 * set src or we are fudged. Log it for future fun
1557 */
1558 if (pif == NULL)
1559 zlog_warn("set src %pI4 is not a local address",
1560 &p.u.prefix4);
1561 return NB_OK;
1562 case NB_EV_PREPARE:
1563 case NB_EV_ABORT:
1564 return NB_OK;
1565 case NB_EV_APPLY:
1566 /* NOTHING */
1567 break;
1568 }
1569
1570 /* Add configuration. */
1571 rhc = nb_running_get_entry(args->dnode, NULL, true);
1572 source = yang_dnode_get_string(args->dnode, NULL);
1573
1574 /* Set destroy information. */
1575 rhc->rhc_shook = generic_set_delete;
1576 rhc->rhc_rule = "src";
1577
1578 rv = generic_set_add(NULL, rhc->rhc_rmi, "src", source);
1579 if (rv != CMD_SUCCESS) {
1580 rhc->rhc_shook = NULL;
1581 return NB_ERR_INCONSISTENCY;
1582 }
1583
1584 return NB_OK;
1585 }
1586
1587 int lib_route_map_entry_set_action_source_v4_destroy(
1588 struct nb_cb_destroy_args *args)
1589 {
1590 return lib_route_map_entry_set_destroy(args);
1591 }
1592
1593 /*
1594 * XPath: /frr-route-map:lib/route-map/entry/set-action/frr-zebra:source-v6
1595 */
1596 int lib_route_map_entry_set_action_source_v6_modify(
1597 struct nb_cb_modify_args *args)
1598 {
1599 struct routemap_hook_context *rhc;
1600 struct interface *pif = NULL;
1601 const char *source;
1602 struct vrf *vrf;
1603 struct prefix p;
1604 int rv;
1605
1606 switch (args->event) {
1607 case NB_EV_VALIDATE:
1608 memset(&p, 0, sizeof(p));
1609 yang_dnode_get_ipv6p(&p, args->dnode, NULL);
1610 if (zebra_check_addr(&p) == 0) {
1611 snprintf(args->errmsg, args->errmsg_len,
1612 "invalid IPv6 address: %s",
1613 yang_dnode_get_string(args->dnode, NULL));
1614 return NB_ERR_VALIDATION;
1615 }
1616
1617 RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
1618 pif = if_lookup_exact_address(&p.u.prefix6, AF_INET6,
1619 vrf->vrf_id);
1620 if (pif != NULL)
1621 break;
1622 }
1623 /*
1624 * On startup the local address *may* not have come up
1625 * yet. We need to allow startup configuration of
1626 * set src or we are fudged. Log it for future fun
1627 */
1628 if (pif == NULL)
1629 zlog_warn("set src %pI6 is not a local address",
1630 &p.u.prefix6);
1631 return NB_OK;
1632 case NB_EV_PREPARE:
1633 case NB_EV_ABORT:
1634 return NB_OK;
1635 case NB_EV_APPLY:
1636 /* NOTHING */
1637 break;
1638 }
1639
1640 /* Add configuration. */
1641 rhc = nb_running_get_entry(args->dnode, NULL, true);
1642 source = yang_dnode_get_string(args->dnode, NULL);
1643
1644 /* Set destroy information. */
1645 rhc->rhc_shook = generic_set_delete;
1646 rhc->rhc_rule = "src";
1647
1648 rv = generic_set_add(NULL, rhc->rhc_rmi, "src", source);
1649 if (rv != CMD_SUCCESS) {
1650 rhc->rhc_shook = NULL;
1651 return NB_ERR_INCONSISTENCY;
1652 }
1653
1654 return NB_OK;
1655 }
1656
1657 int lib_route_map_entry_set_action_source_v6_destroy(
1658 struct nb_cb_destroy_args *args)
1659 {
1660 return lib_route_map_entry_set_destroy(args);
1661 }