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