]> git.proxmox.com Git - mirror_frr.git/blob - staticd/static_nb_config.c
staticd: reject route config with too many nexthops
[mirror_frr.git] / staticd / static_nb_config.c
1 /*
2 * Copyright (C) 2018 Vmware
3 * Vishal Dhingra
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 #include <zebra.h>
20
21 #include "northbound.h"
22 #include "libfrr.h"
23 #include "log.h"
24 #include "lib_errors.h"
25 #include "prefix.h"
26 #include "table.h"
27 #include "vrf.h"
28 #include "nexthop.h"
29 #include "srcdest_table.h"
30
31 #include "static_vrf.h"
32 #include "static_routes.h"
33 #include "static_nb.h"
34
35
36 static int static_path_list_create(struct nb_cb_create_args *args)
37 {
38 struct route_node *rn;
39 struct static_path *pn;
40 const struct lyd_node *vrf_dnode;
41 const char *vrf;
42 uint8_t distance;
43 uint32_t table_id;
44
45 switch (args->event) {
46 case NB_EV_VALIDATE:
47 vrf_dnode = yang_dnode_get_parent(args->dnode,
48 "control-plane-protocol");
49 vrf = yang_dnode_get_string(vrf_dnode, "./vrf");
50 table_id = yang_dnode_get_uint32(args->dnode, "./table-id");
51
52 /*
53 * TableId is not applicable for VRF. Consider the case of
54 * l3mdev, there is one uint32_t space to work with.
55 * A l3mdev device points at a specific table that it
56 * relates to and a set of interfaces it belongs to.
57 */
58 if (table_id && (strcmp(vrf, vrf_get_default_name()) != 0)
59 && !vrf_is_backend_netns()) {
60 snprintf(
61 args->errmsg, args->errmsg_len,
62 "%% table param only available when running on netns-based vrfs");
63 return NB_ERR_VALIDATION;
64 }
65 break;
66 case NB_EV_ABORT:
67 case NB_EV_PREPARE:
68 break;
69 case NB_EV_APPLY:
70 rn = nb_running_get_entry(args->dnode, NULL, true);
71 distance = yang_dnode_get_uint8(args->dnode, "./distance");
72 table_id = yang_dnode_get_uint32(args->dnode, "./table-id");
73 pn = static_add_path(rn, table_id, distance);
74 nb_running_set_entry(args->dnode, pn);
75 }
76
77 return NB_OK;
78 }
79
80 static int static_path_list_destroy(struct nb_cb_destroy_args *args)
81 {
82 struct static_path *pn;
83
84 switch (args->event) {
85 case NB_EV_VALIDATE:
86 case NB_EV_PREPARE:
87 case NB_EV_ABORT:
88 break;
89 case NB_EV_APPLY:
90 pn = nb_running_unset_entry(args->dnode);
91 static_del_path(pn);
92 break;
93 }
94
95 return NB_OK;
96 }
97
98 static int static_path_list_tag_modify(struct nb_cb_modify_args *args)
99 {
100 struct static_path *pn;
101
102 switch (args->event) {
103 case NB_EV_VALIDATE:
104 case NB_EV_ABORT:
105 case NB_EV_PREPARE:
106 break;
107 case NB_EV_APPLY:
108 pn = nb_running_get_entry(args->dnode, NULL, true);
109 pn->tag = yang_dnode_get_uint32(args->dnode, NULL);
110 static_install_path(pn);
111 break;
112 }
113
114 return NB_OK;
115 }
116
117 struct nexthop_iter {
118 uint32_t count;
119 bool blackhole;
120 };
121
122 static int nexthop_iter_cb(const struct lyd_node *dnode, void *arg)
123 {
124 struct nexthop_iter *iter = arg;
125 enum static_nh_type nh_type;
126
127 nh_type = yang_dnode_get_enum(dnode, "./nh-type");
128
129 if (nh_type == STATIC_BLACKHOLE)
130 iter->blackhole = true;
131
132 iter->count++;
133
134 return YANG_ITER_CONTINUE;
135 }
136
137 static bool static_nexthop_create(struct nb_cb_create_args *args)
138 {
139 const struct lyd_node *pn_dnode;
140 struct nexthop_iter iter;
141 struct static_path *pn;
142 struct ipaddr ipaddr;
143 struct static_nexthop *nh;
144 enum static_nh_type nh_type;
145 const char *ifname;
146 const char *nh_vrf;
147
148 switch (args->event) {
149 case NB_EV_VALIDATE:
150 ifname = yang_dnode_get_string(args->dnode, "./interface");
151 if (ifname != NULL) {
152 if (strcasecmp(ifname, "Null0") == 0
153 || strcasecmp(ifname, "reject") == 0
154 || strcasecmp(ifname, "blackhole") == 0) {
155 snprintf(args->errmsg, args->errmsg_len,
156 "%s: Nexthop interface name can not be from reserved keywords(Null0, reject, blackhole)",
157 ifname);
158 return NB_ERR_VALIDATION;
159 }
160 }
161
162 iter.count = 0;
163 iter.blackhole = false;
164
165 pn_dnode = yang_dnode_get_parent(args->dnode, "path-list");
166 yang_dnode_iterate(nexthop_iter_cb, &iter, pn_dnode,
167 "./frr-nexthops/nexthop");
168
169 if (iter.blackhole && iter.count > 1) {
170 snprintf(
171 args->errmsg, args->errmsg_len,
172 "Route cannot have blackhole and non-blackhole nexthops simultaneously");
173 return NB_ERR_VALIDATION;
174 } else if (iter.count > zebra_ecmp_count) {
175 snprintf(args->errmsg, args->errmsg_len,
176 "Route cannot have more than %d ECMP nexthops",
177 zebra_ecmp_count);
178 return NB_ERR_VALIDATION;
179 }
180 break;
181 case NB_EV_PREPARE:
182 case NB_EV_ABORT:
183 break;
184 case NB_EV_APPLY:
185 yang_dnode_get_ip(&ipaddr, args->dnode, "./gateway");
186 nh_type = yang_dnode_get_enum(args->dnode, "./nh-type");
187 ifname = yang_dnode_get_string(args->dnode, "./interface");
188 nh_vrf = yang_dnode_get_string(args->dnode, "./vrf");
189 pn = nb_running_get_entry(args->dnode, NULL, true);
190
191 if (!static_add_nexthop_validate(nh_vrf, nh_type, &ipaddr))
192 flog_warn(
193 EC_LIB_NB_CB_CONFIG_VALIDATE,
194 "Warning!! Local connected address is configured as Gateway IP((%s))",
195 yang_dnode_get_string(args->dnode,
196 "./gateway"));
197 nh = static_add_nexthop(pn, nh_type, &ipaddr, ifname, nh_vrf,
198 0);
199 nb_running_set_entry(args->dnode, nh);
200 break;
201 }
202
203 return NB_OK;
204 }
205
206 static bool static_nexthop_destroy(struct nb_cb_destroy_args *args)
207 {
208 struct static_nexthop *nh;
209
210 switch (args->event) {
211 case NB_EV_VALIDATE:
212 case NB_EV_PREPARE:
213 case NB_EV_ABORT:
214 break;
215 case NB_EV_APPLY:
216 nh = nb_running_unset_entry(args->dnode);
217 static_delete_nexthop(nh);
218 break;
219 }
220
221 return NB_OK;
222 }
223
224 static int nexthop_mpls_label_stack_entry_create(struct nb_cb_create_args *args)
225 {
226 struct static_nexthop *nh;
227 uint32_t pos;
228 uint8_t index;
229
230 switch (args->event) {
231 case NB_EV_VALIDATE:
232 if (!mpls_enabled) {
233 snprintf(
234 args->errmsg, args->errmsg_len,
235 "%% MPLS not turned on in kernel ignoring static route");
236 return NB_ERR_VALIDATION;
237 }
238 break;
239 case NB_EV_PREPARE:
240 case NB_EV_ABORT:
241 break;
242 case NB_EV_APPLY:
243 nh = nb_running_get_entry(args->dnode, NULL, true);
244 pos = yang_get_list_pos(args->dnode);
245 if (!pos) {
246 flog_warn(EC_LIB_NB_CB_CONFIG_APPLY,
247 "libyang returns invalid label position");
248 return NB_ERR;
249 }
250 /* Mapping to array = list-index -1 */
251 index = pos - 1;
252 nh->snh_label.label[index] = 0;
253 nh->snh_label.num_labels++;
254 break;
255 }
256
257 return NB_OK;
258 }
259
260 static int
261 nexthop_mpls_label_stack_entry_destroy(struct nb_cb_destroy_args *args)
262 {
263 struct static_nexthop *nh;
264 uint32_t pos;
265 uint8_t index;
266
267 switch (args->event) {
268 case NB_EV_VALIDATE:
269 case NB_EV_PREPARE:
270 case NB_EV_ABORT:
271 break;
272 case NB_EV_APPLY:
273 nh = nb_running_get_entry(args->dnode, NULL, true);
274 pos = yang_get_list_pos(args->dnode);
275 if (!pos) {
276 flog_warn(EC_LIB_NB_CB_CONFIG_APPLY,
277 "libyang returns invalid label position");
278 return NB_ERR;
279 }
280 index = pos - 1;
281 nh->snh_label.label[index] = 0;
282 nh->snh_label.num_labels--;
283 break;
284 }
285
286 return NB_OK;
287 }
288
289 static int static_nexthop_mpls_label_modify(struct nb_cb_modify_args *args)
290 {
291 struct static_nexthop *nh;
292 uint32_t pos;
293 uint8_t index;
294
295 nh = nb_running_get_entry(args->dnode, NULL, true);
296 pos = yang_get_list_pos(lyd_parent(args->dnode));
297 if (!pos) {
298 flog_warn(EC_LIB_NB_CB_CONFIG_APPLY,
299 "libyang returns invalid label position");
300 return NB_ERR;
301 }
302 /* Mapping to array = list-index -1 */
303 index = pos - 1;
304 nh->snh_label.label[index] = yang_dnode_get_uint32(args->dnode, NULL);
305
306 return NB_OK;
307 }
308
309 static int static_nexthop_onlink_modify(struct nb_cb_modify_args *args)
310 {
311 struct static_nexthop *nh;
312 enum static_nh_type nh_type;
313
314 switch (args->event) {
315 case NB_EV_VALIDATE:
316 nh_type = yang_dnode_get_enum(args->dnode, "../nh-type");
317 if ((nh_type != STATIC_IPV4_GATEWAY_IFNAME)
318 && (nh_type != STATIC_IPV6_GATEWAY_IFNAME)) {
319 snprintf(
320 args->errmsg, args->errmsg_len,
321 "nexthop type is not the ipv4 or ipv6 interface type");
322 return NB_ERR_VALIDATION;
323 }
324 break;
325 case NB_EV_PREPARE:
326 case NB_EV_ABORT:
327 break;
328 case NB_EV_APPLY:
329 nh = nb_running_get_entry(args->dnode, NULL, true);
330 nh->onlink = yang_dnode_get_bool(args->dnode, NULL);
331 break;
332 }
333
334 return NB_OK;
335 }
336
337 static int static_nexthop_color_modify(struct nb_cb_modify_args *args)
338 {
339 struct static_nexthop *nh;
340
341 nh = nb_running_get_entry(args->dnode, NULL, true);
342 nh->color = yang_dnode_get_uint32(args->dnode, NULL);
343
344 return NB_OK;
345 }
346
347 static int static_nexthop_color_destroy(struct nb_cb_destroy_args *args)
348 {
349 struct static_nexthop *nh;
350
351 nh = nb_running_unset_entry(args->dnode);
352 nh->color = 0;
353
354 return NB_OK;
355 }
356
357 static int static_nexthop_bh_type_modify(struct nb_cb_modify_args *args)
358 {
359 struct static_nexthop *nh;
360 enum static_nh_type nh_type;
361
362 switch (args->event) {
363 case NB_EV_VALIDATE:
364 nh_type = yang_dnode_get_enum(args->dnode, "../nh-type");
365 if (nh_type != STATIC_BLACKHOLE) {
366 snprintf(args->errmsg, args->errmsg_len,
367 "nexthop type is not the blackhole type");
368 return NB_ERR_VALIDATION;
369 }
370 break;
371 case NB_EV_PREPARE:
372 case NB_EV_ABORT:
373 break;
374 case NB_EV_APPLY:
375 nh = nb_running_get_entry(args->dnode, NULL, true);
376 nh->bh_type = yang_dnode_get_enum(args->dnode, NULL);
377 break;
378 }
379
380 return NB_OK;
381 }
382
383 void routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_apply_finish(
384 struct nb_cb_apply_finish_args *args)
385 {
386 struct static_nexthop *nh;
387
388 nh = nb_running_get_entry(args->dnode, NULL, true);
389
390 static_install_nexthop(nh);
391 }
392
393 void routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_apply_finish(
394 struct nb_cb_apply_finish_args *args)
395 {
396 struct static_nexthop *nh;
397
398 nh = nb_running_get_entry(args->dnode, NULL, true);
399
400 static_install_nexthop(nh);
401 }
402
403 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_pre_validate(
404 struct nb_cb_pre_validate_args *args)
405 {
406 const struct lyd_node *mls_dnode;
407 uint32_t count;
408
409 mls_dnode = yang_dnode_get(args->dnode, "./mpls-label-stack");
410 count = yang_get_list_elements_count(lyd_child(mls_dnode));
411
412 if (count > MPLS_MAX_LABELS) {
413 snprintf(args->errmsg, args->errmsg_len,
414 "Too many labels, Enter %d or fewer",
415 MPLS_MAX_LABELS);
416 return NB_ERR_VALIDATION;
417 }
418 return NB_OK;
419 }
420
421 int routing_control_plane_protocols_name_validate(
422 struct nb_cb_create_args *args)
423 {
424 const char *name;
425
426 name = yang_dnode_get_string(args->dnode, "./name");
427 if (!strmatch(name, "staticd")) {
428 snprintf(args->errmsg, args->errmsg_len,
429 "static routing supports only one instance with name staticd");
430 return NB_ERR_VALIDATION;
431 }
432 return NB_OK;
433 }
434 /*
435 * XPath:
436 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list
437 */
438 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_create(
439 struct nb_cb_create_args *args)
440 {
441 struct vrf *vrf;
442 struct static_vrf *s_vrf;
443 struct route_node *rn;
444 const struct lyd_node *vrf_dnode;
445 struct prefix prefix;
446 const char *afi_safi;
447 afi_t prefix_afi;
448 afi_t afi;
449 safi_t safi;
450
451 switch (args->event) {
452 case NB_EV_VALIDATE:
453 yang_dnode_get_prefix(&prefix, args->dnode, "./prefix");
454 afi_safi = yang_dnode_get_string(args->dnode, "./afi-safi");
455 yang_afi_safi_identity2value(afi_safi, &afi, &safi);
456 prefix_afi = family2afi(prefix.family);
457 if (afi != prefix_afi) {
458 flog_warn(
459 EC_LIB_NB_CB_CONFIG_VALIDATE,
460 "route node %s creation failed",
461 yang_dnode_get_string(args->dnode, "./prefix"));
462 return NB_ERR_VALIDATION;
463 }
464 break;
465 case NB_EV_PREPARE:
466 case NB_EV_ABORT:
467 break;
468 case NB_EV_APPLY:
469 vrf_dnode = yang_dnode_get_parent(args->dnode,
470 "control-plane-protocol");
471 vrf = nb_running_get_entry(vrf_dnode, NULL, true);
472 s_vrf = vrf->info;
473
474 yang_dnode_get_prefix(&prefix, args->dnode, "./prefix");
475 afi_safi = yang_dnode_get_string(args->dnode, "./afi-safi");
476 yang_afi_safi_identity2value(afi_safi, &afi, &safi);
477
478 rn = static_add_route(afi, safi, &prefix, NULL, s_vrf);
479 if (vrf->vrf_id == VRF_UNKNOWN)
480 snprintf(
481 args->errmsg, args->errmsg_len,
482 "Static Route to %s not installed currently because dependent config not fully available",
483 yang_dnode_get_string(args->dnode, "./prefix"));
484 nb_running_set_entry(args->dnode, rn);
485 break;
486 }
487 return NB_OK;
488 }
489
490 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_destroy(
491 struct nb_cb_destroy_args *args)
492 {
493 struct route_node *rn;
494
495 switch (args->event) {
496 case NB_EV_VALIDATE:
497 case NB_EV_PREPARE:
498 case NB_EV_ABORT:
499 break;
500 case NB_EV_APPLY:
501 rn = nb_running_unset_entry(args->dnode);
502 static_del_route(rn);
503 break;
504 }
505 return NB_OK;
506 }
507
508 /*
509 * XPath:
510 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list
511 */
512 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_create(
513 struct nb_cb_create_args *args)
514 {
515 return static_path_list_create(args);
516 }
517
518 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_destroy(
519 struct nb_cb_destroy_args *args)
520 {
521 return static_path_list_destroy(args);
522 }
523
524 /*
525 * XPath:
526 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/tag
527 */
528 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_tag_modify(
529 struct nb_cb_modify_args *args)
530 {
531 return static_path_list_tag_modify(args);
532 }
533
534 /*
535 * XPath:
536 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop
537 */
538 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_create(
539 struct nb_cb_create_args *args)
540 {
541 return static_nexthop_create(args);
542 }
543
544 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_destroy(
545 struct nb_cb_destroy_args *args)
546 {
547 return static_nexthop_destroy(args);
548 }
549
550 /*
551 * XPath:
552 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/bh-type
553 */
554 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_bh_type_modify(
555 struct nb_cb_modify_args *args)
556 {
557 return static_nexthop_bh_type_modify(args);
558 }
559
560 /*
561 * XPath:
562 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/onlink
563 */
564 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_onlink_modify(
565 struct nb_cb_modify_args *args)
566 {
567 return static_nexthop_onlink_modify(args);
568 }
569
570 /*
571 * XPath:
572 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/srte-color
573 */
574 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_color_modify(
575 struct nb_cb_modify_args *args)
576 {
577 switch (args->event) {
578 case NB_EV_VALIDATE:
579 case NB_EV_PREPARE:
580 case NB_EV_ABORT:
581 break;
582 case NB_EV_APPLY:
583 if (static_nexthop_color_modify(args) != NB_OK)
584 return NB_ERR;
585
586 break;
587 }
588 return NB_OK;
589 }
590
591 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_color_destroy(
592 struct nb_cb_destroy_args *args)
593 {
594 switch (args->event) {
595 case NB_EV_VALIDATE:
596 case NB_EV_PREPARE:
597 case NB_EV_ABORT:
598 break;
599 case NB_EV_APPLY:
600 if (static_nexthop_color_destroy(args) != NB_OK)
601 return NB_ERR;
602 break;
603 }
604 return NB_OK;
605 }
606
607 /*
608 * XPath:
609 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry
610 */
611 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create(
612 struct nb_cb_create_args *args)
613 {
614 return nexthop_mpls_label_stack_entry_create(args);
615 }
616
617 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_destroy(
618 struct nb_cb_destroy_args *args)
619 {
620 return nexthop_mpls_label_stack_entry_destroy(args);
621 }
622
623 /*
624 * XPath:
625 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/label
626 */
627 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_modify(
628 struct nb_cb_modify_args *args)
629 {
630 switch (args->event) {
631 case NB_EV_VALIDATE:
632 case NB_EV_PREPARE:
633 case NB_EV_ABORT:
634 break;
635 case NB_EV_APPLY:
636 if (static_nexthop_mpls_label_modify(args) != NB_OK)
637 return NB_ERR;
638 break;
639 }
640 return NB_OK;
641 }
642
643 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_destroy(
644 struct nb_cb_destroy_args *args)
645 {
646 /*
647 * No operation is required in this call back.
648 * nexthop_mpls_label_stack_entry_destroy() will take care
649 * to reset the label vaue.
650 */
651 switch (args->event) {
652 case NB_EV_VALIDATE:
653 case NB_EV_PREPARE:
654 case NB_EV_ABORT:
655 case NB_EV_APPLY:
656 break;
657 }
658 return NB_OK;
659 }
660
661 /*
662 * XPath:
663 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/ttl
664 */
665 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_modify(
666 struct nb_cb_modify_args *args)
667 {
668 switch (args->event) {
669 case NB_EV_VALIDATE:
670 case NB_EV_PREPARE:
671 case NB_EV_ABORT:
672 case NB_EV_APPLY:
673 break;
674 }
675
676 return NB_OK;
677 }
678
679 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_destroy(
680 struct nb_cb_destroy_args *args)
681 {
682 switch (args->event) {
683 case NB_EV_VALIDATE:
684 case NB_EV_PREPARE:
685 case NB_EV_ABORT:
686 case NB_EV_APPLY:
687 break;
688 }
689
690 return NB_OK;
691 }
692
693 /*
694 * XPath:
695 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/traffic-class
696 */
697 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_modify(
698 struct nb_cb_modify_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 break;
706 }
707
708 return NB_OK;
709 }
710
711 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_destroy(
712 struct nb_cb_destroy_args *args)
713 {
714 switch (args->event) {
715 case NB_EV_VALIDATE:
716 case NB_EV_PREPARE:
717 case NB_EV_ABORT:
718 case NB_EV_APPLY:
719 break;
720 }
721
722 return NB_OK;
723 }
724
725 /*
726 * XPath:
727 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list
728 */
729 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_create(
730 struct nb_cb_create_args *args)
731 {
732 struct static_vrf *s_vrf;
733 struct route_node *rn;
734 struct route_node *src_rn;
735 struct prefix_ipv6 src_prefix = {};
736 struct stable_info *info;
737 afi_t afi;
738 safi_t safi = SAFI_UNICAST;
739
740 switch (args->event) {
741 case NB_EV_VALIDATE:
742 case NB_EV_PREPARE:
743 case NB_EV_ABORT:
744 break;
745 case NB_EV_APPLY:
746 rn = nb_running_get_entry(args->dnode, NULL, true);
747 info = route_table_get_info(rn->table);
748 s_vrf = info->svrf;
749 yang_dnode_get_ipv6p(&src_prefix, args->dnode, "./src-prefix");
750 afi = family2afi(src_prefix.family);
751 src_rn =
752 static_add_route(afi, safi, &rn->p, &src_prefix, s_vrf);
753 nb_running_set_entry(args->dnode, src_rn);
754 break;
755 }
756 return NB_OK;
757 }
758
759 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_destroy(
760 struct nb_cb_destroy_args *args)
761 {
762 struct route_node *src_rn;
763
764 switch (args->event) {
765 case NB_EV_VALIDATE:
766 case NB_EV_PREPARE:
767 case NB_EV_ABORT:
768 break;
769 case NB_EV_APPLY:
770 src_rn = nb_running_unset_entry(args->dnode);
771 static_del_route(src_rn);
772 break;
773 }
774
775 return NB_OK;
776 }
777
778 /*
779 * XPath:
780 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list
781 */
782 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_create(
783 struct nb_cb_create_args *args)
784 {
785 return static_path_list_create(args);
786 }
787
788 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_destroy(
789 struct nb_cb_destroy_args *args)
790 {
791 return static_path_list_destroy(args);
792 }
793
794 /*
795 * XPath:
796 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/tag
797 */
798 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_tag_modify(
799 struct nb_cb_modify_args *args)
800 {
801 return static_path_list_tag_modify(args);
802 }
803
804 /*
805 * XPath:
806 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop
807 */
808 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_create(
809 struct nb_cb_create_args *args)
810 {
811 return static_nexthop_create(args);
812 }
813
814 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_destroy(
815 struct nb_cb_destroy_args *args)
816 {
817 return static_nexthop_destroy(args);
818 }
819
820 /*
821 * XPath:
822 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/bh-type
823 */
824 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_modify(
825 struct nb_cb_modify_args *args)
826 {
827 return static_nexthop_bh_type_modify(args);
828 }
829
830 /*
831 * XPath:
832 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/onlink
833 */
834 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_modify(
835 struct nb_cb_modify_args *args)
836 {
837 return static_nexthop_onlink_modify(args);
838 }
839
840 /*
841 * XPath:
842 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/srte-color
843 */
844 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_modify(
845 struct nb_cb_modify_args *args)
846 {
847 switch (args->event) {
848 case NB_EV_VALIDATE:
849 case NB_EV_PREPARE:
850 case NB_EV_ABORT:
851 break;
852 case NB_EV_APPLY:
853 if (static_nexthop_color_modify(args) != NB_OK)
854 return NB_ERR;
855
856 break;
857 }
858 return NB_OK;
859 }
860
861
862 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_destroy(
863 struct nb_cb_destroy_args *args)
864 {
865 switch (args->event) {
866 case NB_EV_VALIDATE:
867 case NB_EV_PREPARE:
868 case NB_EV_ABORT:
869 break;
870 case NB_EV_APPLY:
871 if (static_nexthop_color_destroy(args) != NB_OK)
872 return NB_ERR;
873 break;
874 }
875 return NB_OK;
876 }
877
878 /*
879 * XPath:
880 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry
881 */
882 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create(
883 struct nb_cb_create_args *args)
884 {
885 return nexthop_mpls_label_stack_entry_create(args);
886 }
887
888 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_destroy(
889 struct nb_cb_destroy_args *args)
890 {
891 return nexthop_mpls_label_stack_entry_destroy(args);
892 }
893
894 /*
895 * XPath:
896 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/label
897 */
898 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_modify(
899 struct nb_cb_modify_args *args)
900 {
901 switch (args->event) {
902 case NB_EV_VALIDATE:
903 case NB_EV_PREPARE:
904 case NB_EV_ABORT:
905 break;
906 case NB_EV_APPLY:
907 if (static_nexthop_mpls_label_modify(args) != NB_OK)
908 return NB_ERR;
909 break;
910 }
911 return NB_OK;
912 }
913
914 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_destroy(
915 struct nb_cb_destroy_args *args)
916 {
917 /*
918 * No operation is required in this call back.
919 * nexthop_mpls_label_stack_entry_destroy() will take care
920 * to reset the label vaue.
921 */
922 switch (args->event) {
923 case NB_EV_VALIDATE:
924 case NB_EV_PREPARE:
925 case NB_EV_ABORT:
926 case NB_EV_APPLY:
927 break;
928 }
929 return NB_OK;
930 }
931
932 /*
933 * XPath:
934 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/ttl
935 */
936 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_modify(
937 struct nb_cb_modify_args *args)
938 {
939 switch (args->event) {
940 case NB_EV_VALIDATE:
941 case NB_EV_PREPARE:
942 case NB_EV_ABORT:
943 case NB_EV_APPLY:
944 break;
945 }
946
947 return NB_OK;
948 }
949
950 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_destroy(
951 struct nb_cb_destroy_args *args)
952 {
953 switch (args->event) {
954 case NB_EV_VALIDATE:
955 case NB_EV_PREPARE:
956 case NB_EV_ABORT:
957 case NB_EV_APPLY:
958 break;
959 }
960
961 return NB_OK;
962 }
963
964 /*
965 * XPath:
966 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/traffic-class
967 */
968 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_modify(
969 struct nb_cb_modify_args *args)
970 {
971 switch (args->event) {
972 case NB_EV_VALIDATE:
973 case NB_EV_PREPARE:
974 case NB_EV_ABORT:
975 case NB_EV_APPLY:
976 break;
977 }
978
979 return NB_OK;
980 }
981
982 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_destroy(
983 struct nb_cb_destroy_args *args)
984 {
985 switch (args->event) {
986 case NB_EV_VALIDATE:
987 case NB_EV_PREPARE:
988 case NB_EV_ABORT:
989 case NB_EV_APPLY:
990 break;
991 }
992
993 return NB_OK;
994 }