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