]> git.proxmox.com Git - mirror_frr.git/blob - lib/routemap_cli.c
Merge pull request #13649 from donaldsharp/unlock_the_node_or_else
[mirror_frr.git] / lib / routemap_cli.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Route map northbound CLI implementation.
4 *
5 * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
6 * Rafael Zalamena
7 */
8
9 #include <zebra.h>
10
11 #include "lib/command.h"
12 #include "lib/northbound_cli.h"
13 #include "lib/routemap.h"
14
15 #include "lib/routemap_cli_clippy.c"
16
17 #define ROUTE_MAP_CMD_STR \
18 "Create route-map or enter route-map command mode\n" \
19 "Route map tag\n"
20 #define ROUTE_MAP_OP_CMD_STR \
21 "Route map denies set operations\n" \
22 "Route map permits set operations\n"
23 #define ROUTE_MAP_SEQUENCE_CMD_STR \
24 "Sequence to insert to/delete from existing route-map entry\n"
25
26 DEFPY_YANG_NOSH(
27 route_map, route_map_cmd,
28 "route-map RMAP_NAME$name <deny|permit>$action (1-65535)$sequence",
29 ROUTE_MAP_CMD_STR
30 ROUTE_MAP_OP_CMD_STR
31 ROUTE_MAP_SEQUENCE_CMD_STR)
32 {
33 char xpath_action[XPATH_MAXLEN + 64];
34 char xpath_index[XPATH_MAXLEN + 32];
35 char xpath[XPATH_MAXLEN];
36 int rv;
37
38 snprintf(xpath, sizeof(xpath),
39 "/frr-route-map:lib/route-map[name='%s']", name);
40 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
41
42 snprintf(xpath_index, sizeof(xpath_index), "%s/entry[sequence='%lu']",
43 xpath, sequence);
44 nb_cli_enqueue_change(vty, xpath_index, NB_OP_CREATE, NULL);
45
46 snprintf(xpath_action, sizeof(xpath_action), "%s/action", xpath_index);
47 nb_cli_enqueue_change(vty, xpath_action, NB_OP_MODIFY, action);
48
49 rv = nb_cli_apply_changes(vty, NULL);
50 if (rv == CMD_SUCCESS)
51 VTY_PUSH_XPATH(RMAP_NODE, xpath_index);
52
53 return rv;
54 }
55
56 DEFPY_YANG(
57 no_route_map_all, no_route_map_all_cmd,
58 "no route-map RMAP_NAME$name",
59 NO_STR
60 ROUTE_MAP_CMD_STR)
61 {
62 char xpath[XPATH_MAXLEN];
63
64 snprintf(xpath, sizeof(xpath),
65 "/frr-route-map:lib/route-map[name='%s']", name);
66 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
67
68 return nb_cli_apply_changes(vty, NULL);
69 }
70
71 DEFPY_YANG(
72 no_route_map, no_route_map_cmd,
73 "no route-map RMAP_NAME$name <deny|permit>$action (1-65535)$sequence",
74 NO_STR
75 ROUTE_MAP_CMD_STR
76 ROUTE_MAP_OP_CMD_STR
77 ROUTE_MAP_SEQUENCE_CMD_STR)
78 {
79 char xpath[XPATH_MAXLEN];
80
81 snprintf(xpath, sizeof(xpath),
82 "/frr-route-map:lib/route-map[name='%s']/entry[sequence='%lu']",
83 name, sequence);
84
85 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
86
87 return nb_cli_apply_changes(vty, NULL);
88 }
89
90 int route_map_instance_cmp(const struct lyd_node *dnode1,
91 const struct lyd_node *dnode2)
92 {
93 uint16_t seq1 = yang_dnode_get_uint16(dnode1, "./sequence");
94 uint16_t seq2 = yang_dnode_get_uint16(dnode2, "./sequence");
95
96 return seq1 - seq2;
97 }
98
99 void route_map_instance_show(struct vty *vty, const struct lyd_node *dnode,
100 bool show_defaults)
101 {
102 const char *name = yang_dnode_get_string(dnode, "../name");
103 const char *action = yang_dnode_get_string(dnode, "./action");
104 const char *sequence = yang_dnode_get_string(dnode, "./sequence");
105
106 vty_out(vty, "route-map %s %s %s\n", name, action, sequence);
107
108 }
109
110 void route_map_instance_show_end(struct vty *vty, const struct lyd_node *dnode)
111 {
112 vty_out(vty, "exit\n");
113 vty_out(vty, "!\n");
114 }
115
116 DEFPY_YANG(
117 match_interface, match_interface_cmd,
118 "match interface IFNAME",
119 MATCH_STR
120 "Match first hop interface of route\n"
121 INTERFACE_STR)
122 {
123 const char *xpath =
124 "./match-condition[condition='frr-route-map:interface']";
125 char xpath_value[XPATH_MAXLEN];
126
127 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
128 snprintf(xpath_value, sizeof(xpath_value),
129 "%s/rmap-match-condition/interface", xpath);
130 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, ifname);
131
132 return nb_cli_apply_changes(vty, NULL);
133 }
134
135 DEFPY_YANG(
136 no_match_interface, no_match_interface_cmd,
137 "no match interface [IFNAME]",
138 NO_STR
139 MATCH_STR
140 "Match first hop interface of route\n"
141 INTERFACE_STR)
142 {
143 const char *xpath =
144 "./match-condition[condition='frr-route-map:interface']";
145
146 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
147
148 return nb_cli_apply_changes(vty, NULL);
149 }
150
151 DEFPY_YANG(
152 match_ip_address, match_ip_address_cmd,
153 "match ip address ACCESSLIST4_NAME$name",
154 MATCH_STR
155 IP_STR
156 "Match address of route\n"
157 "IP Access-list name\n")
158 {
159 const char *xpath =
160 "./match-condition[condition='frr-route-map:ipv4-address-list']";
161 char xpath_value[XPATH_MAXLEN + 32];
162
163 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
164 snprintf(xpath_value, sizeof(xpath_value),
165 "%s/rmap-match-condition/list-name", xpath);
166 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name);
167
168 return nb_cli_apply_changes(vty, NULL);
169 }
170
171 DEFPY_YANG(
172 no_match_ip_address, no_match_ip_address_cmd,
173 "no match ip address [ACCESSLIST4_NAME]",
174 NO_STR
175 MATCH_STR
176 IP_STR
177 "Match address of route\n"
178 "IP Access-list name\n")
179 {
180 const char *xpath =
181 "./match-condition[condition='frr-route-map:ipv4-address-list']";
182
183 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
184
185 return nb_cli_apply_changes(vty, NULL);
186 }
187
188 DEFPY_YANG(
189 match_ip_address_prefix_list,
190 match_ip_address_prefix_list_cmd,
191 "match ip address prefix-list PREFIXLIST_NAME$name",
192 MATCH_STR
193 IP_STR
194 "Match address of route\n"
195 "Match entries of prefix-lists\n"
196 "IP prefix-list name\n")
197 {
198 const char *xpath =
199 "./match-condition[condition='frr-route-map:ipv4-prefix-list']";
200 char xpath_value[XPATH_MAXLEN];
201
202 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
203 snprintf(xpath_value, sizeof(xpath_value),
204 "%s/rmap-match-condition/list-name", xpath);
205 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name);
206
207 return nb_cli_apply_changes(vty, NULL);
208 }
209
210 DEFPY_YANG(
211 no_match_ip_address_prefix_list, no_match_ip_address_prefix_list_cmd,
212 "no match ip address prefix-list [PREFIXLIST_NAME]",
213 NO_STR
214 MATCH_STR
215 IP_STR
216 "Match address of route\n"
217 "Match entries of prefix-lists\n"
218 "IP prefix-list name\n")
219 {
220 const char *xpath =
221 "./match-condition[condition='frr-route-map:ipv4-prefix-list']";
222
223 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
224
225 return nb_cli_apply_changes(vty, NULL);
226 }
227
228 DEFPY_YANG(
229 match_ip_next_hop, match_ip_next_hop_cmd,
230 "match ip next-hop ACCESSLIST4_NAME$name",
231 MATCH_STR
232 IP_STR
233 "Match next-hop address of route\n"
234 "IP Access-list name\n")
235 {
236 const char *xpath =
237 "./match-condition[condition='frr-route-map:ipv4-next-hop-list']";
238 char xpath_value[XPATH_MAXLEN + 32];
239
240 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
241 snprintf(xpath_value, sizeof(xpath_value),
242 "%s/rmap-match-condition/list-name", xpath);
243 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name);
244
245 return nb_cli_apply_changes(vty, NULL);
246 }
247
248 DEFPY_YANG(
249 no_match_ip_next_hop, no_match_ip_next_hop_cmd,
250 "no match ip next-hop [ACCESSLIST4_NAME]",
251 NO_STR
252 MATCH_STR
253 IP_STR
254 "Match address of route\n"
255 "IP Access-list name\n")
256 {
257 const char *xpath =
258 "./match-condition[condition='frr-route-map:ipv4-next-hop-list']";
259
260 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
261
262 return nb_cli_apply_changes(vty, NULL);
263 }
264
265 DEFPY_YANG(
266 match_ip_next_hop_prefix_list,
267 match_ip_next_hop_prefix_list_cmd,
268 "match ip next-hop prefix-list PREFIXLIST_NAME$name",
269 MATCH_STR
270 IP_STR
271 "Match next-hop address of route\n"
272 "Match entries of prefix-lists\n"
273 "IP prefix-list name\n")
274 {
275 const char *xpath =
276 "./match-condition[condition='frr-route-map:ipv4-next-hop-prefix-list']";
277 char xpath_value[XPATH_MAXLEN];
278
279 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
280 snprintf(xpath_value, sizeof(xpath_value),
281 "%s/rmap-match-condition/list-name", xpath);
282 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name);
283
284 return nb_cli_apply_changes(vty, NULL);
285 }
286
287 DEFPY_YANG(
288 no_match_ip_next_hop_prefix_list,
289 no_match_ip_next_hop_prefix_list_cmd,
290 "no match ip next-hop prefix-list [PREFIXLIST_NAME]",
291 NO_STR
292 MATCH_STR
293 IP_STR
294 "Match next-hop address of route\n"
295 "Match entries of prefix-lists\n"
296 "IP prefix-list name\n")
297 {
298 const char *xpath =
299 "./match-condition[condition='frr-route-map:ipv4-next-hop-prefix-list']";
300
301 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
302
303 return nb_cli_apply_changes(vty, NULL);
304 }
305
306 DEFPY_YANG(
307 match_ip_next_hop_type, match_ip_next_hop_type_cmd,
308 "match ip next-hop type <blackhole>$type",
309 MATCH_STR
310 IP_STR
311 "Match next-hop address of route\n"
312 "Match entries by type\n"
313 "Blackhole\n")
314 {
315 const char *xpath =
316 "./match-condition[condition='frr-route-map:ipv4-next-hop-type']";
317 char xpath_value[XPATH_MAXLEN];
318
319 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
320 snprintf(xpath_value, sizeof(xpath_value),
321 "%s/rmap-match-condition/ipv4-next-hop-type", xpath);
322 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, type);
323
324 return nb_cli_apply_changes(vty, NULL);
325 }
326
327 DEFPY_YANG(
328 no_match_ip_next_hop_type, no_match_ip_next_hop_type_cmd,
329 "no match ip next-hop type [<blackhole>]",
330 NO_STR MATCH_STR IP_STR
331 "Match next-hop address of route\n"
332 "Match entries by type\n"
333 "Blackhole\n")
334 {
335 const char *xpath =
336 "./match-condition[condition='frr-route-map:ipv4-next-hop-type']";
337
338 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
339
340 return nb_cli_apply_changes(vty, NULL);
341 }
342
343 DEFPY_YANG(
344 match_ipv6_address, match_ipv6_address_cmd,
345 "match ipv6 address ACCESSLIST6_NAME$name",
346 MATCH_STR
347 IPV6_STR
348 "Match IPv6 address of route\n"
349 "IPv6 access-list name\n")
350 {
351 const char *xpath =
352 "./match-condition[condition='frr-route-map:ipv6-address-list']";
353 char xpath_value[XPATH_MAXLEN];
354
355 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
356 snprintf(xpath_value, sizeof(xpath_value),
357 "%s/rmap-match-condition/list-name", xpath);
358 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name);
359
360 return nb_cli_apply_changes(vty, NULL);
361 }
362
363 DEFPY_YANG(
364 no_match_ipv6_address, no_match_ipv6_address_cmd,
365 "no match ipv6 address [ACCESSLIST6_NAME]",
366 NO_STR
367 MATCH_STR
368 IPV6_STR
369 "Match IPv6 address of route\n"
370 "IPv6 access-list name\n")
371 {
372 const char *xpath =
373 "./match-condition[condition='frr-route-map:ipv6-address-list']";
374
375 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
376
377 return nb_cli_apply_changes(vty, NULL);
378 }
379
380 DEFPY_YANG(
381 match_ipv6_address_prefix_list, match_ipv6_address_prefix_list_cmd,
382 "match ipv6 address prefix-list PREFIXLIST_NAME$name",
383 MATCH_STR
384 IPV6_STR
385 "Match address of route\n"
386 "Match entries of prefix-lists\n"
387 "IP prefix-list name\n")
388 {
389 const char *xpath =
390 "./match-condition[condition='frr-route-map:ipv6-prefix-list']";
391 char xpath_value[XPATH_MAXLEN];
392
393 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
394 snprintf(xpath_value, sizeof(xpath_value),
395 "%s/rmap-match-condition/list-name", xpath);
396 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name);
397
398 return nb_cli_apply_changes(vty, NULL);
399 }
400
401 DEFPY_YANG(
402 no_match_ipv6_address_prefix_list,
403 no_match_ipv6_address_prefix_list_cmd,
404 "no match ipv6 address prefix-list [PREFIXLIST_NAME]",
405 NO_STR
406 MATCH_STR
407 IPV6_STR
408 "Match address of route\n"
409 "Match entries of prefix-lists\n"
410 "IP prefix-list name\n")
411 {
412 const char *xpath =
413 "./match-condition[condition='frr-route-map:ipv6-prefix-list']";
414
415 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
416
417 return nb_cli_apply_changes(vty, NULL);
418 }
419
420 DEFPY_YANG(
421 match_ipv6_next_hop_type, match_ipv6_next_hop_type_cmd,
422 "match ipv6 next-hop type <blackhole>$type",
423 MATCH_STR IPV6_STR
424 "Match next-hop address of route\n"
425 "Match entries by type\n"
426 "Blackhole\n")
427 {
428 const char *xpath =
429 "./match-condition[condition='frr-route-map:ipv6-next-hop-type']";
430 char xpath_value[XPATH_MAXLEN];
431
432 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
433 snprintf(xpath_value, sizeof(xpath_value),
434 "%s/rmap-match-condition/ipv6-next-hop-type", xpath);
435 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, type);
436
437 return nb_cli_apply_changes(vty, NULL);
438 }
439
440 DEFPY_YANG(
441 no_match_ipv6_next_hop_type, no_match_ipv6_next_hop_type_cmd,
442 "no match ipv6 next-hop type [<blackhole>]",
443 NO_STR MATCH_STR IPV6_STR
444 "Match address of route\n"
445 "Match entries by type\n"
446 "Blackhole\n")
447 {
448 const char *xpath =
449 "./match-condition[condition='frr-route-map:ipv6-next-hop-type']";
450
451 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
452
453 return nb_cli_apply_changes(vty, NULL);
454 }
455
456 DEFPY_YANG(
457 match_metric, match_metric_cmd,
458 "match metric (0-4294967295)$metric",
459 MATCH_STR
460 "Match metric of route\n"
461 "Metric value\n")
462 {
463 const char *xpath =
464 "./match-condition[condition='frr-route-map:match-metric']";
465 char xpath_value[XPATH_MAXLEN];
466
467 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
468 snprintf(xpath_value, sizeof(xpath_value),
469 "%s/rmap-match-condition/metric", xpath);
470 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, metric_str);
471
472 return nb_cli_apply_changes(vty, NULL);
473 }
474
475 DEFPY_YANG(
476 no_match_metric, no_match_metric_cmd,
477 "no match metric [(0-4294967295)]",
478 NO_STR
479 MATCH_STR
480 "Match metric of route\n"
481 "Metric value\n")
482 {
483 const char *xpath =
484 "./match-condition[condition='frr-route-map:match-metric']";
485
486 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
487
488 return nb_cli_apply_changes(vty, NULL);
489 }
490
491 DEFPY_YANG(
492 match_tag, match_tag_cmd,
493 "match tag (1-4294967295)$tag",
494 MATCH_STR
495 "Match tag of route\n"
496 "Tag value\n")
497 {
498 const char *xpath =
499 "./match-condition[condition='frr-route-map:match-tag']";
500 char xpath_value[XPATH_MAXLEN];
501
502 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
503 snprintf(xpath_value, sizeof(xpath_value),
504 "%s/rmap-match-condition/tag", xpath);
505 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, tag_str);
506
507 return nb_cli_apply_changes(vty, NULL);
508 }
509
510 DEFPY_YANG(
511 no_match_tag, no_match_tag_cmd,
512 "no match tag [(1-4294967295)]",
513 NO_STR
514 MATCH_STR
515 "Match tag of route\n"
516 "Tag value\n")
517 {
518 const char *xpath =
519 "./match-condition[condition='frr-route-map:match-tag']";
520
521 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
522
523 return nb_cli_apply_changes(vty, NULL);
524 }
525
526 void route_map_condition_show(struct vty *vty, const struct lyd_node *dnode,
527 bool show_defaults)
528 {
529 const char *condition = yang_dnode_get_string(dnode, "./condition");
530 const struct lyd_node *ln;
531 const char *acl;
532
533 if (IS_MATCH_INTERFACE(condition)) {
534 vty_out(vty, " match interface %s\n",
535 yang_dnode_get_string(
536 dnode, "./rmap-match-condition/interface"));
537 } else if (IS_MATCH_IPv4_ADDRESS_LIST(condition)) {
538 vty_out(vty, " match ip address %s\n",
539 yang_dnode_get_string(
540 dnode, "./rmap-match-condition/list-name"));
541 } else if (IS_MATCH_IPv4_NEXTHOP_LIST(condition)) {
542 vty_out(vty, " match ip next-hop %s\n",
543 yang_dnode_get_string(
544 dnode, "./rmap-match-condition/list-name"));
545 } else if (IS_MATCH_IPv6_NEXTHOP_LIST(condition)) {
546 vty_out(vty, " match ipv6 next-hop %s\n",
547 yang_dnode_get_string(
548 dnode, "./rmap-match-condition/list-name"));
549 } else if (IS_MATCH_IPv4_PREFIX_LIST(condition)) {
550 vty_out(vty, " match ip address prefix-list %s\n",
551 yang_dnode_get_string(
552 dnode, "./rmap-match-condition/list-name"));
553 } else if (IS_MATCH_IPv4_NEXTHOP_PREFIX_LIST(condition)) {
554 vty_out(vty, " match ip next-hop prefix-list %s\n",
555 yang_dnode_get_string(
556 dnode, "./rmap-match-condition/list-name"));
557 } else if (IS_MATCH_IPv6_NEXTHOP_PREFIX_LIST(condition)) {
558 vty_out(vty, " match ipv6 next-hop prefix-list %s\n",
559 yang_dnode_get_string(
560 dnode, "./rmap-match-condition/list-name"));
561 } else if (IS_MATCH_IPv6_ADDRESS_LIST(condition)) {
562 vty_out(vty, " match ipv6 address %s\n",
563 yang_dnode_get_string(
564 dnode, "./rmap-match-condition/list-name"));
565 } else if (IS_MATCH_IPv6_PREFIX_LIST(condition)) {
566 vty_out(vty, " match ipv6 address prefix-list %s\n",
567 yang_dnode_get_string(
568 dnode, "./rmap-match-condition/list-name"));
569 } else if (IS_MATCH_IPv4_NEXTHOP_TYPE(condition)) {
570 vty_out(vty, " match ip next-hop type %s\n",
571 yang_dnode_get_string(
572 dnode,
573 "./rmap-match-condition/ipv4-next-hop-type"));
574 } else if (IS_MATCH_IPv6_NEXTHOP_TYPE(condition)) {
575 vty_out(vty, " match ipv6 next-hop type %s\n",
576 yang_dnode_get_string(
577 dnode,
578 "./rmap-match-condition/ipv6-next-hop-type"));
579 } else if (IS_MATCH_METRIC(condition)) {
580 vty_out(vty, " match metric %s\n",
581 yang_dnode_get_string(dnode,
582 "./rmap-match-condition/metric"));
583 } else if (IS_MATCH_TAG(condition)) {
584 vty_out(vty, " match tag %s\n",
585 yang_dnode_get_string(dnode,
586 "./rmap-match-condition/tag"));
587 } else if (IS_MATCH_IPv4_PREFIX_LEN(condition)) {
588 vty_out(vty, " match ip address prefix-len %s\n",
589 yang_dnode_get_string(
590 dnode,
591 "./rmap-match-condition/frr-zebra-route-map:ipv4-prefix-length"));
592 } else if (IS_MATCH_IPv6_PREFIX_LEN(condition)) {
593 vty_out(vty, " match ipv6 address prefix-len %s\n",
594 yang_dnode_get_string(
595 dnode,
596 "./rmap-match-condition/frr-zebra-route-map:ipv6-prefix-length"));
597 } else if (IS_MATCH_IPv4_NH_PREFIX_LEN(condition)) {
598 vty_out(vty, " match ip next-hop prefix-len %s\n",
599 yang_dnode_get_string(
600 dnode,
601 "./rmap-match-condition/frr-zebra-route-map:ipv4-prefix-length"));
602 } else if (IS_MATCH_SRC_PROTO(condition) ||
603 IS_MATCH_BGP_SRC_PROTO(condition)) {
604 vty_out(vty, " match source-protocol %s\n",
605 yang_dnode_get_string(
606 dnode,
607 IS_MATCH_SRC_PROTO(condition)
608 ? "./rmap-match-condition/frr-zebra-route-map:source-protocol"
609 : "./rmap-match-condition/frr-bgp-route-map:source-protocol"));
610 } else if (IS_MATCH_SRC_INSTANCE(condition)) {
611 vty_out(vty, " match source-instance %s\n",
612 yang_dnode_get_string(
613 dnode,
614 "./rmap-match-condition/frr-zebra-route-map:source-instance"));
615 } else if (IS_MATCH_LOCAL_PREF(condition)) {
616 vty_out(vty, " match local-preference %s\n",
617 yang_dnode_get_string(
618 dnode,
619 "./rmap-match-condition/frr-bgp-route-map:local-preference"));
620 } else if (IS_MATCH_ALIAS(condition)) {
621 vty_out(vty, " match alias %s\n",
622 yang_dnode_get_string(
623 dnode,
624 "./rmap-match-condition/frr-bgp-route-map:alias"));
625 } else if (IS_MATCH_SCRIPT(condition)) {
626 vty_out(vty, " match script %s\n",
627 yang_dnode_get_string(
628 dnode,
629 "./rmap-match-condition/frr-bgp-route-map:script"));
630 } else if (IS_MATCH_ORIGIN(condition)) {
631 vty_out(vty, " match origin %s\n",
632 yang_dnode_get_string(
633 dnode,
634 "./rmap-match-condition/frr-bgp-route-map:origin"));
635 } else if (IS_MATCH_RPKI(condition)) {
636 vty_out(vty, " match rpki %s\n",
637 yang_dnode_get_string(
638 dnode,
639 "./rmap-match-condition/frr-bgp-route-map:rpki"));
640 } else if (IS_MATCH_RPKI_EXTCOMMUNITY(condition)) {
641 vty_out(vty, " match rpki-extcommunity %s\n",
642 yang_dnode_get_string(
643 dnode,
644 "./rmap-match-condition/frr-bgp-route-map:rpki-extcommunity"));
645 } else if (IS_MATCH_PROBABILITY(condition)) {
646 vty_out(vty, " match probability %s\n",
647 yang_dnode_get_string(
648 dnode,
649 "./rmap-match-condition/frr-bgp-route-map:probability"));
650 } else if (IS_MATCH_SRC_VRF(condition)) {
651 vty_out(vty, " match source-vrf %s\n",
652 yang_dnode_get_string(
653 dnode,
654 "./rmap-match-condition/frr-bgp-route-map:source-vrf"));
655 } else if (IS_MATCH_PEER(condition)) {
656 acl = NULL;
657 if ((ln = yang_dnode_get(
658 dnode,
659 "./rmap-match-condition/frr-bgp-route-map:peer-ipv4-address"))
660 != NULL)
661 acl = yang_dnode_get_string(ln, NULL);
662 else if (
663 (ln = yang_dnode_get(
664 dnode,
665 "./rmap-match-condition/frr-bgp-route-map:peer-ipv6-address"))
666 != NULL)
667 acl = yang_dnode_get_string(ln, NULL);
668 else if (
669 (ln = yang_dnode_get(
670 dnode,
671 "./rmap-match-condition/frr-bgp-route-map:peer-interface"))
672 != NULL)
673 acl = yang_dnode_get_string(ln, NULL);
674 else if (yang_dnode_get(
675 dnode,
676 "./rmap-match-condition/frr-bgp-route-map:peer-local")
677 != NULL)
678 acl = "local";
679
680 vty_out(vty, " match peer %s\n", acl);
681 } else if (IS_MATCH_AS_LIST(condition)) {
682 vty_out(vty, " match as-path %s\n",
683 yang_dnode_get_string(
684 dnode,
685 "./rmap-match-condition/frr-bgp-route-map:list-name"));
686 } else if (IS_MATCH_EVPN_ROUTE_TYPE(condition)) {
687 vty_out(vty, " match evpn route-type %s\n",
688 yang_dnode_get_string(
689 dnode,
690 "./rmap-match-condition/frr-bgp-route-map:evpn-route-type"));
691 } else if (IS_MATCH_EVPN_DEFAULT_ROUTE(condition)) {
692 vty_out(vty, " match evpn default-route\n");
693 } else if (IS_MATCH_EVPN_VNI(condition)) {
694 vty_out(vty, " match evpn vni %s\n",
695 yang_dnode_get_string(
696 dnode,
697 "./rmap-match-condition/frr-bgp-route-map:evpn-vni"));
698 } else if (IS_MATCH_EVPN_DEFAULT_ROUTE(condition)) {
699 vty_out(vty, " match evpn default-route %s\n",
700 yang_dnode_get_string(
701 dnode,
702 "./rmap-match-condition/frr-bgp-route-map:evpn-default-route"));
703 } else if (IS_MATCH_EVPN_RD(condition)) {
704 vty_out(vty, " match evpn rd %s\n",
705 yang_dnode_get_string(
706 dnode,
707 "./rmap-match-condition/frr-bgp-route-map:route-distinguisher"));
708 } else if (IS_MATCH_MAC_LIST(condition)) {
709 vty_out(vty, " match mac address %s\n",
710 yang_dnode_get_string(
711 dnode,
712 "./rmap-match-condition/frr-bgp-route-map:list-name"));
713 } else if (IS_MATCH_ROUTE_SRC(condition)) {
714 vty_out(vty, " match ip route-source %s\n",
715 yang_dnode_get_string(
716 dnode,
717 "./rmap-match-condition/frr-bgp-route-map:list-name"));
718 } else if (IS_MATCH_ROUTE_SRC_PL(condition)) {
719 vty_out(vty, " match ip route-source prefix-list %s\n",
720 yang_dnode_get_string(
721 dnode,
722 "./rmap-match-condition/frr-bgp-route-map:list-name"));
723 } else if (IS_MATCH_COMMUNITY(condition)) {
724 vty_out(vty, " match community %s",
725 yang_dnode_get_string(
726 dnode,
727 "./rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name"));
728 if (yang_dnode_get_bool(
729 dnode,
730 "./rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match"))
731 vty_out(vty, " exact-match");
732 vty_out(vty, "\n");
733 } else if (IS_MATCH_LCOMMUNITY(condition)) {
734 vty_out(vty, " match large-community %s",
735 yang_dnode_get_string(
736 dnode,
737 "./rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name"));
738 if (yang_dnode_get_bool(
739 dnode,
740 "./rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match"))
741 vty_out(vty, " exact-match");
742 vty_out(vty, "\n");
743 } else if (IS_MATCH_EXTCOMMUNITY(condition)) {
744 vty_out(vty, " match extcommunity %s\n",
745 yang_dnode_get_string(
746 dnode,
747 "./rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name"));
748 } else if (IS_MATCH_IPV4_NH(condition)) {
749 vty_out(vty, " match ip next-hop address %s\n",
750 yang_dnode_get_string(
751 dnode,
752 "./rmap-match-condition/frr-bgp-route-map:ipv4-address"));
753 } else if (IS_MATCH_IPV6_NH(condition)) {
754 vty_out(vty, " match ipv6 next-hop address %s\n",
755 yang_dnode_get_string(
756 dnode,
757 "./rmap-match-condition/frr-bgp-route-map:ipv6-address"));
758 }
759 }
760
761 DEFPY_YANG(
762 set_ip_nexthop, set_ip_nexthop_cmd,
763 "set ip next-hop A.B.C.D$addr",
764 SET_STR
765 IP_STR
766 "Next hop address\n"
767 "IP address of next hop\n")
768 {
769 const char *xpath =
770 "./set-action[action='frr-route-map:ipv4-next-hop']";
771 char xpath_value[XPATH_MAXLEN];
772
773 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
774 snprintf(xpath_value, sizeof(xpath_value),
775 "%s/rmap-set-action/ipv4-address", xpath);
776 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, addr_str);
777
778 return nb_cli_apply_changes(vty, NULL);
779 }
780
781 DEFPY_YANG(
782 no_set_ip_nexthop, no_set_ip_nexthop_cmd,
783 "no set ip next-hop [A.B.C.D]",
784 NO_STR
785 SET_STR
786 IP_STR
787 "Next hop address\n"
788 "IP address of next hop\n")
789 {
790 const char *xpath =
791 "./set-action[action='frr-route-map:ipv4-next-hop']";
792
793 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
794
795 return nb_cli_apply_changes(vty, NULL);
796 }
797
798 DEFPY_YANG(
799 set_ipv6_nexthop_local, set_ipv6_nexthop_local_cmd,
800 "set ipv6 next-hop local X:X::X:X$addr",
801 SET_STR
802 IPV6_STR
803 "IPv6 next-hop address\n"
804 "IPv6 local address\n"
805 "IPv6 address of next hop\n")
806 {
807 const char *xpath =
808 "./set-action[action='frr-route-map:ipv6-next-hop']";
809 char xpath_value[XPATH_MAXLEN];
810
811 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
812 snprintf(xpath_value, sizeof(xpath_value),
813 "%s/rmap-set-action/ipv6-address", xpath);
814 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, addr_str);
815
816 return nb_cli_apply_changes(vty, NULL);
817 }
818
819 DEFPY_YANG(
820 no_set_ipv6_nexthop_local, no_set_ipv6_nexthop_local_cmd,
821 "no set ipv6 next-hop local [X:X::X:X]",
822 NO_STR
823 SET_STR
824 IPV6_STR
825 "IPv6 next-hop address\n"
826 "IPv6 local address\n"
827 "IPv6 address of next hop\n")
828 {
829 const char *xpath =
830 "./set-action[action='frr-route-map:ipv6-next-hop']";
831
832 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
833
834 return nb_cli_apply_changes(vty, NULL);
835 }
836
837 DEFPY_YANG(
838 set_metric, set_metric_cmd,
839 "set metric <(-4294967295-4294967295)$metric|rtt$rtt|+rtt$artt|-rtt$srtt>",
840 SET_STR
841 "Metric value for destination routing protocol\n"
842 "Metric value (use +/- for additions or subtractions)\n"
843 "Assign round trip time\n"
844 "Add round trip time\n"
845 "Subtract round trip time\n")
846 {
847 const char *xpath = "./set-action[action='frr-route-map:set-metric']";
848 char xpath_value[XPATH_MAXLEN];
849 char value[64];
850
851 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
852 if (rtt) {
853 snprintf(xpath_value, sizeof(xpath_value),
854 "%s/rmap-set-action/use-round-trip-time", xpath);
855 snprintf(value, sizeof(value), "true");
856 } else if (artt) {
857 snprintf(xpath_value, sizeof(xpath_value),
858 "%s/rmap-set-action/add-round-trip-time", xpath);
859 snprintf(value, sizeof(value), "true");
860 } else if (srtt) {
861 snprintf(xpath_value, sizeof(xpath_value),
862 "%s/rmap-set-action/subtract-round-trip-time", xpath);
863 snprintf(value, sizeof(value), "true");
864 } else if (metric_str && metric_str[0] == '+') {
865 snprintf(xpath_value, sizeof(xpath_value),
866 "%s/rmap-set-action/add-metric", xpath);
867 snprintf(value, sizeof(value), "%s", ++metric_str);
868 } else if (metric_str && metric_str[0] == '-') {
869 snprintf(xpath_value, sizeof(xpath_value),
870 "%s/rmap-set-action/subtract-metric", xpath);
871 snprintf(value, sizeof(value), "%s", ++metric_str);
872 } else {
873 snprintf(xpath_value, sizeof(xpath_value),
874 "%s/rmap-set-action/value", xpath);
875 snprintf(value, sizeof(value), "%s", metric_str);
876 }
877 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, value);
878
879 return nb_cli_apply_changes(vty, NULL);
880 }
881
882 DEFPY_YANG(
883 no_set_metric, no_set_metric_cmd,
884 "no set metric [OPTVAL]",
885 NO_STR
886 SET_STR
887 "Metric value for destination routing protocol\n"
888 "Metric value\n")
889 {
890 const char *xpath = "./set-action[action='frr-route-map:set-metric']";
891
892 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
893 return nb_cli_apply_changes(vty, NULL);
894 }
895
896 DEFPY_YANG(set_min_metric, set_min_metric_cmd,
897 "set min-metric <(0-4294967295)$metric>",
898 SET_STR
899 "Minimum metric value for destination routing protocol\n"
900 "Minimum metric value\n")
901 {
902 const char *xpath =
903 "./set-action[action='frr-route-map:set-min-metric']";
904 char xpath_value[XPATH_MAXLEN];
905 char value[64];
906
907 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
908
909 snprintf(xpath_value, sizeof(xpath_value),
910 "%s/rmap-set-action/min-metric", xpath);
911 snprintf(value, sizeof(value), "%s", metric_str);
912
913 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, value);
914
915 return nb_cli_apply_changes(vty, NULL);
916 }
917
918 DEFPY_YANG(no_set_min_metric, no_set_min_metric_cmd,
919 "no set min-metric [(0-4294967295)]",
920 NO_STR SET_STR
921 "Minimum metric value for destination routing protocol\n"
922 "Minumum metric value\n")
923 {
924 const char *xpath =
925 "./set-action[action='frr-route-map:set-min-metric']";
926
927 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
928 return nb_cli_apply_changes(vty, NULL);
929 }
930
931 DEFPY_YANG(set_max_metric, set_max_metric_cmd,
932 "set max-metric <(0-4294967295)$metric>",
933 SET_STR
934 "Maximum metric value for destination routing protocol\n"
935 "Miximum metric value\n")
936 {
937 const char *xpath =
938 "./set-action[action='frr-route-map:set-max-metric']";
939 char xpath_value[XPATH_MAXLEN];
940 char value[64];
941
942 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
943
944 snprintf(xpath_value, sizeof(xpath_value),
945 "%s/rmap-set-action/max-metric", xpath);
946 snprintf(value, sizeof(value), "%s", metric_str);
947
948 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, value);
949
950 return nb_cli_apply_changes(vty, NULL);
951 }
952
953 DEFPY_YANG(no_set_max_metric, no_set_max_metric_cmd,
954 "no set max-metric [(0-4294967295)]",
955 NO_STR SET_STR
956 "Maximum Metric value for destination routing protocol\n"
957 "Maximum metric value\n")
958 {
959 const char *xpath =
960 "./set-action[action='frr-route-map:set-max-metric']";
961
962 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
963 return nb_cli_apply_changes(vty, NULL);
964 }
965
966 DEFPY_YANG(
967 set_tag, set_tag_cmd,
968 "set tag (1-4294967295)$tag",
969 SET_STR
970 "Tag value for routing protocol\n"
971 "Tag value\n")
972 {
973 const char *xpath = "./set-action[action='frr-route-map:set-tag']";
974 char xpath_value[XPATH_MAXLEN];
975
976 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
977 snprintf(xpath_value, sizeof(xpath_value), "%s/rmap-set-action/tag",
978 xpath);
979 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, tag_str);
980
981 return nb_cli_apply_changes(vty, NULL);
982 }
983
984 DEFPY_YANG(
985 no_set_tag, no_set_tag_cmd,
986 "no set tag [(1-4294967295)]",
987 NO_STR
988 SET_STR
989 "Tag value for routing protocol\n"
990 "Tag value\n")
991 {
992 const char *xpath = "./set-action[action='frr-route-map:set-tag']";
993
994 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
995
996 return nb_cli_apply_changes(vty, NULL);
997 }
998
999 DEFUN_YANG (set_srte_color,
1000 set_srte_color_cmd,
1001 "set sr-te color (1-4294967295)",
1002 SET_STR
1003 SRTE_STR
1004 SRTE_COLOR_STR
1005 "Color of the SR-TE Policies to match with\n")
1006 {
1007 const char *xpath =
1008 "./set-action[action='frr-route-map:set-sr-te-color']";
1009 char xpath_value[XPATH_MAXLEN];
1010 int idx = 0;
1011
1012 char *arg = argv_find(argv, argc, "(1-4294967295)", &idx)
1013 ? argv[idx]->arg
1014 : NULL;
1015
1016 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
1017 snprintf(xpath_value, sizeof(xpath_value),
1018 "%s/rmap-set-action/policy", xpath);
1019 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, arg);
1020
1021 return nb_cli_apply_changes(vty, NULL);
1022 }
1023
1024 DEFUN_YANG (no_set_srte_color,
1025 no_set_srte_color_cmd,
1026 "no set sr-te color [(1-4294967295)]",
1027 NO_STR
1028 SET_STR
1029 SRTE_STR
1030 SRTE_COLOR_STR
1031 "Color of the SR-TE Policies to match with\n")
1032 {
1033 const char *xpath =
1034 "./set-action[action='frr-route-map:set-sr-te-color']";
1035
1036 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
1037
1038 return nb_cli_apply_changes(vty, NULL);
1039 }
1040
1041
1042 void route_map_action_show(struct vty *vty, const struct lyd_node *dnode,
1043 bool show_defaults)
1044 {
1045 const char *action = yang_dnode_get_string(dnode, "./action");
1046 const struct lyd_node *ln;
1047 const char *acl;
1048
1049 if (IS_SET_IPv4_NH(action)) {
1050 vty_out(vty, " set ip next-hop %s\n",
1051 yang_dnode_get_string(
1052 dnode, "./rmap-set-action/ipv4-address"));
1053 } else if (IS_SET_IPv6_NH(action)) {
1054 vty_out(vty, " set ipv6 next-hop local %s\n",
1055 yang_dnode_get_string(
1056 dnode, "./rmap-set-action/ipv6-address"));
1057 } else if (IS_SET_METRIC(action)) {
1058 if (yang_dnode_get(dnode,
1059 "./rmap-set-action/use-round-trip-time")) {
1060 vty_out(vty, " set metric rtt\n");
1061 } else if (yang_dnode_get(
1062 dnode,
1063 "./rmap-set-action/add-round-trip-time")) {
1064 vty_out(vty, " set metric +rtt\n");
1065 } else if (
1066 yang_dnode_get(
1067 dnode,
1068 "./rmap-set-action/subtract-round-trip-time")) {
1069 vty_out(vty, " set metric -rtt\n");
1070 } else if (yang_dnode_get(dnode,
1071 "./rmap-set-action/add-metric")) {
1072 vty_out(vty, " set metric +%s\n",
1073 yang_dnode_get_string(
1074 dnode, "./rmap-set-action/add-metric"));
1075 } else if (yang_dnode_get(
1076 dnode,
1077 "./rmap-set-action/subtract-metric")) {
1078 vty_out(vty, " set metric -%s\n",
1079 yang_dnode_get_string(
1080 dnode,
1081 "./rmap-set-action/subtract-metric"));
1082 } else {
1083 vty_out(vty, " set metric %s\n",
1084 yang_dnode_get_string(
1085 dnode, "./rmap-set-action/value"));
1086 }
1087 } else if (IS_SET_MIN_METRIC(action)) {
1088 vty_out(vty, " set min-metric %s\n",
1089 yang_dnode_get_string(dnode,
1090 "./rmap-set-action/min-metric"));
1091 } else if (IS_SET_MAX_METRIC(action)) {
1092 vty_out(vty, " set max-metric %s\n",
1093 yang_dnode_get_string(dnode,
1094 "./rmap-set-action/max-metric"));
1095 } else if (IS_SET_TAG(action)) {
1096 vty_out(vty, " set tag %s\n",
1097 yang_dnode_get_string(dnode, "./rmap-set-action/tag"));
1098 } else if (IS_SET_SR_TE_COLOR(action)) {
1099 vty_out(vty, " set sr-te color %s\n",
1100 yang_dnode_get_string(dnode,
1101 "./rmap-set-action/policy"));
1102 } else if (IS_SET_SRC(action)) {
1103 if (yang_dnode_exists(
1104 dnode,
1105 "./rmap-set-action/frr-zebra-route-map:ipv4-src-address"))
1106 vty_out(vty, " set src %s\n",
1107 yang_dnode_get_string(
1108 dnode,
1109 "./rmap-set-action/frr-zebra-route-map:ipv4-src-address"));
1110 else
1111 vty_out(vty, " set src %s\n",
1112 yang_dnode_get_string(
1113 dnode,
1114 "./rmap-set-action/frr-zebra-route-map:ipv6-src-address"));
1115 } else if (IS_SET_METRIC_TYPE(action)) {
1116 vty_out(vty, " set metric-type %s\n",
1117 yang_dnode_get_string(
1118 dnode,
1119 "./rmap-set-action/frr-ospf-route-map:metric-type"));
1120 } else if (IS_SET_FORWARDING_ADDR(action)) {
1121 vty_out(vty, " set forwarding-address %s\n",
1122 yang_dnode_get_string(
1123 dnode,
1124 "./rmap-set-action/frr-ospf6-route-map:ipv6-address"));
1125 } else if (IS_SET_WEIGHT(action)) {
1126 vty_out(vty, " set weight %s\n",
1127 yang_dnode_get_string(
1128 dnode,
1129 "./rmap-set-action/frr-bgp-route-map:weight"));
1130 } else if (IS_SET_TABLE(action)) {
1131 vty_out(vty, " set table %s\n",
1132 yang_dnode_get_string(
1133 dnode,
1134 "./rmap-set-action/frr-bgp-route-map:table"));
1135 } else if (IS_SET_LOCAL_PREF(action)) {
1136 vty_out(vty, " set local-preference %s\n",
1137 yang_dnode_get_string(
1138 dnode,
1139 "./rmap-set-action/frr-bgp-route-map:local-pref"));
1140 } else if (IS_SET_LABEL_INDEX(action)) {
1141 vty_out(vty, " set label-index %s\n",
1142 yang_dnode_get_string(
1143 dnode,
1144 "./rmap-set-action/frr-bgp-route-map:label-index"));
1145 } else if (IS_SET_DISTANCE(action)) {
1146 vty_out(vty, " set distance %s\n",
1147 yang_dnode_get_string(
1148 dnode,
1149 "./rmap-set-action/frr-bgp-route-map:distance"));
1150 } else if (IS_SET_ORIGIN(action)) {
1151 vty_out(vty, " set origin %s\n",
1152 yang_dnode_get_string(
1153 dnode,
1154 "./rmap-set-action/frr-bgp-route-map:origin"));
1155 } else if (IS_SET_ATOMIC_AGGREGATE(action)) {
1156 vty_out(vty, " set atomic-aggregate\n");
1157 } else if (IS_SET_AIGP_METRIC(action)) {
1158 vty_out(vty, " set aigp-metric %s\n",
1159 yang_dnode_get_string(
1160 dnode,
1161 "./rmap-set-action/frr-bgp-route-map:aigp-metric"));
1162 } else if (IS_SET_ORIGINATOR_ID(action)) {
1163 vty_out(vty, " set originator-id %s\n",
1164 yang_dnode_get_string(
1165 dnode,
1166 "./rmap-set-action/frr-bgp-route-map:originator-id"));
1167 } else if (IS_SET_COMM_LIST_DEL(action)) {
1168 acl = NULL;
1169 if ((ln = yang_dnode_get(
1170 dnode,
1171 "./rmap-set-action/frr-bgp-route-map:comm-list-name"))
1172 != NULL)
1173 acl = yang_dnode_get_string(ln, NULL);
1174
1175 assert(acl);
1176
1177 vty_out(vty, " set comm-list %s delete\n", acl);
1178 } else if (IS_SET_LCOMM_LIST_DEL(action)) {
1179 acl = NULL;
1180 if ((ln = yang_dnode_get(
1181 dnode,
1182 "./rmap-set-action/frr-bgp-route-map:comm-list-name"))
1183 != NULL)
1184 acl = yang_dnode_get_string(ln, NULL);
1185
1186 assert(acl);
1187
1188 vty_out(vty, " set large-comm-list %s delete\n", acl);
1189 } else if (IS_SET_LCOMMUNITY(action)) {
1190 if (yang_dnode_exists(
1191 dnode,
1192 "./rmap-set-action/frr-bgp-route-map:large-community-string"))
1193 vty_out(vty, " set large-community %s\n",
1194 yang_dnode_get_string(
1195 dnode,
1196 "./rmap-set-action/frr-bgp-route-map:large-community-string"));
1197 else {
1198 if (true
1199 == yang_dnode_get_bool(
1200 dnode,
1201 "./rmap-set-action/frr-bgp-route-map:large-community-none"))
1202 vty_out(vty, " set large-community none\n");
1203 }
1204 } else if (IS_SET_COMMUNITY(action)) {
1205 if (yang_dnode_exists(
1206 dnode,
1207 "./rmap-set-action/frr-bgp-route-map:community-string"))
1208 vty_out(vty, " set community %s\n",
1209 yang_dnode_get_string(
1210 dnode,
1211 "./rmap-set-action/frr-bgp-route-map:community-string"));
1212 else {
1213 if (true
1214 == yang_dnode_get_bool(
1215 dnode,
1216 "./rmap-set-action/frr-bgp-route-map:community-none"))
1217 vty_out(vty, " set community none\n");
1218 }
1219 } else if (IS_SET_EXTCOMMUNITY_RT(action)) {
1220 vty_out(vty, " set extcommunity rt %s\n",
1221 yang_dnode_get_string(
1222 dnode,
1223 "./rmap-set-action/frr-bgp-route-map:extcommunity-rt"));
1224 } else if (IS_SET_EXTCOMMUNITY_NT(action)) {
1225 vty_out(vty, " set extcommunity nt %s\n",
1226 yang_dnode_get_string(
1227 dnode,
1228 "./rmap-set-action/frr-bgp-route-map:extcommunity-nt"));
1229 } else if (IS_SET_EXTCOMMUNITY_SOO(action)) {
1230 vty_out(vty, " set extcommunity soo %s\n",
1231 yang_dnode_get_string(
1232 dnode,
1233 "./rmap-set-action/frr-bgp-route-map:extcommunity-soo"));
1234 } else if (IS_SET_EXTCOMMUNITY_LB(action)) {
1235 enum ecommunity_lb_type lb_type;
1236 char str[VTY_BUFSIZ];
1237 uint16_t bandwidth;
1238
1239 lb_type = yang_dnode_get_enum(
1240 dnode,
1241 "./rmap-set-action/frr-bgp-route-map:extcommunity-lb/lb-type");
1242 switch (lb_type) {
1243 case EXPLICIT_BANDWIDTH:
1244 bandwidth = yang_dnode_get_uint16(
1245 dnode,
1246 "./rmap-set-action/frr-bgp-route-map:extcommunity-lb/bandwidth");
1247 snprintf(str, sizeof(str), "%d", bandwidth);
1248 break;
1249 case CUMULATIVE_BANDWIDTH:
1250 snprintf(str, sizeof(str), "%s", "cumulative");
1251 break;
1252 case COMPUTED_BANDWIDTH:
1253 snprintf(str, sizeof(str), "%s", "num-multipaths");
1254 }
1255
1256 if (yang_dnode_get_bool(
1257 dnode,
1258 "./rmap-set-action/frr-bgp-route-map:extcommunity-lb/two-octet-as-specific"))
1259 strlcat(str, " non-transitive", sizeof(str));
1260
1261 vty_out(vty, " set extcommunity bandwidth %s\n", str);
1262 } else if (IS_SET_EXTCOMMUNITY_NONE(action)) {
1263 if (yang_dnode_get_bool(
1264 dnode,
1265 "./rmap-set-action/frr-bgp-route-map:extcommunity-none"))
1266 vty_out(vty, " set extcommunity none\n");
1267 } else if (IS_SET_AGGREGATOR(action)) {
1268 vty_out(vty, " set aggregator as %s %s\n",
1269 yang_dnode_get_string(
1270 dnode,
1271 "./rmap-set-action/frr-bgp-route-map:aggregator/aggregator-asn"),
1272 yang_dnode_get_string(
1273 dnode,
1274 "./rmap-set-action/frr-bgp-route-map:aggregator/aggregator-address"));
1275 } else if (IS_SET_AS_EXCLUDE(action)) {
1276 vty_out(vty, " set as-path exclude %s\n",
1277 yang_dnode_get_string(
1278 dnode,
1279 "./rmap-set-action/frr-bgp-route-map:exclude-as-path"));
1280 } else if (IS_SET_AS_REPLACE(action)) {
1281 vty_out(vty, " set as-path replace %s\n",
1282 yang_dnode_get_string(
1283 dnode,
1284 "./rmap-set-action/frr-bgp-route-map:replace-as-path"));
1285 } else if (IS_SET_AS_PREPEND(action)) {
1286 if (yang_dnode_exists(
1287 dnode,
1288 "./rmap-set-action/frr-bgp-route-map:prepend-as-path"))
1289 vty_out(vty, " set as-path prepend %s\n",
1290 yang_dnode_get_string(
1291 dnode,
1292 "./rmap-set-action/frr-bgp-route-map:prepend-as-path"));
1293 else {
1294 vty_out(vty, " set as-path prepend last-as %u\n",
1295 yang_dnode_get_uint8(
1296 dnode,
1297 "./rmap-set-action/frr-bgp-route-map:last-as"));
1298 }
1299 } else if (IS_SET_IPV6_NH_GLOBAL(action)) {
1300 vty_out(vty, " set ipv6 next-hop global %s\n",
1301 yang_dnode_get_string(
1302 dnode,
1303 "./rmap-set-action/frr-bgp-route-map:ipv6-address"));
1304 } else if (IS_SET_IPV6_VPN_NH(action)) {
1305 vty_out(vty, " set ipv6 vpn next-hop %s\n",
1306 yang_dnode_get_string(
1307 dnode,
1308 "./rmap-set-action/frr-bgp-route-map:ipv6-address"));
1309 } else if (IS_SET_IPV6_PEER_ADDR(action)) {
1310 if (true
1311 == yang_dnode_get_bool(
1312 dnode,
1313 "./rmap-set-action/frr-bgp-route-map:preference"))
1314 vty_out(vty, " set ipv6 next-hop peer-address\n");
1315 } else if (IS_SET_IPV6_PREFER_GLOBAL(action)) {
1316 if (true
1317 == yang_dnode_get_bool(
1318 dnode,
1319 "./rmap-set-action/frr-bgp-route-map:preference"))
1320 vty_out(vty, " set ipv6 next-hop prefer-global\n");
1321 } else if (IS_SET_IPV4_VPN_NH(action)) {
1322 vty_out(vty, " set ipv4 vpn next-hop %s\n",
1323 yang_dnode_get_string(
1324 dnode,
1325 "./rmap-set-action/frr-bgp-route-map:ipv4-address"));
1326 } else if (IS_SET_BGP_IPV4_NH(action)) {
1327 vty_out(vty, " set ip next-hop %s\n",
1328 yang_dnode_get_string(
1329 dnode,
1330 "./rmap-set-action/frr-bgp-route-map:ipv4-nexthop"));
1331 } else if (IS_SET_BGP_EVPN_GATEWAY_IP_IPV4(action)) {
1332 vty_out(vty, " set evpn gateway-ip ipv4 %s\n",
1333 yang_dnode_get_string(
1334 dnode,
1335 "./rmap-set-action/frr-bgp-route-map:evpn-gateway-ip-ipv4"));
1336 } else if (IS_SET_BGP_EVPN_GATEWAY_IP_IPV6(action)) {
1337 vty_out(vty, " set evpn gateway-ip ipv6 %s\n",
1338 yang_dnode_get_string(
1339 dnode,
1340 "./rmap-set-action/frr-bgp-route-map:evpn-gateway-ip-ipv6"));
1341 } else if (IS_SET_BGP_L3VPN_NEXTHOP_ENCAPSULATION(action)) {
1342 vty_out(vty, " set l3vpn next-hop encapsulation %s\n",
1343 yang_dnode_get_string(
1344 dnode,
1345 "./rmap-set-action/frr-bgp-route-map:l3vpn-nexthop-encapsulation"));
1346 }
1347 }
1348
1349 DEFPY_YANG(
1350 rmap_onmatch_next, rmap_onmatch_next_cmd,
1351 "on-match next",
1352 "Exit policy on matches\n"
1353 "Next clause\n")
1354 {
1355 nb_cli_enqueue_change(vty, "./exit-policy", NB_OP_MODIFY, "next");
1356
1357 return nb_cli_apply_changes(vty, NULL);
1358 }
1359
1360 DEFPY_YANG(
1361 no_rmap_onmatch_next,
1362 no_rmap_onmatch_next_cmd,
1363 "no on-match next",
1364 NO_STR
1365 "Exit policy on matches\n"
1366 "Next clause\n")
1367 {
1368 nb_cli_enqueue_change(vty, "./exit-policy", NB_OP_DESTROY, NULL);
1369
1370 return nb_cli_apply_changes(vty, NULL);
1371 }
1372
1373 DEFPY_YANG(
1374 rmap_onmatch_goto, rmap_onmatch_goto_cmd,
1375 "on-match goto (1-65535)$rm_num",
1376 "Exit policy on matches\n"
1377 "Goto Clause number\n"
1378 "Number\n")
1379 {
1380 nb_cli_enqueue_change(vty, "./exit-policy", NB_OP_MODIFY, "goto");
1381 nb_cli_enqueue_change(vty, "./goto-value", NB_OP_MODIFY, rm_num_str);
1382
1383 return nb_cli_apply_changes(vty, NULL);
1384 }
1385
1386 DEFPY_YANG(
1387 no_rmap_onmatch_goto, no_rmap_onmatch_goto_cmd,
1388 "no on-match goto",
1389 NO_STR
1390 "Exit policy on matches\n"
1391 "Goto Clause number\n")
1392 {
1393 nb_cli_enqueue_change(vty, "./exit-policy", NB_OP_DESTROY, NULL);
1394
1395 return nb_cli_apply_changes(vty, NULL);
1396 }
1397
1398 /* Cisco/GNU Zebra compatibility aliases */
1399 ALIAS_YANG(
1400 rmap_onmatch_goto, rmap_continue_cmd,
1401 "continue (1-65535)$rm_num",
1402 "Continue on a different entry within the route-map\n"
1403 "Route-map entry sequence number\n")
1404
1405 ALIAS_YANG(
1406 no_rmap_onmatch_goto, no_rmap_continue_cmd,
1407 "no continue [(1-65535)]",
1408 NO_STR
1409 "Continue on a different entry within the route-map\n"
1410 "Route-map entry sequence number\n")
1411
1412 void route_map_exit_policy_show(struct vty *vty, const struct lyd_node *dnode,
1413 bool show_defaults)
1414 {
1415 int exit_policy = yang_dnode_get_enum(dnode, NULL);
1416
1417 switch (exit_policy) {
1418 case 0: /* permit-or-deny */
1419 /* NOTHING: default option. */
1420 break;
1421 case 1: /* next */
1422 vty_out(vty, " on-match next\n");
1423 break;
1424 case 2: /* goto */
1425 vty_out(vty, " on-match goto %s\n",
1426 yang_dnode_get_string(dnode, "../goto-value"));
1427 break;
1428 }
1429 }
1430
1431 DEFPY_YANG(
1432 rmap_call, rmap_call_cmd,
1433 "call WORD$name",
1434 "Jump to another Route-Map after match+set\n"
1435 "Target route-map name\n")
1436 {
1437 nb_cli_enqueue_change(vty, "./call", NB_OP_MODIFY, name);
1438
1439 return nb_cli_apply_changes(vty, NULL);
1440 }
1441
1442 DEFPY_YANG(
1443 no_rmap_call, no_rmap_call_cmd,
1444 "no call [NAME]",
1445 NO_STR
1446 "Jump to another Route-Map after match+set\n"
1447 "Target route-map name\n")
1448 {
1449 nb_cli_enqueue_change(vty, "./call", NB_OP_DESTROY, NULL);
1450
1451 return nb_cli_apply_changes(vty, NULL);
1452 }
1453
1454 void route_map_call_show(struct vty *vty, const struct lyd_node *dnode,
1455 bool show_defaults)
1456 {
1457 vty_out(vty, " call %s\n", yang_dnode_get_string(dnode, NULL));
1458 }
1459
1460 DEFPY_YANG(
1461 rmap_description, rmap_description_cmd,
1462 "description LINE...",
1463 "Route-map comment\n"
1464 "Comment describing this route-map rule\n")
1465 {
1466 char *desc;
1467 int rv;
1468
1469 desc = argv_concat(argv, argc, 1);
1470 nb_cli_enqueue_change(vty, "./description", NB_OP_MODIFY, desc);
1471 rv = nb_cli_apply_changes(vty, NULL);
1472 XFREE(MTYPE_TMP, desc);
1473
1474 return rv;
1475 }
1476
1477 DEFUN_YANG (no_rmap_description,
1478 no_rmap_description_cmd,
1479 "no description",
1480 NO_STR
1481 "Route-map comment\n")
1482 {
1483 nb_cli_enqueue_change(vty, "./description", NB_OP_DESTROY, NULL);
1484
1485 return nb_cli_apply_changes(vty, NULL);
1486 }
1487
1488 void route_map_description_show(struct vty *vty, const struct lyd_node *dnode,
1489 bool show_defaults)
1490 {
1491 vty_out(vty, " description %s\n", yang_dnode_get_string(dnode, NULL));
1492 }
1493
1494 DEFPY_YANG(
1495 route_map_optimization, route_map_optimization_cmd,
1496 "[no] route-map RMAP_NAME$name optimization",
1497 NO_STR
1498 ROUTE_MAP_CMD_STR
1499 "Configure route-map optimization\n")
1500 {
1501 char xpath[XPATH_MAXLEN];
1502
1503 snprintf(xpath, sizeof(xpath),
1504 "/frr-route-map:lib/route-map[name='%s']", name);
1505 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
1506
1507 snprintf(
1508 xpath, sizeof(xpath),
1509 "/frr-route-map:lib/route-map[name='%s']/optimization-disabled",
1510 name);
1511 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, no ? "true" : "false");
1512
1513 return nb_cli_apply_changes(vty, NULL);
1514 }
1515
1516 void route_map_optimization_disabled_show(struct vty *vty,
1517 const struct lyd_node *dnode,
1518 bool show_defaults)
1519 {
1520 const char *name = yang_dnode_get_string(dnode, "../name");
1521 const bool disabled = yang_dnode_get_bool(dnode, NULL);
1522
1523 vty_out(vty, "%sroute-map %s optimization\n", disabled ? "no " : "",
1524 name);
1525 }
1526
1527 static int route_map_config_write(struct vty *vty)
1528 {
1529 const struct lyd_node *dnode;
1530 int written = 0;
1531
1532 dnode = yang_dnode_get(running_config->dnode,
1533 "/frr-route-map:lib");
1534 if (dnode) {
1535 nb_cli_show_dnode_cmds(vty, dnode, false);
1536 written = 1;
1537 }
1538
1539 return written;
1540 }
1541
1542 /* Route map node structure. */
1543 static int route_map_config_write(struct vty *vty);
1544 static struct cmd_node rmap_node = {
1545 .name = "routemap",
1546 .node = RMAP_NODE,
1547 .parent_node = CONFIG_NODE,
1548 .prompt = "%s(config-route-map)# ",
1549 .config_write = route_map_config_write,
1550 };
1551
1552 static void rmap_autocomplete(vector comps, struct cmd_token *token)
1553 {
1554 struct route_map *map;
1555
1556 for (map = route_map_master.head; map; map = map->next)
1557 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, map->name));
1558 }
1559
1560 static const struct cmd_variable_handler rmap_var_handlers[] = {
1561 {.varname = "route_map", .completions = rmap_autocomplete},
1562 {.tokenname = "ROUTEMAP_NAME", .completions = rmap_autocomplete},
1563 {.tokenname = "RMAP_NAME", .completions = rmap_autocomplete},
1564 {.completions = NULL}
1565 };
1566
1567 void route_map_cli_init(void)
1568 {
1569 /* Auto complete handler. */
1570 cmd_variable_handler_register(rmap_var_handlers);
1571
1572 /* CLI commands. */
1573 install_node(&rmap_node);
1574 install_default(RMAP_NODE);
1575 install_element(CONFIG_NODE, &route_map_cmd);
1576 install_element(CONFIG_NODE, &no_route_map_cmd);
1577 install_element(CONFIG_NODE, &no_route_map_all_cmd);
1578 install_element(CONFIG_NODE, &route_map_optimization_cmd);
1579
1580 /* Install the on-match stuff */
1581 install_element(RMAP_NODE, &rmap_onmatch_next_cmd);
1582 install_element(RMAP_NODE, &no_rmap_onmatch_next_cmd);
1583 install_element(RMAP_NODE, &rmap_onmatch_goto_cmd);
1584 install_element(RMAP_NODE, &no_rmap_onmatch_goto_cmd);
1585 install_element(RMAP_NODE, &rmap_continue_cmd);
1586 install_element(RMAP_NODE, &no_rmap_continue_cmd);
1587
1588 /* Install the call stuff. */
1589 install_element(RMAP_NODE, &rmap_call_cmd);
1590 install_element(RMAP_NODE, &no_rmap_call_cmd);
1591
1592 /* Install description commands. */
1593 install_element(RMAP_NODE, &rmap_description_cmd);
1594 install_element(RMAP_NODE, &no_rmap_description_cmd);
1595
1596 /* Install 'match' commands. */
1597 install_element(RMAP_NODE, &match_interface_cmd);
1598 install_element(RMAP_NODE, &no_match_interface_cmd);
1599
1600 install_element(RMAP_NODE, &match_ip_address_cmd);
1601 install_element(RMAP_NODE, &no_match_ip_address_cmd);
1602
1603 install_element(RMAP_NODE, &match_ip_address_prefix_list_cmd);
1604 install_element(RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
1605
1606 install_element(RMAP_NODE, &match_ip_next_hop_cmd);
1607 install_element(RMAP_NODE, &no_match_ip_next_hop_cmd);
1608
1609 install_element(RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
1610 install_element(RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
1611
1612 install_element(RMAP_NODE, &match_ip_next_hop_type_cmd);
1613 install_element(RMAP_NODE, &no_match_ip_next_hop_type_cmd);
1614
1615 install_element(RMAP_NODE, &match_ipv6_address_cmd);
1616 install_element(RMAP_NODE, &no_match_ipv6_address_cmd);
1617
1618 install_element(RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
1619 install_element(RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
1620
1621 install_element(RMAP_NODE, &match_ipv6_next_hop_type_cmd);
1622 install_element(RMAP_NODE, &no_match_ipv6_next_hop_type_cmd);
1623
1624 install_element(RMAP_NODE, &match_metric_cmd);
1625 install_element(RMAP_NODE, &no_match_metric_cmd);
1626
1627 install_element(RMAP_NODE, &match_tag_cmd);
1628 install_element(RMAP_NODE, &no_match_tag_cmd);
1629
1630 /* Install 'set' commands. */
1631 install_element(RMAP_NODE, &set_ip_nexthop_cmd);
1632 install_element(RMAP_NODE, &no_set_ip_nexthop_cmd);
1633
1634 install_element(RMAP_NODE, &set_ipv6_nexthop_local_cmd);
1635 install_element(RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
1636
1637 install_element(RMAP_NODE, &set_metric_cmd);
1638 install_element(RMAP_NODE, &no_set_metric_cmd);
1639
1640 install_element(RMAP_NODE, &set_min_metric_cmd);
1641 install_element(RMAP_NODE, &no_set_min_metric_cmd);
1642
1643 install_element(RMAP_NODE, &set_max_metric_cmd);
1644 install_element(RMAP_NODE, &no_set_max_metric_cmd);
1645
1646 install_element(RMAP_NODE, &set_tag_cmd);
1647 install_element(RMAP_NODE, &no_set_tag_cmd);
1648
1649 install_element(RMAP_NODE, &set_srte_color_cmd);
1650 install_element(RMAP_NODE, &no_set_srte_color_cmd);
1651 }