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