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