]> git.proxmox.com Git - mirror_frr.git/blob - staticd/static_nb_config.c
bgpd: Fix IP-VRF ext-comm check for MACIP routes
[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 "northbound.h"
20 #include "libfrr.h"
21 #include "log.h"
22 #include "lib_errors.h"
23 #include "prefix.h"
24 #include "table.h"
25 #include "vrf.h"
26 #include "nexthop.h"
27 #include "srcdest_table.h"
28
29 #include "static_vrf.h"
30 #include "static_routes.h"
31 #include "static_nb.h"
32
33
34 static int static_path_list_create(struct nb_cb_create_args *args)
35 {
36 struct route_node *rn;
37 struct static_path *pn;
38 const struct lyd_node *vrf_dnode;
39 const char *vrf;
40 uint8_t distance;
41 uint32_t table_id;
42
43 switch (args->event) {
44 case NB_EV_VALIDATE:
45 vrf_dnode = yang_dnode_get_parent(args->dnode,
46 "control-plane-protocol");
47 vrf = yang_dnode_get_string(vrf_dnode, "./vrf");
48 table_id = yang_dnode_get_uint32(args->dnode, "./table-id");
49
50 /*
51 * TableId is not applicable for VRF. Consider the case of
52 * l3mdev, there is one uint32_t space to work with.
53 * A l3mdev device points at a specific table that it
54 * relates to and a set of interfaces it belongs to.
55 */
56 if (table_id && (strcmp(vrf, vrf_get_default_name()) != 0)
57 && !vrf_is_backend_netns()) {
58 snprintf(
59 args->errmsg, args->errmsg_len,
60 "%% table param only available when running on netns-based vrfs");
61 return NB_ERR_VALIDATION;
62 }
63 break;
64 case NB_EV_ABORT:
65 case NB_EV_PREPARE:
66 break;
67 case NB_EV_APPLY:
68 rn = nb_running_get_entry(args->dnode, NULL, true);
69 distance = yang_dnode_get_uint8(args->dnode, "./distance");
70 table_id = yang_dnode_get_uint32(args->dnode, "./table-id");
71 pn = static_add_path(rn, table_id, distance);
72 nb_running_set_entry(args->dnode, pn);
73 }
74
75 return NB_OK;
76 }
77
78 static void static_path_list_destroy(struct nb_cb_destroy_args *args,
79 const struct lyd_node *rn_dnode,
80 struct stable_info *info)
81 {
82 struct route_node *rn;
83 struct static_path *pn;
84
85 pn = nb_running_unset_entry(args->dnode);
86 rn = nb_running_get_entry(rn_dnode, NULL, true);
87 static_del_path(rn, pn, info->safi, info->svrf);
88 }
89
90 static void static_path_list_tag_modify(struct nb_cb_modify_args *args,
91 const struct lyd_node *rn_dnode,
92 struct stable_info *info)
93 {
94 struct static_path *pn;
95 struct route_node *rn;
96 route_tag_t tag;
97
98 tag = yang_dnode_get_uint32(args->dnode, NULL);
99 pn = nb_running_get_entry(args->dnode, NULL, true);
100 pn->tag = tag;
101 rn = nb_running_get_entry(rn_dnode, NULL, true);
102
103 static_install_path(rn, pn, info->safi, info->svrf);
104 }
105
106 struct nexthop_iter {
107 int count;
108 bool blackhole;
109 };
110
111 static int nexthop_iter_cb(const struct lyd_node *dnode, void *arg)
112 {
113 struct nexthop_iter *iter = arg;
114 int nh_type;
115
116 nh_type = yang_dnode_get_enum(dnode, "./nh-type");
117
118 if (nh_type == STATIC_BLACKHOLE)
119 iter->blackhole = true;
120
121 iter->count++;
122
123 return YANG_ITER_CONTINUE;
124 }
125
126 static bool static_nexthop_create(struct nb_cb_create_args *args,
127 const struct lyd_node *rn_dnode,
128 struct stable_info *info)
129 {
130 const struct lyd_node *pn_dnode;
131 struct nexthop_iter iter;
132 struct route_node *rn;
133 struct static_path *pn;
134 struct ipaddr ipaddr;
135 struct static_nexthop *nh;
136 int nh_type;
137 const char *ifname;
138 const char *nh_vrf;
139
140 switch (args->event) {
141 case NB_EV_VALIDATE:
142 ifname = yang_dnode_get_string(args->dnode, "./interface");
143 if (ifname != NULL) {
144 if (strcasecmp(ifname, "Null0") == 0
145 || strcasecmp(ifname, "reject") == 0
146 || strcasecmp(ifname, "blackhole") == 0) {
147 snprintf(args->errmsg, args->errmsg_len,
148 "%s: Nexthop interface name can not be from reserved keywords(Null0, reject, blackhole)",
149 ifname);
150 return NB_ERR_VALIDATION;
151 }
152 }
153
154 iter.count = 0;
155 iter.blackhole = false;
156
157 pn_dnode = yang_dnode_get_parent(args->dnode, "path-list");
158 yang_dnode_iterate(nexthop_iter_cb, &iter, pn_dnode,
159 "./frr-nexthops/nexthop");
160
161 if (iter.blackhole && iter.count > 1) {
162 snprintf(
163 args->errmsg, args->errmsg_len,
164 "Route can not have blackhole and non-blackhole nexthops simultaneously");
165 return NB_ERR_VALIDATION;
166 }
167 break;
168 case NB_EV_PREPARE:
169 case NB_EV_ABORT:
170 break;
171 case NB_EV_APPLY:
172 yang_dnode_get_ip(&ipaddr, args->dnode, "./gateway");
173 nh_type = yang_dnode_get_enum(args->dnode, "./nh-type");
174 ifname = yang_dnode_get_string(args->dnode, "./interface");
175 nh_vrf = yang_dnode_get_string(args->dnode, "./vrf");
176 pn = nb_running_get_entry(args->dnode, NULL, true);
177 rn = nb_running_get_entry(rn_dnode, NULL, true);
178
179 if (!static_add_nexthop_validate(nh_vrf, nh_type, &ipaddr))
180 flog_warn(
181 EC_LIB_NB_CB_CONFIG_VALIDATE,
182 "Warning!! Local connected address is configured as Gateway IP((%s))",
183 yang_dnode_get_string(args->dnode,
184 "./gateway"));
185 nh = static_add_nexthop(rn, pn, info->safi, info->svrf, nh_type,
186 &ipaddr, ifname, nh_vrf, 0);
187 nb_running_set_entry(args->dnode, nh);
188 break;
189 }
190
191 return NB_OK;
192 }
193
194 static bool static_nexthop_destroy(struct nb_cb_destroy_args *args,
195 const struct lyd_node *rn_dnode,
196 struct stable_info *info)
197 {
198 struct route_node *rn;
199 struct static_path *pn;
200 const struct lyd_node *pn_dnode;
201 struct static_nexthop *nh;
202 int ret;
203
204 nh = nb_running_unset_entry(args->dnode);
205 pn_dnode = yang_dnode_get_parent(args->dnode, "path-list");
206 pn = nb_running_get_entry(pn_dnode, NULL, true);
207 rn = nb_running_get_entry(rn_dnode, NULL, true);
208
209 ret = static_delete_nexthop(rn, pn, info->safi, info->svrf, nh);
210 if (!ret) {
211 char buf[SRCDEST2STR_BUFFER];
212
213 flog_warn(EC_LIB_NB_CB_CONFIG_APPLY,
214 "%s : nh [%d:%s:%s:%s] nexthop destroy failed",
215 srcdest_rnode2str(rn, buf, sizeof(buf)),
216 yang_dnode_get_enum(args->dnode, "./nh-type"),
217 yang_dnode_get_string(args->dnode, "./interface"),
218 yang_dnode_get_string(args->dnode, "./gateway"),
219 yang_dnode_get_string(args->dnode, "./vrf"));
220 return NB_ERR;
221 }
222
223 return NB_OK;
224 }
225
226 static int nexthop_mpls_label_stack_entry_create(struct nb_cb_create_args *args)
227 {
228 struct static_nexthop *nh;
229 uint32_t pos;
230 uint8_t index;
231
232 switch (args->event) {
233 case NB_EV_VALIDATE:
234 if (!mpls_enabled) {
235 snprintf(
236 args->errmsg, args->errmsg_len,
237 "%% MPLS not turned on in kernel ignoring static route");
238 return NB_ERR_VALIDATION;
239 }
240 break;
241 case NB_EV_PREPARE:
242 case NB_EV_ABORT:
243 break;
244 case NB_EV_APPLY:
245 nh = nb_running_get_entry(args->dnode, NULL, true);
246 pos = yang_get_list_pos(args->dnode);
247 if (!pos) {
248 flog_warn(EC_LIB_NB_CB_CONFIG_APPLY,
249 "libyang returns invalid label position");
250 return NB_ERR;
251 }
252 /* Mapping to array = list-index -1 */
253 index = pos - 1;
254 nh->snh_label.label[index] = 0;
255 nh->snh_label.num_labels++;
256 break;
257 }
258
259 return NB_OK;
260 }
261
262 static int
263 nexthop_mpls_label_stack_entry_destroy(struct nb_cb_destroy_args *args)
264 {
265 struct static_nexthop *nh;
266 uint32_t pos;
267 uint8_t index;
268
269 switch (args->event) {
270 case NB_EV_VALIDATE:
271 case NB_EV_PREPARE:
272 case NB_EV_ABORT:
273 break;
274 case NB_EV_APPLY:
275 nh = nb_running_get_entry(args->dnode, NULL, true);
276 pos = yang_get_list_pos(args->dnode);
277 if (!pos) {
278 flog_warn(EC_LIB_NB_CB_CONFIG_APPLY,
279 "libyang returns invalid label position");
280 return NB_ERR;
281 }
282 index = pos - 1;
283 nh->snh_label.label[index] = 0;
284 nh->snh_label.num_labels--;
285 break;
286 }
287
288 return NB_OK;
289 }
290
291 static int static_nexthop_mpls_label_modify(struct nb_cb_modify_args *args)
292 {
293 struct static_nexthop *nh;
294 uint32_t pos;
295 uint8_t index;
296
297 nh = nb_running_get_entry(args->dnode, NULL, true);
298 pos = yang_get_list_pos(args->dnode->parent);
299 if (!pos) {
300 flog_warn(EC_LIB_NB_CB_CONFIG_APPLY,
301 "libyang returns invalid label position");
302 return NB_ERR;
303 }
304 /* Mapping to array = list-index -1 */
305 index = pos - 1;
306 nh->snh_label.label[index] = yang_dnode_get_uint32(args->dnode, NULL);
307
308 return NB_OK;
309 }
310
311 static int static_nexthop_onlink_modify(struct nb_cb_modify_args *args)
312 {
313 struct static_nexthop *nh;
314 static_types nh_type;
315
316 switch (args->event) {
317 case NB_EV_VALIDATE:
318 nh_type = yang_dnode_get_enum(args->dnode, "../nh-type");
319 if ((nh_type != STATIC_IPV4_GATEWAY_IFNAME)
320 && (nh_type != STATIC_IPV6_GATEWAY_IFNAME)) {
321 snprintf(
322 args->errmsg, args->errmsg_len,
323 "nexthop type is not the ipv4 or ipv6 interface type");
324 return NB_ERR_VALIDATION;
325 }
326 break;
327 case NB_EV_PREPARE:
328 case NB_EV_ABORT:
329 break;
330 case NB_EV_APPLY:
331 nh = nb_running_get_entry(args->dnode, NULL, true);
332 nh->onlink = yang_dnode_get_bool(args->dnode, NULL);
333 break;
334 }
335
336 return NB_OK;
337 }
338
339 static int static_nexthop_color_modify(struct nb_cb_modify_args *args)
340 {
341 struct static_nexthop *nh;
342
343 nh = nb_running_get_entry(args->dnode, NULL, true);
344 nh->color = yang_dnode_get_uint32(args->dnode, NULL);
345
346 return NB_OK;
347 }
348
349 static int static_nexthop_color_destroy(struct nb_cb_destroy_args *args)
350 {
351 struct static_nexthop *nh;
352
353 nh = nb_running_unset_entry(args->dnode);
354 nh->color = 0;
355
356 return NB_OK;
357 }
358
359 static int static_nexthop_bh_type_modify(struct nb_cb_modify_args *args)
360 {
361 struct static_nexthop *nh;
362 static_types nh_type;
363
364 switch (args->event) {
365 case NB_EV_VALIDATE:
366 nh_type = yang_dnode_get_enum(args->dnode, "../nh-type");
367 if (nh_type != STATIC_BLACKHOLE) {
368 snprintf(args->errmsg, args->errmsg_len,
369 "nexthop type is not the blackhole type");
370 return NB_ERR_VALIDATION;
371 }
372 break;
373 case NB_EV_PREPARE:
374 case NB_EV_ABORT:
375 break;
376 case NB_EV_APPLY:
377 nh = nb_running_get_entry(args->dnode, NULL, true);
378 nh->bh_type = yang_dnode_get_enum(args->dnode, NULL);
379 break;
380 }
381
382 return NB_OK;
383 }
384
385
386 void routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_apply_finish(
387 struct nb_cb_apply_finish_args *args)
388 {
389 struct static_nexthop *nh;
390 struct static_path *pn;
391 struct route_node *rn;
392 const struct lyd_node *pn_dnode;
393 const struct lyd_node *rn_dnode;
394 const char *ifname;
395 const char *nh_vrf;
396 struct stable_info *info;
397 int nh_type;
398
399 nh_type = yang_dnode_get_enum(args->dnode, "./nh-type");
400 ifname = yang_dnode_get_string(args->dnode, "./interface");
401 nh_vrf = yang_dnode_get_string(args->dnode, "./vrf");
402
403 nh = nb_running_get_entry(args->dnode, NULL, true);
404
405 pn_dnode = yang_dnode_get_parent(args->dnode, "path-list");
406 pn = nb_running_get_entry(pn_dnode, NULL, true);
407
408 rn_dnode = yang_dnode_get_parent(pn_dnode, "route-list");
409 rn = nb_running_get_entry(rn_dnode, NULL, true);
410 info = route_table_get_info(rn->table);
411
412 static_install_nexthop(rn, pn, nh, info->safi, info->svrf, ifname,
413 nh_type, nh_vrf);
414 }
415
416
417 void routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_apply_finish(
418 struct nb_cb_apply_finish_args *args)
419 {
420 struct static_nexthop *nh;
421 struct static_path *pn;
422 struct route_node *rn;
423 struct route_node *src_rn;
424 const struct lyd_node *pn_dnode;
425 const struct lyd_node *rn_dnode;
426 const struct lyd_node *src_dnode;
427 const char *ifname;
428 const char *nh_vrf;
429 struct stable_info *info;
430 int nh_type;
431
432 nh_type = yang_dnode_get_enum(args->dnode, "./nh-type");
433 ifname = yang_dnode_get_string(args->dnode, "./interface");
434 nh_vrf = yang_dnode_get_string(args->dnode, "./vrf");
435
436 nh = nb_running_get_entry(args->dnode, NULL, true);
437
438 pn_dnode = yang_dnode_get_parent(args->dnode, "path-list");
439 pn = nb_running_get_entry(pn_dnode, NULL, true);
440
441 src_dnode = yang_dnode_get_parent(pn_dnode, "src-list");
442 src_rn = nb_running_get_entry(src_dnode, NULL, true);
443
444 rn_dnode = yang_dnode_get_parent(src_dnode, "route-list");
445 rn = nb_running_get_entry(rn_dnode, NULL, true);
446 info = route_table_get_info(rn->table);
447
448 static_install_nexthop(src_rn, pn, nh, info->safi, info->svrf, ifname,
449 nh_type, nh_vrf);
450 }
451 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_pre_validate(
452 struct nb_cb_pre_validate_args *args)
453 {
454 const struct lyd_node *mls_dnode;
455 uint32_t count;
456
457 mls_dnode = yang_dnode_get(args->dnode, "./mpls-label-stack");
458 count = yang_get_list_elements_count(yang_dnode_get_child(mls_dnode));
459
460 if (count > MPLS_MAX_LABELS) {
461 snprintf(args->errmsg, args->errmsg_len,
462 "Too many labels, Enter %d or fewer",
463 MPLS_MAX_LABELS);
464 return NB_ERR_VALIDATION;
465 }
466 return NB_OK;
467 }
468
469 int routing_control_plane_protocols_name_validate(
470 struct nb_cb_create_args *args)
471 {
472 const char *name;
473
474 name = yang_dnode_get_string(args->dnode, "./name");
475 if (!strmatch(name, "staticd")) {
476 snprintf(args->errmsg, args->errmsg_len,
477 "static routing supports only one instance with name staticd");
478 return NB_ERR_VALIDATION;
479 }
480 return NB_OK;
481 }
482 /*
483 * XPath:
484 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list
485 */
486 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_create(
487 struct nb_cb_create_args *args)
488 {
489 struct vrf *vrf;
490 struct static_vrf *s_vrf;
491 struct route_node *rn;
492 const struct lyd_node *vrf_dnode;
493 struct prefix prefix;
494 const char *afi_safi;
495 afi_t prefix_afi;
496 afi_t afi;
497 safi_t safi;
498
499 switch (args->event) {
500 case NB_EV_VALIDATE:
501 yang_dnode_get_prefix(&prefix, args->dnode, "./prefix");
502 afi_safi = yang_dnode_get_string(args->dnode, "./afi-safi");
503 yang_afi_safi_identity2value(afi_safi, &afi, &safi);
504 prefix_afi = family2afi(prefix.family);
505 if (afi != prefix_afi) {
506 flog_warn(
507 EC_LIB_NB_CB_CONFIG_VALIDATE,
508 "route node %s creation failed",
509 yang_dnode_get_string(args->dnode, "./prefix"));
510 return NB_ERR_VALIDATION;
511 }
512 break;
513 case NB_EV_PREPARE:
514 case NB_EV_ABORT:
515 break;
516 case NB_EV_APPLY:
517 vrf_dnode = yang_dnode_get_parent(args->dnode,
518 "control-plane-protocol");
519 vrf = nb_running_get_entry(vrf_dnode, NULL, true);
520 s_vrf = vrf->info;
521
522 yang_dnode_get_prefix(&prefix, args->dnode, "./prefix");
523 afi_safi = yang_dnode_get_string(args->dnode, "./afi-safi");
524 yang_afi_safi_identity2value(afi_safi, &afi, &safi);
525
526 rn = static_add_route(afi, safi, &prefix, NULL, s_vrf);
527 if (!rn) {
528 flog_warn(
529 EC_LIB_NB_CB_CONFIG_APPLY,
530 "route node %s creation failed",
531 yang_dnode_get_string(args->dnode, "./prefix"));
532 return NB_ERR;
533 }
534 if (vrf->vrf_id == VRF_UNKNOWN)
535 snprintf(
536 args->errmsg, args->errmsg_len,
537 "Static Route to %s not installed currently because dependent config not fully available",
538 yang_dnode_get_string(args->dnode, "./prefix"));
539 nb_running_set_entry(args->dnode, rn);
540 break;
541 }
542 return NB_OK;
543 }
544
545 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_destroy(
546 struct nb_cb_destroy_args *args)
547 {
548 struct route_node *rn;
549 struct stable_info *info;
550
551 switch (args->event) {
552 case NB_EV_VALIDATE:
553 case NB_EV_PREPARE:
554 case NB_EV_ABORT:
555 break;
556 case NB_EV_APPLY:
557 rn = nb_running_unset_entry(args->dnode);
558 info = route_table_get_info(rn->table);
559 static_del_route(rn, info->safi, info->svrf);
560 break;
561 }
562 return NB_OK;
563 }
564
565 /*
566 * XPath:
567 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list
568 */
569 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_create(
570 struct nb_cb_create_args *args)
571 {
572 return static_path_list_create(args);
573 }
574
575 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_destroy(
576 struct nb_cb_destroy_args *args)
577 {
578 const struct lyd_node *rn_dnode;
579 struct route_node *rn;
580 struct stable_info *info;
581
582 switch (args->event) {
583 case NB_EV_VALIDATE:
584 case NB_EV_PREPARE:
585 case NB_EV_ABORT:
586 break;
587 case NB_EV_APPLY:
588 rn_dnode = yang_dnode_get_parent(args->dnode, "route-list");
589 rn = nb_running_get_entry(rn_dnode, NULL, true);
590 info = route_table_get_info(rn->table);
591 static_path_list_destroy(args, rn_dnode, info);
592 break;
593 }
594 return NB_OK;
595 }
596
597 /*
598 * XPath:
599 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/tag
600 */
601 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_tag_modify(
602 struct nb_cb_modify_args *args)
603 {
604 struct stable_info *info;
605 struct route_node *rn;
606 const struct lyd_node *rn_dnode;
607
608 switch (args->event) {
609 case NB_EV_VALIDATE:
610 case NB_EV_ABORT:
611 case NB_EV_PREPARE:
612 break;
613 case NB_EV_APPLY:
614 rn_dnode = yang_dnode_get_parent(args->dnode, "route-list");
615 rn = nb_running_get_entry(rn_dnode, NULL, true);
616 info = route_table_get_info(rn->table);
617 static_path_list_tag_modify(args, rn_dnode, info);
618 break;
619 }
620
621 return NB_OK;
622 }
623
624 /*
625 * XPath:
626 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop
627 */
628 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_create(
629 struct nb_cb_create_args *args)
630 {
631 struct route_node *rn;
632 const struct lyd_node *rn_dnode;
633 struct stable_info *info;
634
635 switch (args->event) {
636 case NB_EV_VALIDATE:
637 rn_dnode = yang_dnode_get_parent(args->dnode, "route-list");
638 if (static_nexthop_create(args, rn_dnode, NULL) != NB_OK)
639 return NB_ERR_VALIDATION;
640 break;
641 case NB_EV_PREPARE:
642 case NB_EV_ABORT:
643 break;
644 case NB_EV_APPLY:
645 rn_dnode = yang_dnode_get_parent(args->dnode, "route-list");
646 rn = nb_running_get_entry(rn_dnode, NULL, true);
647 info = route_table_get_info(rn->table);
648
649 if (static_nexthop_create(args, rn_dnode, info) != NB_OK)
650 return NB_ERR_INCONSISTENCY;
651 break;
652 }
653 return NB_OK;
654 }
655
656 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_destroy(
657 struct nb_cb_destroy_args *args)
658 {
659 struct route_node *rn;
660 const struct lyd_node *rn_dnode;
661 struct stable_info *info;
662
663 switch (args->event) {
664 case NB_EV_VALIDATE:
665 case NB_EV_PREPARE:
666 case NB_EV_ABORT:
667 break;
668 case NB_EV_APPLY:
669 rn_dnode = yang_dnode_get_parent(args->dnode, "route-list");
670 rn = nb_running_get_entry(rn_dnode, NULL, true);
671 info = route_table_get_info(rn->table);
672
673 if (static_nexthop_destroy(args, rn_dnode, info) != NB_OK)
674 return NB_ERR;
675 break;
676 }
677 return NB_OK;
678 }
679
680 /*
681 * XPath:
682 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/bh-type
683 */
684 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_bh_type_modify(
685 struct nb_cb_modify_args *args)
686 {
687 return static_nexthop_bh_type_modify(args);
688 }
689
690 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_bh_type_destroy(
691 struct nb_cb_destroy_args *args)
692 {
693 /* blackhole type has a boolean type with default value,
694 * so no need to do any operations in destroy callback
695 */
696 switch (args->event) {
697 case NB_EV_VALIDATE:
698 case NB_EV_PREPARE:
699 case NB_EV_ABORT:
700 case NB_EV_APPLY:
701 break;
702 }
703 return NB_OK;
704 }
705
706 /*
707 * XPath:
708 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/onlink
709 */
710 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_onlink_modify(
711 struct nb_cb_modify_args *args)
712 {
713 return static_nexthop_onlink_modify(args);
714 }
715
716 /*
717 * XPath:
718 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/srte-color
719 */
720 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_color_modify(
721 struct nb_cb_modify_args *args)
722 {
723 switch (args->event) {
724 case NB_EV_VALIDATE:
725 case NB_EV_PREPARE:
726 case NB_EV_ABORT:
727 break;
728 case NB_EV_APPLY:
729 if (static_nexthop_color_modify(args) != NB_OK)
730 return NB_ERR;
731
732 break;
733 }
734 return NB_OK;
735 }
736
737 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_color_destroy(
738 struct nb_cb_destroy_args *args)
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 if (static_nexthop_color_destroy(args) != NB_OK)
747 return NB_ERR;
748 break;
749 }
750 return NB_OK;
751 }
752
753 /*
754 * XPath:
755 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry
756 */
757 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create(
758 struct nb_cb_create_args *args)
759 {
760 return nexthop_mpls_label_stack_entry_create(args);
761 }
762
763 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_destroy(
764 struct nb_cb_destroy_args *args)
765 {
766 return nexthop_mpls_label_stack_entry_destroy(args);
767 }
768
769 /*
770 * XPath:
771 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/label
772 */
773 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_modify(
774 struct nb_cb_modify_args *args)
775 {
776 switch (args->event) {
777 case NB_EV_VALIDATE:
778 case NB_EV_PREPARE:
779 case NB_EV_ABORT:
780 break;
781 case NB_EV_APPLY:
782 if (static_nexthop_mpls_label_modify(args) != NB_OK)
783 return NB_ERR;
784 break;
785 }
786 return NB_OK;
787 }
788
789 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_destroy(
790 struct nb_cb_destroy_args *args)
791 {
792 /*
793 * No operation is required in this call back.
794 * nexthop_mpls_label_stack_entry_destroy() will take care
795 * to reset the label vaue.
796 */
797 switch (args->event) {
798 case NB_EV_VALIDATE:
799 case NB_EV_PREPARE:
800 case NB_EV_ABORT:
801 case NB_EV_APPLY:
802 break;
803 }
804 return NB_OK;
805 }
806
807 /*
808 * XPath:
809 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/ttl
810 */
811 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_modify(
812 struct nb_cb_modify_args *args)
813 {
814 switch (args->event) {
815 case NB_EV_VALIDATE:
816 case NB_EV_PREPARE:
817 case NB_EV_ABORT:
818 case NB_EV_APPLY:
819 break;
820 }
821
822 return NB_OK;
823 }
824
825 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_destroy(
826 struct nb_cb_destroy_args *args)
827 {
828 switch (args->event) {
829 case NB_EV_VALIDATE:
830 case NB_EV_PREPARE:
831 case NB_EV_ABORT:
832 case NB_EV_APPLY:
833 break;
834 }
835
836 return NB_OK;
837 }
838
839 /*
840 * XPath:
841 * /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
842 */
843 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_modify(
844 struct nb_cb_modify_args *args)
845 {
846 switch (args->event) {
847 case NB_EV_VALIDATE:
848 case NB_EV_PREPARE:
849 case NB_EV_ABORT:
850 case NB_EV_APPLY:
851 break;
852 }
853
854 return NB_OK;
855 }
856
857 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_destroy(
858 struct nb_cb_destroy_args *args)
859 {
860 switch (args->event) {
861 case NB_EV_VALIDATE:
862 case NB_EV_PREPARE:
863 case NB_EV_ABORT:
864 case NB_EV_APPLY:
865 break;
866 }
867
868 return NB_OK;
869 }
870
871 /*
872 * XPath:
873 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list
874 */
875 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_create(
876 struct nb_cb_create_args *args)
877 {
878 struct static_vrf *s_vrf;
879 struct route_node *rn;
880 struct route_node *src_rn;
881 struct prefix_ipv6 src_prefix = {};
882 struct stable_info *info;
883 afi_t afi;
884 safi_t safi = SAFI_UNICAST;
885
886 switch (args->event) {
887 case NB_EV_VALIDATE:
888 case NB_EV_PREPARE:
889 case NB_EV_ABORT:
890 break;
891 case NB_EV_APPLY:
892 rn = nb_running_get_entry(args->dnode, NULL, true);
893 info = route_table_get_info(rn->table);
894 s_vrf = info->svrf;
895 yang_dnode_get_ipv6p(&src_prefix, args->dnode, "./src-prefix");
896 afi = family2afi(src_prefix.family);
897 src_rn =
898 static_add_route(afi, safi, &rn->p, &src_prefix, s_vrf);
899 if (!src_rn) {
900 flog_warn(EC_LIB_NB_CB_CONFIG_APPLY,
901 "src rn %s creation failed",
902 yang_dnode_get_string(args->dnode,
903 "./src-prefix"));
904 return NB_ERR;
905 }
906 nb_running_set_entry(args->dnode, src_rn);
907 break;
908 }
909 return NB_OK;
910 }
911
912 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_destroy(
913 struct nb_cb_destroy_args *args)
914 {
915 struct route_node *src_rn;
916 struct route_node *rn;
917 struct stable_info *info;
918 const struct lyd_node *rn_dnode;
919
920 switch (args->event) {
921 case NB_EV_VALIDATE:
922 case NB_EV_PREPARE:
923 case NB_EV_ABORT:
924 break;
925 case NB_EV_APPLY:
926 src_rn = nb_running_unset_entry(args->dnode);
927 rn_dnode = yang_dnode_get_parent(args->dnode, "route-list");
928 rn = nb_running_get_entry(rn_dnode, NULL, true);
929 info = route_table_get_info(rn->table);
930 static_del_route(src_rn, info->safi, info->svrf);
931 break;
932 }
933
934 return NB_OK;
935 }
936
937 /*
938 * XPath:
939 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list
940 */
941 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_create(
942 struct nb_cb_create_args *args)
943 {
944 return static_path_list_create(args);
945 }
946
947 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_destroy(
948 struct nb_cb_destroy_args *args)
949 {
950 struct route_node *rn;
951 const struct lyd_node *rn_dnode;
952 const struct lyd_node *srn_dnode;
953 struct stable_info *info;
954
955 switch (args->event) {
956 case NB_EV_VALIDATE:
957 case NB_EV_PREPARE:
958 case NB_EV_ABORT:
959 break;
960 case NB_EV_APPLY:
961 srn_dnode = yang_dnode_get_parent(args->dnode, "src-list");
962 rn_dnode = yang_dnode_get_parent(srn_dnode, "route-list");
963 rn = nb_running_get_entry(rn_dnode, NULL, true);
964 info = route_table_get_info(rn->table);
965 static_path_list_destroy(args, srn_dnode, info);
966 break;
967 }
968 return NB_OK;
969 }
970
971 /*
972 * XPath:
973 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/tag
974 */
975 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_tag_modify(
976 struct nb_cb_modify_args *args)
977 {
978 struct stable_info *info;
979 struct route_node *rn;
980 const struct lyd_node *srn_dnode;
981 const struct lyd_node *rn_dnode;
982
983 switch (args->event) {
984 case NB_EV_VALIDATE:
985 case NB_EV_ABORT:
986 case NB_EV_PREPARE:
987 break;
988 case NB_EV_APPLY:
989 srn_dnode = yang_dnode_get_parent(args->dnode, "src-list");
990 rn_dnode = yang_dnode_get_parent(srn_dnode, "route-list");
991 rn = nb_running_get_entry(rn_dnode, NULL, true);
992 info = route_table_get_info(rn->table);
993 static_path_list_tag_modify(args, srn_dnode, info);
994 break;
995 }
996 return NB_OK;
997 }
998
999 /*
1000 * XPath:
1001 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop
1002 */
1003 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_create(
1004 struct nb_cb_create_args *args)
1005 {
1006 struct route_node *rn;
1007 const struct lyd_node *rn_dnode;
1008 const struct lyd_node *src_dnode;
1009 struct stable_info *info;
1010
1011 switch (args->event) {
1012 case NB_EV_VALIDATE:
1013 rn_dnode = yang_dnode_get_parent(args->dnode, "route-list");
1014 if (static_nexthop_create(args, rn_dnode, NULL) != NB_OK)
1015 return NB_ERR_VALIDATION;
1016 break;
1017 case NB_EV_PREPARE:
1018 case NB_EV_ABORT:
1019 break;
1020 case NB_EV_APPLY:
1021 src_dnode = yang_dnode_get_parent(args->dnode, "src-list");
1022 rn_dnode = yang_dnode_get_parent(src_dnode, "route-list");
1023 rn = nb_running_get_entry(rn_dnode, NULL, true);
1024 info = route_table_get_info(rn->table);
1025
1026 if (static_nexthop_create(args, src_dnode, info) != NB_OK)
1027 return NB_ERR_VALIDATION;
1028
1029 break;
1030 }
1031 return NB_OK;
1032 }
1033
1034 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_destroy(
1035 struct nb_cb_destroy_args *args)
1036 {
1037 struct route_node *rn;
1038 const struct lyd_node *rn_dnode;
1039 const struct lyd_node *src_dnode;
1040 struct stable_info *info;
1041
1042 switch (args->event) {
1043 case NB_EV_VALIDATE:
1044 case NB_EV_PREPARE:
1045 case NB_EV_ABORT:
1046 break;
1047 case NB_EV_APPLY:
1048 src_dnode = yang_dnode_get_parent(args->dnode, "src-list");
1049 rn_dnode = yang_dnode_get_parent(src_dnode, "route-list");
1050 rn = nb_running_get_entry(rn_dnode, NULL, true);
1051 info = route_table_get_info(rn->table);
1052
1053 if (static_nexthop_destroy(args, rn_dnode, info) != NB_OK)
1054 return NB_ERR;
1055 break;
1056 }
1057 return NB_OK;
1058 }
1059
1060 /*
1061 * XPath:
1062 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/bh-type
1063 */
1064 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_modify(
1065 struct nb_cb_modify_args *args)
1066 {
1067 return static_nexthop_bh_type_modify(args);
1068 }
1069
1070 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_destroy(
1071 struct nb_cb_destroy_args *args)
1072 {
1073 /* blackhole type has a boolean type with default value,
1074 * so no need to do any operations in destroy callback
1075 */
1076 switch (args->event) {
1077 case NB_EV_VALIDATE:
1078 case NB_EV_PREPARE:
1079 case NB_EV_ABORT:
1080 case NB_EV_APPLY:
1081 break;
1082 }
1083
1084 return NB_OK;
1085 }
1086
1087 /*
1088 * XPath:
1089 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/onlink
1090 */
1091 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_modify(
1092 struct nb_cb_modify_args *args)
1093 {
1094 return static_nexthop_onlink_modify(args);
1095 }
1096
1097 /*
1098 * XPath:
1099 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/srte-color
1100 */
1101 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_modify(
1102 struct nb_cb_modify_args *args)
1103 {
1104 switch (args->event) {
1105 case NB_EV_VALIDATE:
1106 case NB_EV_PREPARE:
1107 case NB_EV_ABORT:
1108 break;
1109 case NB_EV_APPLY:
1110 if (static_nexthop_color_modify(args) != NB_OK)
1111 return NB_ERR;
1112
1113 break;
1114 }
1115 return NB_OK;
1116 }
1117
1118
1119 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_destroy(
1120 struct nb_cb_destroy_args *args)
1121 {
1122 switch (args->event) {
1123 case NB_EV_VALIDATE:
1124 case NB_EV_PREPARE:
1125 case NB_EV_ABORT:
1126 break;
1127 case NB_EV_APPLY:
1128 if (static_nexthop_color_destroy(args) != NB_OK)
1129 return NB_ERR;
1130 break;
1131 }
1132 return NB_OK;
1133 }
1134
1135 /*
1136 * XPath:
1137 * /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
1138 */
1139 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create(
1140 struct nb_cb_create_args *args)
1141 {
1142 return nexthop_mpls_label_stack_entry_create(args);
1143 }
1144
1145 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_destroy(
1146 struct nb_cb_destroy_args *args)
1147 {
1148 return nexthop_mpls_label_stack_entry_destroy(args);
1149 }
1150
1151 /*
1152 * XPath:
1153 * /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
1154 */
1155 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_modify(
1156 struct nb_cb_modify_args *args)
1157 {
1158 switch (args->event) {
1159 case NB_EV_VALIDATE:
1160 case NB_EV_PREPARE:
1161 case NB_EV_ABORT:
1162 break;
1163 case NB_EV_APPLY:
1164 if (static_nexthop_mpls_label_modify(args) != NB_OK)
1165 return NB_ERR;
1166 break;
1167 }
1168 return NB_OK;
1169 }
1170
1171 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_destroy(
1172 struct nb_cb_destroy_args *args)
1173 {
1174 /*
1175 * No operation is required in this call back.
1176 * nexthop_mpls_label_stack_entry_destroy() will take care
1177 * to reset the label vaue.
1178 */
1179 switch (args->event) {
1180 case NB_EV_VALIDATE:
1181 case NB_EV_PREPARE:
1182 case NB_EV_ABORT:
1183 case NB_EV_APPLY:
1184 break;
1185 }
1186 return NB_OK;
1187 }
1188
1189 /*
1190 * XPath:
1191 * /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
1192 */
1193 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_modify(
1194 struct nb_cb_modify_args *args)
1195 {
1196 switch (args->event) {
1197 case NB_EV_VALIDATE:
1198 case NB_EV_PREPARE:
1199 case NB_EV_ABORT:
1200 case NB_EV_APPLY:
1201 break;
1202 }
1203
1204 return NB_OK;
1205 }
1206
1207 int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_destroy(
1208 struct nb_cb_destroy_args *args)
1209 {
1210 switch (args->event) {
1211 case NB_EV_VALIDATE:
1212 case NB_EV_PREPARE:
1213 case NB_EV_ABORT:
1214 case NB_EV_APPLY:
1215 break;
1216 }
1217
1218 return NB_OK;
1219 }
1220
1221 /*
1222 * XPath:
1223 * /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
1224 */
1225 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(
1226 struct nb_cb_modify_args *args)
1227 {
1228 switch (args->event) {
1229 case NB_EV_VALIDATE:
1230 case NB_EV_PREPARE:
1231 case NB_EV_ABORT:
1232 case NB_EV_APPLY:
1233 break;
1234 }
1235
1236 return NB_OK;
1237 }
1238
1239 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(
1240 struct nb_cb_destroy_args *args)
1241 {
1242 switch (args->event) {
1243 case NB_EV_VALIDATE:
1244 case NB_EV_PREPARE:
1245 case NB_EV_ABORT:
1246 case NB_EV_APPLY:
1247 break;
1248 }
1249
1250 return NB_OK;
1251 }