Line data Source code
1 : /*
2 : * Route map northbound implementation.
3 : *
4 : * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
5 : * Rafael Zalamena
6 : *
7 : * This program is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU General Public License as published by
9 : * the Free Software Foundation; either version 2 of the License, or
10 : * (at your option) any later version.
11 : *
12 : * This program is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU General Public License
18 : * along with this program; if not, write to the Free Software
19 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 : * 02110-1301 USA.
21 : */
22 :
23 : #include <zebra.h>
24 :
25 : #include "lib/command.h"
26 : #include "lib/log.h"
27 : #include "lib/northbound.h"
28 : #include "lib/routemap.h"
29 :
30 : /*
31 : * Auxiliary functions to avoid code duplication:
32 : *
33 : * lib_route_map_entry_set_destroy: unset `set` commands.
34 : * lib_route_map_entry_match_destroy: unset `match` commands.
35 : */
36 0 : int lib_route_map_entry_match_destroy(struct nb_cb_destroy_args *args)
37 : {
38 0 : struct routemap_hook_context *rhc;
39 0 : int rv;
40 :
41 0 : if (args->event != NB_EV_APPLY)
42 : return NB_OK;
43 :
44 0 : rhc = nb_running_get_entry(args->dnode, NULL, true);
45 0 : if (rhc->rhc_mhook == NULL)
46 : return NB_OK;
47 :
48 0 : rv = rhc->rhc_mhook(rhc->rhc_rmi, rhc->rhc_rule, NULL,
49 : rhc->rhc_event,
50 : args->errmsg, args->errmsg_len);
51 0 : if (rv != CMD_SUCCESS)
52 : return NB_ERR_INCONSISTENCY;
53 :
54 : return NB_OK;
55 : }
56 :
57 0 : int lib_route_map_entry_set_destroy(struct nb_cb_destroy_args *args)
58 : {
59 0 : struct routemap_hook_context *rhc;
60 0 : int rv;
61 :
62 0 : if (args->event != NB_EV_APPLY)
63 : return NB_OK;
64 :
65 0 : rhc = nb_running_get_entry(args->dnode, NULL, true);
66 0 : if (rhc->rhc_shook == NULL)
67 : return NB_OK;
68 :
69 0 : rv = rhc->rhc_shook(rhc->rhc_rmi, rhc->rhc_rule, NULL,
70 : args->errmsg, args->errmsg_len);
71 0 : if (rv != CMD_SUCCESS)
72 : return NB_ERR_INCONSISTENCY;
73 :
74 : return NB_OK;
75 : }
76 :
77 : /*
78 : * Auxiliary hook context list manipulation functions.
79 : */
80 : struct routemap_hook_context *
81 36 : routemap_hook_context_insert(struct route_map_index *rmi)
82 : {
83 36 : struct routemap_hook_context *rhc;
84 :
85 36 : rhc = XCALLOC(MTYPE_TMP, sizeof(*rhc));
86 36 : rhc->rhc_rmi = rmi;
87 36 : TAILQ_INSERT_TAIL(&rmi->rhclist, rhc, rhc_entry);
88 :
89 36 : return rhc;
90 : }
91 :
92 36 : void routemap_hook_context_free(struct routemap_hook_context *rhc)
93 : {
94 36 : struct route_map_index *rmi = rhc->rhc_rmi;
95 :
96 36 : TAILQ_REMOVE(&rmi->rhclist, rhc, rhc_entry);
97 36 : XFREE(MTYPE_TMP, rhc);
98 36 : }
99 :
100 : /*
101 : * XPath: /frr-route-map:lib/route-map
102 : */
103 39 : static int lib_route_map_create(struct nb_cb_create_args *args)
104 : {
105 39 : struct route_map *rm;
106 39 : const char *rm_name;
107 :
108 39 : switch (args->event) {
109 : case NB_EV_VALIDATE:
110 : case NB_EV_PREPARE:
111 : case NB_EV_ABORT:
112 : /* NOTHING */
113 : break;
114 13 : case NB_EV_APPLY:
115 13 : rm_name = yang_dnode_get_string(args->dnode, "./name");
116 13 : rm = route_map_get(rm_name);
117 13 : nb_running_set_entry(args->dnode, rm);
118 13 : break;
119 : }
120 :
121 39 : return NB_OK;
122 : }
123 :
124 0 : static int lib_route_map_destroy(struct nb_cb_destroy_args *args)
125 : {
126 0 : struct route_map *rm;
127 :
128 0 : switch (args->event) {
129 : case NB_EV_VALIDATE:
130 : case NB_EV_PREPARE:
131 : case NB_EV_ABORT:
132 : /* NOTHING */
133 : break;
134 0 : case NB_EV_APPLY:
135 0 : rm = nb_running_unset_entry(args->dnode);
136 0 : route_map_delete(rm);
137 0 : break;
138 : }
139 :
140 0 : return NB_OK;
141 : }
142 :
143 : /*
144 : * XPath: /frr-route-map:lib/route-map/optimization-disabled
145 : */
146 : static int
147 0 : lib_route_map_optimization_disabled_modify(struct nb_cb_modify_args *args)
148 : {
149 0 : struct route_map *rm;
150 0 : bool disabled = yang_dnode_get_bool(args->dnode, NULL);
151 :
152 0 : switch (args->event) {
153 : case NB_EV_VALIDATE:
154 : case NB_EV_PREPARE:
155 : case NB_EV_ABORT:
156 : /* NOTHING */
157 : break;
158 0 : case NB_EV_APPLY:
159 0 : rm = nb_running_get_entry(args->dnode, NULL, true);
160 0 : rm->optimization_disabled = disabled;
161 0 : break;
162 : }
163 :
164 0 : return NB_OK;
165 : }
166 :
167 : /*
168 : * XPath: /frr-route-map:lib/route-map/entry
169 : */
170 66 : static int lib_route_map_entry_create(struct nb_cb_create_args *args)
171 : {
172 66 : struct route_map_index *rmi;
173 66 : struct route_map *rm;
174 66 : uint16_t sequence;
175 66 : int action;
176 :
177 66 : switch (args->event) {
178 : case NB_EV_VALIDATE:
179 : case NB_EV_PREPARE:
180 : case NB_EV_ABORT:
181 : /* NOTHING */
182 : break;
183 22 : case NB_EV_APPLY:
184 22 : sequence = yang_dnode_get_uint16(args->dnode, "./sequence");
185 22 : action = yang_dnode_get_enum(args->dnode, "./action") == 0
186 : ? RMAP_PERMIT
187 22 : : RMAP_DENY;
188 22 : rm = nb_running_get_entry(args->dnode, NULL, true);
189 22 : rmi = route_map_index_get(rm, action, sequence);
190 22 : nb_running_set_entry(args->dnode, rmi);
191 22 : break;
192 : }
193 :
194 66 : return NB_OK;
195 : }
196 :
197 0 : static int lib_route_map_entry_destroy(struct nb_cb_destroy_args *args)
198 : {
199 0 : struct route_map_index *rmi;
200 :
201 0 : switch (args->event) {
202 : case NB_EV_VALIDATE:
203 : case NB_EV_PREPARE:
204 : case NB_EV_ABORT:
205 : /* NOTHING */
206 : break;
207 0 : case NB_EV_APPLY:
208 0 : rmi = nb_running_unset_entry(args->dnode);
209 0 : route_map_index_delete(rmi, 1);
210 0 : break;
211 : }
212 :
213 0 : return NB_OK;
214 : }
215 :
216 : /*
217 : * XPath: /frr-route-map:lib/route-map/entry/description
218 : */
219 : static int
220 0 : lib_route_map_entry_description_modify(struct nb_cb_modify_args *args)
221 : {
222 0 : struct route_map_index *rmi;
223 0 : const char *description;
224 :
225 0 : switch (args->event) {
226 : case NB_EV_VALIDATE:
227 : /* NOTHING */
228 : break;
229 0 : case NB_EV_PREPARE:
230 0 : description = yang_dnode_get_string(args->dnode, NULL);
231 0 : args->resource->ptr = XSTRDUP(MTYPE_TMP, description);
232 0 : if (args->resource->ptr == NULL)
233 : return NB_ERR_RESOURCE;
234 : break;
235 0 : case NB_EV_ABORT:
236 0 : XFREE(MTYPE_TMP, args->resource->ptr);
237 0 : break;
238 0 : case NB_EV_APPLY:
239 0 : rmi = nb_running_get_entry(args->dnode, NULL, true);
240 0 : XFREE(MTYPE_TMP, rmi->description);
241 0 : rmi->description = args->resource->ptr;
242 0 : break;
243 : }
244 :
245 : return NB_OK;
246 : }
247 :
248 : static int
249 0 : lib_route_map_entry_description_destroy(struct nb_cb_destroy_args *args)
250 : {
251 0 : struct route_map_index *rmi;
252 :
253 0 : switch (args->event) {
254 : case NB_EV_VALIDATE:
255 : case NB_EV_PREPARE:
256 : case NB_EV_ABORT:
257 : /* NOTHING */
258 : break;
259 0 : case NB_EV_APPLY:
260 0 : rmi = nb_running_get_entry(args->dnode, NULL, true);
261 0 : XFREE(MTYPE_TMP, rmi->description);
262 0 : break;
263 : }
264 :
265 0 : return NB_OK;
266 : }
267 :
268 : /*
269 : * XPath: /frr-route-map:lib/route-map/entry/action
270 : */
271 66 : static int lib_route_map_entry_action_modify(struct nb_cb_modify_args *args)
272 : {
273 66 : struct route_map_index *rmi;
274 66 : struct route_map *map;
275 :
276 66 : switch (args->event) {
277 : case NB_EV_VALIDATE:
278 : case NB_EV_PREPARE:
279 : case NB_EV_ABORT:
280 : /* NOTHING */
281 : break;
282 22 : case NB_EV_APPLY:
283 22 : rmi = nb_running_get_entry(args->dnode, NULL, true);
284 22 : rmi->type = yang_dnode_get_enum(args->dnode, NULL);
285 22 : map = rmi->map;
286 :
287 : /* Execute event hook. */
288 22 : if (route_map_master.event_hook) {
289 22 : (*route_map_master.event_hook)(map->name);
290 22 : route_map_notify_dependencies(map->name,
291 : RMAP_EVENT_CALL_ADDED);
292 : }
293 :
294 : break;
295 : }
296 :
297 66 : return NB_OK;
298 : }
299 :
300 : /*
301 : * XPath: /frr-route-map:lib/route-map/entry/call
302 : */
303 0 : static int lib_route_map_entry_call_modify(struct nb_cb_modify_args *args)
304 : {
305 0 : struct route_map_index *rmi;
306 0 : const char *rm_name, *rmn_name;
307 :
308 0 : switch (args->event) {
309 0 : case NB_EV_VALIDATE:
310 0 : rm_name = yang_dnode_get_string(args->dnode, "../../name");
311 0 : rmn_name = yang_dnode_get_string(args->dnode, NULL);
312 : /* Don't allow to jump to the same route map instance. */
313 0 : if (strcmp(rm_name, rmn_name) == 0)
314 : return NB_ERR_VALIDATION;
315 :
316 : /* TODO: detect circular route map sequences. */
317 : break;
318 0 : case NB_EV_PREPARE:
319 0 : rmn_name = yang_dnode_get_string(args->dnode, NULL);
320 0 : args->resource->ptr = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmn_name);
321 0 : break;
322 0 : case NB_EV_ABORT:
323 0 : XFREE(MTYPE_ROUTE_MAP_NAME, args->resource->ptr);
324 0 : break;
325 0 : case NB_EV_APPLY:
326 0 : rmi = nb_running_get_entry(args->dnode, NULL, true);
327 0 : if (rmi->nextrm) {
328 0 : route_map_upd8_dependency(RMAP_EVENT_CALL_DELETED,
329 0 : rmi->nextrm, rmi->map->name);
330 0 : XFREE(MTYPE_ROUTE_MAP_NAME, rmi->nextrm);
331 : }
332 0 : rmi->nextrm = args->resource->ptr;
333 0 : route_map_upd8_dependency(RMAP_EVENT_CALL_ADDED, rmi->nextrm,
334 0 : rmi->map->name);
335 0 : break;
336 : }
337 :
338 : return NB_OK;
339 : }
340 :
341 0 : static int lib_route_map_entry_call_destroy(struct nb_cb_destroy_args *args)
342 : {
343 0 : struct route_map_index *rmi;
344 :
345 0 : switch (args->event) {
346 : case NB_EV_VALIDATE:
347 : case NB_EV_PREPARE:
348 : case NB_EV_ABORT:
349 : /* NOTHING */
350 : break;
351 0 : case NB_EV_APPLY:
352 0 : rmi = nb_running_get_entry(args->dnode, NULL, true);
353 0 : route_map_upd8_dependency(RMAP_EVENT_CALL_DELETED, rmi->nextrm,
354 0 : rmi->map->name);
355 0 : XFREE(MTYPE_ROUTE_MAP_NAME, rmi->nextrm);
356 0 : rmi->nextrm = NULL;
357 0 : break;
358 : }
359 :
360 0 : return NB_OK;
361 : }
362 :
363 : /*
364 : * XPath: /frr-route-map:lib/route-map/entry/exit-policy
365 : */
366 : static int
367 0 : lib_route_map_entry_exit_policy_modify(struct nb_cb_modify_args *args)
368 : {
369 0 : struct route_map_index *rmi;
370 0 : int rm_action;
371 0 : int policy;
372 :
373 0 : switch (args->event) {
374 0 : case NB_EV_VALIDATE:
375 0 : policy = yang_dnode_get_enum(args->dnode, NULL);
376 0 : switch (policy) {
377 : case 0: /* permit-or-deny */
378 : break;
379 0 : case 1: /* next */
380 : /* FALLTHROUGH */
381 : case 2: /* goto */
382 0 : rm_action =
383 0 : yang_dnode_get_enum(args->dnode, "../action");
384 0 : if (rm_action == 1 /* deny */) {
385 : /*
386 : * On deny it is not possible to 'goto'
387 : * anywhere.
388 : */
389 : return NB_ERR_VALIDATION;
390 : }
391 : break;
392 : }
393 : break;
394 : case NB_EV_PREPARE:
395 : case NB_EV_ABORT:
396 : break;
397 0 : case NB_EV_APPLY:
398 0 : rmi = nb_running_get_entry(args->dnode, NULL, true);
399 0 : policy = yang_dnode_get_enum(args->dnode, NULL);
400 :
401 0 : switch (policy) {
402 0 : case 0: /* permit-or-deny */
403 0 : rmi->exitpolicy = RMAP_EXIT;
404 0 : break;
405 0 : case 1: /* next */
406 0 : rmi->exitpolicy = RMAP_NEXT;
407 0 : break;
408 0 : case 2: /* goto */
409 0 : rmi->exitpolicy = RMAP_GOTO;
410 0 : break;
411 : }
412 : break;
413 : }
414 :
415 : return NB_OK;
416 : }
417 :
418 : /*
419 : * XPath: /frr-route-map:lib/route-map/entry/goto-value
420 : */
421 0 : static int lib_route_map_entry_goto_value_modify(struct nb_cb_modify_args *args)
422 : {
423 0 : struct route_map_index *rmi;
424 0 : uint16_t rmi_index;
425 0 : uint16_t rmi_next;
426 :
427 0 : switch (args->event) {
428 0 : case NB_EV_VALIDATE:
429 0 : rmi_index = yang_dnode_get_uint16(args->dnode, "../sequence");
430 0 : rmi_next = yang_dnode_get_uint16(args->dnode, NULL);
431 0 : if (rmi_next <= rmi_index) {
432 : /* Can't jump backwards on a route map. */
433 : return NB_ERR_VALIDATION;
434 : }
435 : break;
436 : case NB_EV_PREPARE:
437 : case NB_EV_ABORT:
438 : /* NOTHING */
439 : break;
440 0 : case NB_EV_APPLY:
441 0 : rmi = nb_running_get_entry(args->dnode, NULL, true);
442 0 : rmi->nextpref = yang_dnode_get_uint16(args->dnode, NULL);
443 0 : break;
444 : }
445 :
446 : return NB_OK;
447 : }
448 :
449 : static int
450 0 : lib_route_map_entry_goto_value_destroy(struct nb_cb_destroy_args *args)
451 : {
452 0 : struct route_map_index *rmi;
453 :
454 0 : switch (args->event) {
455 : case NB_EV_VALIDATE:
456 : case NB_EV_PREPARE:
457 : case NB_EV_ABORT:
458 : /* NOTHING */
459 : break;
460 0 : case NB_EV_APPLY:
461 0 : rmi = nb_running_get_entry(args->dnode, NULL, true);
462 0 : rmi->nextpref = 0;
463 0 : break;
464 : }
465 :
466 0 : return NB_OK;
467 : }
468 :
469 : /*
470 : * XPath: /frr-route-map:lib/route-map/entry/match-condition
471 : */
472 : static int
473 108 : lib_route_map_entry_match_condition_create(struct nb_cb_create_args *args)
474 : {
475 108 : struct routemap_hook_context *rhc;
476 108 : struct route_map_index *rmi;
477 :
478 108 : switch (args->event) {
479 : case NB_EV_VALIDATE:
480 : case NB_EV_PREPARE:
481 : case NB_EV_ABORT:
482 : /* NOTHING */
483 : break;
484 36 : case NB_EV_APPLY:
485 36 : rmi = nb_running_get_entry(args->dnode, NULL, true);
486 36 : rhc = routemap_hook_context_insert(rmi);
487 36 : nb_running_set_entry(args->dnode, rhc);
488 36 : break;
489 : }
490 :
491 108 : return NB_OK;
492 : }
493 :
494 : static int
495 0 : lib_route_map_entry_match_condition_destroy(struct nb_cb_destroy_args *args)
496 : {
497 0 : struct routemap_hook_context *rhc;
498 0 : int rv;
499 :
500 0 : if (args->event != NB_EV_APPLY)
501 : return NB_OK;
502 :
503 0 : rv = lib_route_map_entry_match_destroy(args);
504 0 : rhc = nb_running_unset_entry(args->dnode);
505 0 : routemap_hook_context_free(rhc);
506 :
507 0 : return rv;
508 : }
509 :
510 : /*
511 : * XPath: /frr-route-map:lib/route-map/entry/match-condition/interface
512 : */
513 0 : static int lib_route_map_entry_match_condition_interface_modify(
514 : struct nb_cb_modify_args *args)
515 : {
516 0 : struct routemap_hook_context *rhc;
517 0 : const char *ifname;
518 0 : int rv;
519 :
520 0 : if (args->event != NB_EV_APPLY)
521 : return NB_OK;
522 :
523 : /* Check for hook function. */
524 0 : if (rmap_match_set_hook.match_interface == NULL)
525 : return NB_OK;
526 :
527 : /* Add configuration. */
528 0 : rhc = nb_running_get_entry(args->dnode, NULL, true);
529 0 : ifname = yang_dnode_get_string(args->dnode, NULL);
530 :
531 : /* Set destroy information. */
532 0 : rhc->rhc_mhook = rmap_match_set_hook.no_match_interface;
533 0 : rhc->rhc_rule = "interface";
534 0 : rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
535 :
536 0 : rv = rmap_match_set_hook.match_interface(rhc->rhc_rmi,
537 : "interface", ifname,
538 : RMAP_EVENT_MATCH_ADDED,
539 : args->errmsg, args->errmsg_len);
540 0 : if (rv != CMD_SUCCESS) {
541 0 : rhc->rhc_mhook = NULL;
542 0 : return NB_ERR_INCONSISTENCY;
543 : }
544 :
545 : return NB_OK;
546 : }
547 :
548 0 : static int lib_route_map_entry_match_condition_interface_destroy(
549 : struct nb_cb_destroy_args *args)
550 : {
551 0 : return lib_route_map_entry_match_destroy(args);
552 : }
553 :
554 : /*
555 : * XPath: /frr-route-map:lib/route-map/entry/match-condition/list-name
556 : */
557 30 : static int lib_route_map_entry_match_condition_list_name_modify(
558 : struct nb_cb_modify_args *args)
559 : {
560 30 : struct routemap_hook_context *rhc;
561 30 : const char *acl;
562 30 : const char *condition;
563 30 : int rv;
564 :
565 30 : if (args->event != NB_EV_APPLY)
566 : return NB_OK;
567 :
568 : /* Check for hook installation, otherwise we can just stop. */
569 10 : acl = yang_dnode_get_string(args->dnode, NULL);
570 10 : rhc = nb_running_get_entry(args->dnode, NULL, true);
571 10 : condition = yang_dnode_get_string(args->dnode, "../../condition");
572 :
573 10 : if (IS_MATCH_IPv4_ADDRESS_LIST(condition)) {
574 0 : if (rmap_match_set_hook.match_ip_address == NULL)
575 : return NB_OK;
576 0 : rhc->rhc_mhook = rmap_match_set_hook.no_match_ip_address;
577 0 : rhc->rhc_rule = "ip address";
578 0 : rhc->rhc_event = RMAP_EVENT_FILTER_DELETED;
579 0 : rv = rmap_match_set_hook.match_ip_address(
580 : rhc->rhc_rmi, "ip address", acl,
581 : RMAP_EVENT_FILTER_ADDED,
582 : args->errmsg, args->errmsg_len);
583 10 : } else if (IS_MATCH_IPv4_PREFIX_LIST(condition)) {
584 1 : if (rmap_match_set_hook.match_ip_address_prefix_list == NULL)
585 : return NB_OK;
586 1 : rhc->rhc_mhook =
587 1 : rmap_match_set_hook.no_match_ip_address_prefix_list;
588 1 : rhc->rhc_rule = "ip address prefix-list";
589 1 : rhc->rhc_event = RMAP_EVENT_PLIST_DELETED;
590 1 : rv = rmap_match_set_hook.match_ip_address_prefix_list(
591 : rhc->rhc_rmi, "ip address prefix-list", acl,
592 : RMAP_EVENT_PLIST_ADDED,
593 : args->errmsg, args->errmsg_len);
594 9 : } else if (IS_MATCH_IPv4_NEXTHOP_LIST(condition)) {
595 0 : if (rmap_match_set_hook.match_ip_next_hop == NULL)
596 : return NB_OK;
597 0 : rhc->rhc_mhook = rmap_match_set_hook.no_match_ip_next_hop;
598 0 : rhc->rhc_rule = "ip next-hop";
599 0 : rhc->rhc_event = RMAP_EVENT_FILTER_DELETED;
600 0 : rv = rmap_match_set_hook.match_ip_next_hop(
601 : rhc->rhc_rmi, "ip next-hop", acl,
602 : RMAP_EVENT_FILTER_ADDED,
603 : args->errmsg, args->errmsg_len);
604 9 : } else if (IS_MATCH_IPv6_NEXTHOP_LIST(condition)) {
605 3 : if (rmap_match_set_hook.match_ipv6_next_hop == NULL)
606 : return NB_OK;
607 3 : rhc->rhc_mhook = rmap_match_set_hook.no_match_ipv6_next_hop;
608 3 : rhc->rhc_rule = "ipv6 next-hop";
609 3 : rhc->rhc_event = RMAP_EVENT_FILTER_DELETED;
610 3 : rv = rmap_match_set_hook.match_ipv6_next_hop(
611 : rhc->rhc_rmi, "ipv6 next-hop", acl,
612 : RMAP_EVENT_FILTER_ADDED, args->errmsg,
613 : args->errmsg_len);
614 6 : } else if (IS_MATCH_IPv4_NEXTHOP_PREFIX_LIST(condition)) {
615 0 : if (rmap_match_set_hook.match_ip_next_hop_prefix_list == NULL)
616 : return NB_OK;
617 0 : rhc->rhc_mhook =
618 0 : rmap_match_set_hook.no_match_ip_next_hop_prefix_list;
619 0 : rhc->rhc_rule = "ip next-hop prefix-list";
620 0 : rhc->rhc_event = RMAP_EVENT_PLIST_DELETED;
621 0 : rv = rmap_match_set_hook.match_ip_next_hop_prefix_list(
622 : rhc->rhc_rmi, "ip next-hop prefix-list", acl,
623 : RMAP_EVENT_PLIST_ADDED,
624 : args->errmsg, args->errmsg_len);
625 6 : } else if (IS_MATCH_IPv6_NEXTHOP_PREFIX_LIST(condition)) {
626 1 : if (rmap_match_set_hook.match_ipv6_next_hop_prefix_list == NULL)
627 : return NB_OK;
628 1 : rhc->rhc_mhook =
629 1 : rmap_match_set_hook.no_match_ipv6_next_hop_prefix_list;
630 1 : rhc->rhc_rule = "ipv6 next-hop prefix-list";
631 1 : rhc->rhc_event = RMAP_EVENT_PLIST_DELETED;
632 1 : rv = rmap_match_set_hook.match_ipv6_next_hop_prefix_list(
633 : rhc->rhc_rmi, "ipv6 next-hop prefix-list", acl,
634 : RMAP_EVENT_PLIST_ADDED, args->errmsg, args->errmsg_len);
635 5 : } else if (IS_MATCH_IPv6_ADDRESS_LIST(condition)) {
636 0 : if (rmap_match_set_hook.match_ipv6_address == NULL)
637 : return NB_OK;
638 0 : rhc->rhc_mhook = rmap_match_set_hook.no_match_ipv6_address;
639 0 : rhc->rhc_rule = "ipv6 address";
640 0 : rhc->rhc_event = RMAP_EVENT_FILTER_DELETED;
641 0 : rv = rmap_match_set_hook.match_ipv6_address(
642 : rhc->rhc_rmi, "ipv6 address", acl,
643 : RMAP_EVENT_FILTER_ADDED,
644 : args->errmsg, args->errmsg_len);
645 5 : } else if (IS_MATCH_IPv6_PREFIX_LIST(condition)) {
646 5 : if (rmap_match_set_hook.match_ipv6_address_prefix_list == NULL)
647 : return NB_OK;
648 5 : rhc->rhc_mhook =
649 5 : rmap_match_set_hook.no_match_ipv6_address_prefix_list;
650 5 : rhc->rhc_rule = "ipv6 address prefix-list";
651 5 : rhc->rhc_event = RMAP_EVENT_PLIST_DELETED;
652 5 : rv = rmap_match_set_hook.match_ipv6_address_prefix_list(
653 : rhc->rhc_rmi, "ipv6 address prefix-list", acl,
654 : RMAP_EVENT_PLIST_ADDED,
655 : args->errmsg, args->errmsg_len);
656 : } else
657 : rv = CMD_ERR_NO_MATCH;
658 :
659 10 : if (rv != CMD_SUCCESS) {
660 0 : rhc->rhc_mhook = NULL;
661 0 : return NB_ERR_INCONSISTENCY;
662 : }
663 :
664 : return NB_OK;
665 : }
666 :
667 0 : static int lib_route_map_entry_match_condition_list_name_destroy(
668 : struct nb_cb_destroy_args *args)
669 : {
670 0 : return lib_route_map_entry_match_destroy(args);
671 : }
672 :
673 : /*
674 : * XPath: /frr-route-map:lib/route-map/entry/match-condition/ipv4-next-hop-type
675 : */
676 0 : static int lib_route_map_entry_match_condition_ipv4_next_hop_type_modify(
677 : struct nb_cb_modify_args *args)
678 : {
679 0 : struct routemap_hook_context *rhc;
680 0 : const char *type;
681 0 : int rv;
682 :
683 0 : if (args->event != NB_EV_APPLY)
684 : return NB_OK;
685 :
686 : /* Check for hook function. */
687 0 : if (rmap_match_set_hook.match_ip_next_hop_type == NULL)
688 : return NB_OK;
689 :
690 : /* Add configuration. */
691 0 : rhc = nb_running_get_entry(args->dnode, NULL, true);
692 0 : type = yang_dnode_get_string(args->dnode, NULL);
693 :
694 : /* Set destroy information. */
695 0 : rhc->rhc_mhook = rmap_match_set_hook.no_match_ip_next_hop_type;
696 0 : rhc->rhc_rule = "ip next-hop type";
697 0 : rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
698 :
699 0 : rv = rmap_match_set_hook.match_ip_next_hop_type(
700 : rhc->rhc_rmi, "ip next-hop type", type,
701 : RMAP_EVENT_MATCH_ADDED,
702 : args->errmsg, args->errmsg_len);
703 0 : if (rv != CMD_SUCCESS) {
704 0 : rhc->rhc_mhook = NULL;
705 0 : return NB_ERR_INCONSISTENCY;
706 : }
707 :
708 : return NB_OK;
709 : }
710 :
711 0 : static int lib_route_map_entry_match_condition_ipv4_next_hop_type_destroy(
712 : struct nb_cb_destroy_args *args)
713 : {
714 0 : return lib_route_map_entry_match_destroy(args);
715 : }
716 :
717 : /*
718 : * XPath: /frr-route-map:lib/route-map/entry/match-condition/ipv6-next-hop-type
719 : */
720 0 : static int lib_route_map_entry_match_condition_ipv6_next_hop_type_modify(
721 : struct nb_cb_modify_args *args)
722 : {
723 0 : struct routemap_hook_context *rhc;
724 0 : const char *type;
725 0 : int rv;
726 :
727 0 : if (args->event != NB_EV_APPLY)
728 : return NB_OK;
729 :
730 : /* Check for hook function. */
731 0 : if (rmap_match_set_hook.match_ipv6_next_hop_type == NULL)
732 : return NB_OK;
733 :
734 : /* Add configuration. */
735 0 : rhc = nb_running_get_entry(args->dnode, NULL, true);
736 0 : type = yang_dnode_get_string(args->dnode, NULL);
737 :
738 : /* Set destroy information. */
739 0 : rhc->rhc_mhook = rmap_match_set_hook.no_match_ipv6_next_hop_type;
740 0 : rhc->rhc_rule = "ipv6 next-hop type";
741 0 : rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
742 :
743 0 : rv = rmap_match_set_hook.match_ipv6_next_hop_type(
744 : rhc->rhc_rmi, "ipv6 next-hop type", type,
745 : RMAP_EVENT_MATCH_ADDED,
746 : args->errmsg, args->errmsg_len);
747 0 : if (rv != CMD_SUCCESS) {
748 0 : rhc->rhc_mhook = NULL;
749 0 : return NB_ERR_INCONSISTENCY;
750 : }
751 :
752 : return NB_OK;
753 : }
754 :
755 0 : static int lib_route_map_entry_match_condition_ipv6_next_hop_type_destroy(
756 : struct nb_cb_destroy_args *args)
757 : {
758 0 : return lib_route_map_entry_match_destroy(args);
759 : }
760 :
761 : /*
762 : * XPath: /frr-route-map:lib/route-map/entry/match-condition/metric
763 : */
764 0 : static int lib_route_map_entry_match_condition_metric_modify(
765 : struct nb_cb_modify_args *args)
766 : {
767 0 : struct routemap_hook_context *rhc;
768 0 : const char *type;
769 0 : int rv;
770 :
771 0 : if (args->event != NB_EV_APPLY)
772 : return NB_OK;
773 :
774 : /* Check for hook function. */
775 0 : if (rmap_match_set_hook.match_metric == NULL)
776 : return NB_OK;
777 :
778 : /* Add configuration. */
779 0 : rhc = nb_running_get_entry(args->dnode, NULL, true);
780 0 : type = yang_dnode_get_string(args->dnode, NULL);
781 :
782 : /* Set destroy information. */
783 0 : rhc->rhc_mhook = rmap_match_set_hook.no_match_metric;
784 0 : rhc->rhc_rule = "metric";
785 0 : rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
786 :
787 0 : rv = rmap_match_set_hook.match_metric(rhc->rhc_rmi, "metric",
788 : type, RMAP_EVENT_MATCH_ADDED,
789 : args->errmsg, args->errmsg_len);
790 0 : if (rv != CMD_SUCCESS) {
791 0 : rhc->rhc_mhook = NULL;
792 0 : return NB_ERR_INCONSISTENCY;
793 : }
794 :
795 : return NB_OK;
796 : }
797 :
798 0 : static int lib_route_map_entry_match_condition_metric_destroy(
799 : struct nb_cb_destroy_args *args)
800 : {
801 0 : return lib_route_map_entry_match_destroy(args);
802 : }
803 :
804 : /*
805 : * XPath: /frr-route-map:lib/route-map/entry/match-condition/tag
806 : */
807 : static int
808 0 : lib_route_map_entry_match_condition_tag_modify(struct nb_cb_modify_args *args)
809 : {
810 0 : struct routemap_hook_context *rhc;
811 0 : const char *tag;
812 0 : int rv;
813 :
814 0 : if (args->event != NB_EV_APPLY)
815 : return NB_OK;
816 :
817 : /* Check for hook function. */
818 0 : if (rmap_match_set_hook.match_tag == NULL)
819 : return NB_OK;
820 :
821 : /* Add configuration. */
822 0 : rhc = nb_running_get_entry(args->dnode, NULL, true);
823 0 : tag = yang_dnode_get_string(args->dnode, NULL);
824 :
825 : /* Set destroy information. */
826 0 : rhc->rhc_mhook = rmap_match_set_hook.no_match_tag;
827 0 : rhc->rhc_rule = "tag";
828 0 : rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
829 :
830 0 : rv = rmap_match_set_hook.match_tag(rhc->rhc_rmi, "tag", tag,
831 : RMAP_EVENT_MATCH_ADDED,
832 : args->errmsg, args->errmsg_len);
833 0 : if (rv != CMD_SUCCESS) {
834 0 : rhc->rhc_mhook = NULL;
835 0 : return NB_ERR_INCONSISTENCY;
836 : }
837 :
838 : return NB_OK;
839 : }
840 :
841 : static int
842 0 : lib_route_map_entry_match_condition_tag_destroy(struct nb_cb_destroy_args *args)
843 : {
844 0 : return lib_route_map_entry_match_destroy(args);
845 : }
846 :
847 : /*
848 : * XPath: /frr-route-map:lib/route-map/entry/set-action
849 : */
850 69 : static int lib_route_map_entry_set_action_create(struct nb_cb_create_args *args)
851 : {
852 69 : return lib_route_map_entry_match_condition_create(args);
853 : }
854 :
855 : static int
856 0 : lib_route_map_entry_set_action_destroy(struct nb_cb_destroy_args *args)
857 : {
858 0 : struct routemap_hook_context *rhc;
859 0 : int rv;
860 :
861 0 : if (args->event != NB_EV_APPLY)
862 : return NB_OK;
863 :
864 0 : rv = lib_route_map_entry_set_destroy(args);
865 0 : rhc = nb_running_unset_entry(args->dnode);
866 0 : routemap_hook_context_free(rhc);
867 :
868 0 : return rv;
869 : }
870 :
871 : /*
872 : * XPath: /frr-route-map:lib/route-map/entry/set-action/ipv4-address
873 : */
874 0 : static int lib_route_map_entry_set_action_ipv4_address_modify(
875 : struct nb_cb_modify_args *args)
876 : {
877 0 : struct routemap_hook_context *rhc;
878 0 : const char *address;
879 0 : struct in_addr ia;
880 0 : int rv;
881 :
882 0 : switch (args->event) {
883 0 : case NB_EV_VALIDATE:
884 : /*
885 : * NOTE: validate if 'action' is 'ipv4-next-hop',
886 : * currently it is not necessary because this is the
887 : * only implemented action.
888 : */
889 0 : yang_dnode_get_ipv4(&ia, args->dnode, NULL);
890 0 : if (ia.s_addr == INADDR_ANY || !ipv4_unicast_valid(&ia))
891 0 : return NB_ERR_VALIDATION;
892 : /* FALLTHROUGH */
893 : case NB_EV_PREPARE:
894 : case NB_EV_ABORT:
895 : return NB_OK;
896 : case NB_EV_APPLY:
897 : break;
898 : }
899 :
900 : /* Check for hook function. */
901 0 : if (rmap_match_set_hook.set_ip_nexthop == NULL)
902 : return NB_OK;
903 :
904 : /* Add configuration. */
905 0 : rhc = nb_running_get_entry(args->dnode, NULL, true);
906 0 : address = yang_dnode_get_string(args->dnode, NULL);
907 :
908 : /* Set destroy information. */
909 0 : rhc->rhc_shook = rmap_match_set_hook.no_set_ip_nexthop;
910 0 : rhc->rhc_rule = "ip next-hop";
911 :
912 0 : rv = rmap_match_set_hook.set_ip_nexthop(rhc->rhc_rmi, "ip next-hop",
913 : address,
914 : args->errmsg, args->errmsg_len);
915 0 : if (rv != CMD_SUCCESS) {
916 0 : rhc->rhc_shook = NULL;
917 0 : return NB_ERR_INCONSISTENCY;
918 : }
919 :
920 : return NB_OK;
921 : }
922 :
923 0 : static int lib_route_map_entry_set_action_ipv4_address_destroy(
924 : struct nb_cb_destroy_args *args)
925 : {
926 0 : return lib_route_map_entry_set_destroy(args);
927 : }
928 :
929 : /*
930 : * XPath: /frr-route-map:lib/route-map/entry/set-action/ipv6-address
931 : */
932 0 : static int lib_route_map_entry_set_action_ipv6_address_modify(
933 : struct nb_cb_modify_args *args)
934 : {
935 0 : struct routemap_hook_context *rhc;
936 0 : const char *address;
937 0 : struct in6_addr i6a;
938 0 : int rv;
939 :
940 0 : switch (args->event) {
941 0 : case NB_EV_VALIDATE:
942 : /*
943 : * NOTE: validate if 'action' is 'ipv6-next-hop',
944 : * currently it is not necessary because this is the
945 : * only implemented action. Other actions might have
946 : * different validations.
947 : */
948 0 : yang_dnode_get_ipv6(&i6a, args->dnode, NULL);
949 0 : if (!IN6_IS_ADDR_LINKLOCAL(&i6a))
950 : return NB_ERR_VALIDATION;
951 : /* FALLTHROUGH */
952 : case NB_EV_PREPARE:
953 : case NB_EV_ABORT:
954 : return NB_OK;
955 : case NB_EV_APPLY:
956 : break;
957 : }
958 :
959 : /* Check for hook function. */
960 0 : if (rmap_match_set_hook.set_ipv6_nexthop_local == NULL)
961 : return NB_OK;
962 :
963 : /* Add configuration. */
964 0 : rhc = nb_running_get_entry(args->dnode, NULL, true);
965 0 : address = yang_dnode_get_string(args->dnode, NULL);
966 :
967 : /* Set destroy information. */
968 0 : rhc->rhc_shook = rmap_match_set_hook.no_set_ipv6_nexthop_local;
969 0 : rhc->rhc_rule = "ipv6 next-hop local";
970 :
971 0 : rv = rmap_match_set_hook.set_ipv6_nexthop_local(
972 : rhc->rhc_rmi, "ipv6 next-hop local", address,
973 : args->errmsg, args->errmsg_len);
974 0 : if (rv != CMD_SUCCESS) {
975 0 : rhc->rhc_shook = NULL;
976 0 : return NB_ERR_INCONSISTENCY;
977 : }
978 :
979 : return NB_OK;
980 : }
981 :
982 0 : static int lib_route_map_entry_set_action_ipv6_address_destroy(
983 : struct nb_cb_destroy_args *args)
984 : {
985 0 : return lib_route_map_entry_set_destroy(args);
986 : }
987 :
988 : /*
989 : * XPath: /frr-route-map:lib/route-map/entry/set-action/value
990 : */
991 6 : static int set_action_modify(enum nb_event event, const struct lyd_node *dnode,
992 : union nb_resource *resource, const char *value,
993 : char *errmsg, size_t errmsg_len)
994 : {
995 6 : struct routemap_hook_context *rhc;
996 6 : int rv;
997 :
998 : /*
999 : * NOTE: validate if 'action' is 'metric', currently it is not
1000 : * necessary because this is the only implemented action. Other
1001 : * actions might have different validations.
1002 : */
1003 6 : if (event != NB_EV_APPLY)
1004 : return NB_OK;
1005 :
1006 : /* Check for hook function. */
1007 2 : if (rmap_match_set_hook.set_metric == NULL)
1008 : return NB_OK;
1009 :
1010 : /* Add configuration. */
1011 2 : rhc = nb_running_get_entry(dnode, NULL, true);
1012 :
1013 : /* Set destroy information. */
1014 2 : rhc->rhc_shook = rmap_match_set_hook.no_set_metric;
1015 2 : rhc->rhc_rule = "metric";
1016 :
1017 2 : rv = rmap_match_set_hook.set_metric(rhc->rhc_rmi, "metric",
1018 : value,
1019 : errmsg, errmsg_len
1020 : );
1021 2 : if (rv != CMD_SUCCESS) {
1022 0 : rhc->rhc_shook = NULL;
1023 0 : return NB_ERR_INCONSISTENCY;
1024 : }
1025 :
1026 : return NB_OK;
1027 : }
1028 :
1029 : static int
1030 6 : lib_route_map_entry_set_action_value_modify(struct nb_cb_modify_args *args)
1031 : {
1032 6 : const char *metric = yang_dnode_get_string(args->dnode, NULL);
1033 :
1034 6 : return set_action_modify(args->event, args->dnode, args->resource,
1035 : metric, args->errmsg, args->errmsg_len);
1036 : }
1037 :
1038 : static int
1039 0 : lib_route_map_entry_set_action_value_destroy(struct nb_cb_destroy_args *args)
1040 : {
1041 0 : return lib_route_map_entry_set_destroy(args);
1042 : }
1043 :
1044 : /*
1045 : * XPath: /frr-route-map:lib/route-map/entry/set-action/add-metric
1046 : */
1047 : static int
1048 0 : lib_route_map_entry_set_action_add_metric_modify(struct nb_cb_modify_args *args)
1049 : {
1050 0 : char metric_str[16];
1051 :
1052 0 : if (args->event == NB_EV_VALIDATE
1053 0 : && yang_dnode_get_uint32(args->dnode, NULL) == 0) {
1054 0 : snprintf(args->errmsg, args->errmsg_len,
1055 : "Can't add zero to metric");
1056 0 : return NB_ERR_VALIDATION;
1057 : }
1058 :
1059 0 : snprintf(metric_str, sizeof(metric_str), "+%s",
1060 : yang_dnode_get_string(args->dnode, NULL));
1061 0 : return set_action_modify(args->event, args->dnode, args->resource,
1062 : metric_str,
1063 : args->errmsg, args->errmsg_len);
1064 : }
1065 :
1066 0 : static int lib_route_map_entry_set_action_add_metric_destroy(
1067 : struct nb_cb_destroy_args *args)
1068 : {
1069 0 : return lib_route_map_entry_set_action_value_destroy(args);
1070 : }
1071 :
1072 : /*
1073 : * XPath: /frr-route-map:lib/route-map/entry/set-action/subtract-metric
1074 : */
1075 0 : static int lib_route_map_entry_set_action_subtract_metric_modify(
1076 : struct nb_cb_modify_args *args)
1077 : {
1078 0 : char metric_str[16];
1079 :
1080 0 : if (args->event == NB_EV_VALIDATE
1081 0 : && yang_dnode_get_uint32(args->dnode, NULL) == 0) {
1082 0 : snprintf(args->errmsg, args->errmsg_len,
1083 : "Can't subtract zero from metric");
1084 0 : return NB_ERR_VALIDATION;
1085 : }
1086 :
1087 0 : snprintf(metric_str, sizeof(metric_str), "-%s",
1088 : yang_dnode_get_string(args->dnode, NULL));
1089 0 : return set_action_modify(args->event, args->dnode, args->resource,
1090 : metric_str,
1091 : args->errmsg, args->errmsg_len);
1092 : }
1093 :
1094 0 : static int lib_route_map_entry_set_action_subtract_metric_destroy(
1095 : struct nb_cb_destroy_args *args)
1096 : {
1097 0 : return lib_route_map_entry_set_action_value_destroy(args);
1098 : }
1099 :
1100 : /*
1101 : * XPath: /frr-route-map:lib/route-map/entry/set-action/use-round-trip-time
1102 : */
1103 0 : static int lib_route_map_entry_set_action_use_round_trip_time_modify(
1104 : struct nb_cb_modify_args *args)
1105 : {
1106 0 : return set_action_modify(args->event, args->dnode, args->resource,
1107 : "rtt",
1108 : args->errmsg, args->errmsg_len);
1109 : }
1110 :
1111 0 : static int lib_route_map_entry_set_action_use_round_trip_time_destroy(
1112 : struct nb_cb_destroy_args *args)
1113 : {
1114 0 : return lib_route_map_entry_set_action_value_destroy(args);
1115 : }
1116 :
1117 : /*
1118 : * XPath: /frr-route-map:lib/route-map/entry/set-action/add-round-trip-time
1119 : */
1120 0 : static int lib_route_map_entry_set_action_add_round_trip_time_modify(
1121 : struct nb_cb_modify_args *args)
1122 : {
1123 0 : return set_action_modify(args->event, args->dnode, args->resource,
1124 : "+rtt",
1125 : args->errmsg, args->errmsg_len);
1126 : }
1127 :
1128 0 : static int lib_route_map_entry_set_action_add_round_trip_time_destroy(
1129 : struct nb_cb_destroy_args *args)
1130 : {
1131 0 : return lib_route_map_entry_set_action_value_destroy(args);
1132 : }
1133 :
1134 : /*
1135 : * XPath: /frr-route-map:lib/route-map/entry/set-action/subtract-round-trip-time
1136 : */
1137 0 : static int lib_route_map_entry_set_action_subtract_round_trip_time_modify(
1138 : struct nb_cb_modify_args *args)
1139 : {
1140 0 : return set_action_modify(args->event, args->dnode, args->resource,
1141 : "-rtt", args->errmsg, args->errmsg_len);
1142 : }
1143 :
1144 0 : static int lib_route_map_entry_set_action_subtract_round_trip_time_destroy(
1145 : struct nb_cb_destroy_args *args)
1146 : {
1147 0 : return lib_route_map_entry_set_action_value_destroy(args);
1148 : }
1149 :
1150 : /*
1151 : * XPath: /frr-route-map:lib/route-map/entry/set-action/tag
1152 : */
1153 : static int
1154 0 : lib_route_map_entry_set_action_tag_modify(struct nb_cb_modify_args *args)
1155 : {
1156 0 : struct routemap_hook_context *rhc;
1157 0 : const char *tag;
1158 0 : int rv;
1159 :
1160 : /*
1161 : * NOTE: validate if 'action' is 'tag', currently it is not
1162 : * necessary because this is the only implemented action. Other
1163 : * actions might have different validations.
1164 : */
1165 0 : if (args->event != NB_EV_APPLY)
1166 : return NB_OK;
1167 :
1168 : /* Check for hook function. */
1169 0 : if (rmap_match_set_hook.set_tag == NULL)
1170 : return NB_OK;
1171 :
1172 : /* Add configuration. */
1173 0 : rhc = nb_running_get_entry(args->dnode, NULL, true);
1174 0 : tag = yang_dnode_get_string(args->dnode, NULL);
1175 :
1176 : /* Set destroy information. */
1177 0 : rhc->rhc_shook = rmap_match_set_hook.no_set_tag;
1178 0 : rhc->rhc_rule = "tag";
1179 :
1180 0 : rv = rmap_match_set_hook.set_tag(rhc->rhc_rmi, "tag", tag,
1181 : args->errmsg, args->errmsg_len);
1182 0 : if (rv != CMD_SUCCESS) {
1183 0 : rhc->rhc_shook = NULL;
1184 0 : return NB_ERR_INCONSISTENCY;
1185 : }
1186 :
1187 : return NB_OK;
1188 : }
1189 :
1190 : static int
1191 0 : lib_route_map_entry_set_action_tag_destroy(struct nb_cb_destroy_args *args)
1192 : {
1193 0 : return lib_route_map_entry_set_destroy(args);
1194 : }
1195 :
1196 : /*
1197 : * XPath: /frr-route-map:lib/route-map/entry/set-action/policy
1198 : */
1199 : static int
1200 0 : lib_route_map_entry_set_action_policy_modify(struct nb_cb_modify_args *args)
1201 : {
1202 0 : struct routemap_hook_context *rhc;
1203 0 : const char *policy;
1204 0 : int rv;
1205 :
1206 : /*
1207 : * NOTE: validate if 'action' is 'tag', currently it is not
1208 : * necessary because this is the only implemented action. Other
1209 : * actions might have different validations.
1210 : */
1211 0 : if (args->event != NB_EV_APPLY)
1212 : return NB_OK;
1213 :
1214 : /* Check for hook function. */
1215 0 : if (rmap_match_set_hook.set_srte_color == NULL)
1216 : return NB_OK;
1217 :
1218 : /* Add configuration. */
1219 0 : rhc = nb_running_get_entry(args->dnode, NULL, true);
1220 0 : policy = yang_dnode_get_string(args->dnode, NULL);
1221 :
1222 : /* Set destroy information. */
1223 0 : rhc->rhc_shook = rmap_match_set_hook.no_set_tag;
1224 0 : rhc->rhc_rule = "sr-te color";
1225 :
1226 0 : rv = rmap_match_set_hook.set_tag(rhc->rhc_rmi, "sr-te color", policy,
1227 : args->errmsg, args->errmsg_len);
1228 0 : if (rv != CMD_SUCCESS) {
1229 0 : rhc->rhc_shook = NULL;
1230 0 : return NB_ERR_INCONSISTENCY;
1231 : }
1232 :
1233 : return NB_OK;
1234 : }
1235 :
1236 : static int
1237 0 : lib_route_map_entry_set_action_policy_destroy(struct nb_cb_destroy_args *args)
1238 : {
1239 0 : return lib_route_map_entry_set_destroy(args);
1240 : }
1241 :
1242 : /* clang-format off */
1243 : const struct frr_yang_module_info frr_route_map_info = {
1244 : .name = "frr-route-map",
1245 : .nodes = {
1246 : {
1247 : .xpath = "/frr-route-map:lib/route-map",
1248 : .cbs = {
1249 : .create = lib_route_map_create,
1250 : .destroy = lib_route_map_destroy,
1251 : }
1252 : },
1253 : {
1254 : .xpath = "/frr-route-map:lib/route-map/optimization-disabled",
1255 : .cbs = {
1256 : .modify = lib_route_map_optimization_disabled_modify,
1257 : .cli_show = route_map_optimization_disabled_show,
1258 : }
1259 : },
1260 : {
1261 : .xpath = "/frr-route-map:lib/route-map/entry",
1262 : .cbs = {
1263 : .create = lib_route_map_entry_create,
1264 : .destroy = lib_route_map_entry_destroy,
1265 : .cli_cmp = route_map_instance_cmp,
1266 : .cli_show = route_map_instance_show,
1267 : .cli_show_end = route_map_instance_show_end,
1268 : }
1269 : },
1270 : {
1271 : .xpath = "/frr-route-map:lib/route-map/entry/description",
1272 : .cbs = {
1273 : .modify = lib_route_map_entry_description_modify,
1274 : .destroy = lib_route_map_entry_description_destroy,
1275 : .cli_show = route_map_description_show,
1276 : }
1277 : },
1278 : {
1279 : .xpath = "/frr-route-map:lib/route-map/entry/action",
1280 : .cbs = {
1281 : .modify = lib_route_map_entry_action_modify,
1282 : }
1283 : },
1284 : {
1285 : .xpath = "/frr-route-map:lib/route-map/entry/call",
1286 : .cbs = {
1287 : .modify = lib_route_map_entry_call_modify,
1288 : .destroy = lib_route_map_entry_call_destroy,
1289 : .cli_show = route_map_call_show,
1290 : }
1291 : },
1292 : {
1293 : .xpath = "/frr-route-map:lib/route-map/entry/exit-policy",
1294 : .cbs = {
1295 : .modify = lib_route_map_entry_exit_policy_modify,
1296 : .cli_show = route_map_exit_policy_show,
1297 : }
1298 : },
1299 : {
1300 : .xpath = "/frr-route-map:lib/route-map/entry/goto-value",
1301 : .cbs = {
1302 : .modify = lib_route_map_entry_goto_value_modify,
1303 : .destroy = lib_route_map_entry_goto_value_destroy,
1304 : }
1305 : },
1306 : {
1307 : .xpath = "/frr-route-map:lib/route-map/entry/match-condition",
1308 : .cbs = {
1309 : .create = lib_route_map_entry_match_condition_create,
1310 : .destroy = lib_route_map_entry_match_condition_destroy,
1311 : .cli_show = route_map_condition_show,
1312 : }
1313 : },
1314 : {
1315 : .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/interface",
1316 : .cbs = {
1317 : .modify = lib_route_map_entry_match_condition_interface_modify,
1318 : .destroy = lib_route_map_entry_match_condition_interface_destroy,
1319 : }
1320 : },
1321 : {
1322 : .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/list-name",
1323 : .cbs = {
1324 : .modify = lib_route_map_entry_match_condition_list_name_modify,
1325 : .destroy = lib_route_map_entry_match_condition_list_name_destroy,
1326 : }
1327 : },
1328 : {
1329 : .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/ipv4-next-hop-type",
1330 : .cbs = {
1331 : .modify = lib_route_map_entry_match_condition_ipv4_next_hop_type_modify,
1332 : .destroy = lib_route_map_entry_match_condition_ipv4_next_hop_type_destroy,
1333 : }
1334 : },
1335 : {
1336 : .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/ipv6-next-hop-type",
1337 : .cbs = {
1338 : .modify = lib_route_map_entry_match_condition_ipv6_next_hop_type_modify,
1339 : .destroy = lib_route_map_entry_match_condition_ipv6_next_hop_type_destroy,
1340 : }
1341 : },
1342 : {
1343 : .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/metric",
1344 : .cbs = {
1345 : .modify = lib_route_map_entry_match_condition_metric_modify,
1346 : .destroy = lib_route_map_entry_match_condition_metric_destroy,
1347 : }
1348 : },
1349 : {
1350 : .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/tag",
1351 : .cbs = {
1352 : .modify = lib_route_map_entry_match_condition_tag_modify,
1353 : .destroy = lib_route_map_entry_match_condition_tag_destroy,
1354 : }
1355 : },
1356 : {
1357 : .xpath = "/frr-route-map:lib/route-map/entry/set-action",
1358 : .cbs = {
1359 : .create = lib_route_map_entry_set_action_create,
1360 : .destroy = lib_route_map_entry_set_action_destroy,
1361 : .cli_show = route_map_action_show,
1362 : }
1363 : },
1364 : {
1365 : .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/ipv4-address",
1366 : .cbs = {
1367 : .modify = lib_route_map_entry_set_action_ipv4_address_modify,
1368 : .destroy = lib_route_map_entry_set_action_ipv4_address_destroy,
1369 : }
1370 : },
1371 : {
1372 : .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/ipv6-address",
1373 : .cbs = {
1374 : .modify = lib_route_map_entry_set_action_ipv6_address_modify,
1375 : .destroy = lib_route_map_entry_set_action_ipv6_address_destroy,
1376 : }
1377 : },
1378 : {
1379 : .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/value",
1380 : .cbs = {
1381 : .modify = lib_route_map_entry_set_action_value_modify,
1382 : .destroy = lib_route_map_entry_set_action_value_destroy,
1383 : }
1384 : },
1385 : {
1386 : .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/add-metric",
1387 : .cbs = {
1388 : .modify = lib_route_map_entry_set_action_add_metric_modify,
1389 : .destroy = lib_route_map_entry_set_action_add_metric_destroy,
1390 : }
1391 : },
1392 : {
1393 : .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/subtract-metric",
1394 : .cbs = {
1395 : .modify = lib_route_map_entry_set_action_subtract_metric_modify,
1396 : .destroy = lib_route_map_entry_set_action_subtract_metric_destroy,
1397 : }
1398 : },
1399 : {
1400 : .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/use-round-trip-time",
1401 : .cbs = {
1402 : .modify = lib_route_map_entry_set_action_use_round_trip_time_modify,
1403 : .destroy = lib_route_map_entry_set_action_use_round_trip_time_destroy,
1404 : }
1405 : },
1406 : {
1407 : .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/add-round-trip-time",
1408 : .cbs = {
1409 : .modify = lib_route_map_entry_set_action_add_round_trip_time_modify,
1410 : .destroy = lib_route_map_entry_set_action_add_round_trip_time_destroy,
1411 : }
1412 : },
1413 : {
1414 : .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/subtract-round-trip-time",
1415 : .cbs = {
1416 : .modify = lib_route_map_entry_set_action_subtract_round_trip_time_modify,
1417 : .destroy = lib_route_map_entry_set_action_subtract_round_trip_time_destroy,
1418 : }
1419 : },
1420 : {
1421 : .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/tag",
1422 : .cbs = {
1423 : .modify = lib_route_map_entry_set_action_tag_modify,
1424 : .destroy = lib_route_map_entry_set_action_tag_destroy,
1425 : }
1426 : },
1427 : {
1428 : .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/policy",
1429 : .cbs = {
1430 : .modify = lib_route_map_entry_set_action_policy_modify,
1431 : .destroy = lib_route_map_entry_set_action_policy_destroy,
1432 : }
1433 : },
1434 :
1435 : {
1436 : .xpath = NULL,
1437 : },
1438 : }
1439 : };
|