]> git.proxmox.com Git - mirror_frr.git/blame - staticd/static_vty.c
Merge pull request #8716 from idryzhov/fix-commands
[mirror_frr.git] / staticd / static_vty.c
CommitLineData
7e24fdf3
DS
1/*
2 * STATICd - vty code
3 * Copyright (C) 2018 Cumulus Networks, Inc.
4 * Donald Sharp
5 *
8d5cbee9
DS
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
7e24fdf3 10 *
8d5cbee9
DS
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
7e24fdf3
DS
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20#include <zebra.h>
21
22#include "command.h"
23#include "vty.h"
24#include "vrf.h"
25#include "prefix.h"
26#include "nexthop.h"
27#include "table.h"
28#include "srcdest_table.h"
29#include "mpls.h"
88fa5104 30#include "northbound.h"
31#include "libfrr.h"
32#include "routing_nb.h"
33#include "northbound_cli.h"
7e24fdf3
DS
34
35#include "static_vrf.h"
7e24fdf3
DS
36#include "static_vty.h"
37#include "static_routes.h"
31ddf3b7 38#include "static_debug.h"
7e24fdf3
DS
39#ifndef VTYSH_EXTRACT_PL
40#include "staticd/static_vty_clippy.c"
41#endif
88fa5104 42#include "static_nb.h"
31ddf3b7
MS
43
44#define STATICD_STR "Static route daemon\n"
45
88fa5104 46static int static_route_leak(struct vty *vty, const char *svrf,
47 const char *nh_svrf, afi_t afi, safi_t safi,
48 const char *negate, const char *dest_str,
49 const char *mask_str, const char *src_str,
50 const char *gate_str, const char *ifname,
51 const char *flag_str, const char *tag_str,
52 const char *distance_str, const char *label_str,
065276ae
SM
53 const char *table_str, bool onlink,
54 const char *color_str)
7e24fdf3 55{
7e24fdf3 56 int ret;
7e24fdf3 57 struct prefix p, src;
7e24fdf3 58 struct in_addr mask;
7e24fdf3 59 uint8_t type;
88fa5104 60 const char *bh_type;
61 char xpath_prefix[XPATH_MAXLEN];
62 char xpath_nexthop[XPATH_MAXLEN];
63 char xpath_mpls[XPATH_MAXLEN];
64 char xpath_label[XPATH_MAXLEN];
65 char ab_xpath[XPATH_MAXLEN];
66 char buf_prefix[PREFIX_STRLEN];
67 char buf_src_prefix[PREFIX_STRLEN];
68 char buf_nh_type[PREFIX_STRLEN];
69 char buf_tag[PREFIX_STRLEN];
88fa5104 70 uint8_t label_stack_id = 0;
71 const char *buf_gate_str;
72 uint8_t distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
73 route_tag_t tag = 0;
7e24fdf3 74 uint32_t table_id = 0;
88fa5104 75 const struct lyd_node *dnode;
76
77 memset(buf_src_prefix, 0, PREFIX_STRLEN);
78 memset(buf_nh_type, 0, PREFIX_STRLEN);
7e24fdf3
DS
79
80 ret = str2prefix(dest_str, &p);
81 if (ret <= 0) {
406537cb 82 vty_out(vty, "%% Malformed address\n");
7e24fdf3
DS
83 return CMD_WARNING_CONFIG_FAILED;
84 }
85
86 switch (afi) {
87 case AFI_IP:
88 /* Cisco like mask notation. */
89 if (mask_str) {
90 ret = inet_aton(mask_str, &mask);
91 if (ret == 0) {
406537cb 92 vty_out(vty, "%% Malformed address\n");
7e24fdf3
DS
93 return CMD_WARNING_CONFIG_FAILED;
94 }
95 p.prefixlen = ip_masklen(mask);
96 }
97 break;
98 case AFI_IP6:
99 /* srcdest routing */
100 if (src_str) {
101 ret = str2prefix(src_str, &src);
102 if (ret <= 0 || src.family != AF_INET6) {
406537cb 103 vty_out(vty, "%% Malformed source address\n");
7e24fdf3
DS
104 return CMD_WARNING_CONFIG_FAILED;
105 }
7e24fdf3
DS
106 }
107 break;
108 default:
109 break;
110 }
111
112 /* Apply mask for given prefix. */
113 apply_mask(&p);
114
88fa5104 115 prefix2str(&p, buf_prefix, sizeof(buf_prefix));
7e24fdf3 116
88fa5104 117 if (src_str)
118 prefix2str(&src, buf_src_prefix, sizeof(buf_src_prefix));
119 if (gate_str)
120 buf_gate_str = gate_str;
121 else
122 buf_gate_str = "";
123
124 if (gate_str == NULL && ifname == NULL)
125 type = STATIC_BLACKHOLE;
126 else if (gate_str && ifname) {
127 if (afi == AFI_IP)
128 type = STATIC_IPV4_GATEWAY_IFNAME;
129 else
130 type = STATIC_IPV6_GATEWAY_IFNAME;
131 } else if (ifname)
132 type = STATIC_IFNAME;
133 else {
134 if (afi == AFI_IP)
135 type = STATIC_IPV4_GATEWAY;
136 else
137 type = STATIC_IPV6_GATEWAY;
7e24fdf3
DS
138 }
139
140 /* Administrative distance. */
141 if (distance_str)
142 distance = atoi(distance_str);
143 else
144 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
145
146 /* tag */
147 if (tag_str)
148 tag = strtoul(tag_str, NULL, 10);
149
7e24fdf3
DS
150 /* TableID */
151 if (table_str)
152 table_id = atol(table_str);
153
88fa5104 154 static_get_nh_type(type, buf_nh_type, PREFIX_STRLEN);
155 if (!negate) {
156 /* route + path procesing */
157 if (src_str)
158 snprintf(xpath_prefix, sizeof(xpath_prefix),
159 FRR_S_ROUTE_SRC_INFO_KEY_XPATH,
160 "frr-staticd:staticd", "staticd", svrf,
161 buf_prefix,
314825ff 162 yang_afi_safi_value2identity(afi, safi),
ef4b6b22 163 buf_src_prefix, table_id, distance);
88fa5104 164 else
165 snprintf(xpath_prefix, sizeof(xpath_prefix),
166 FRR_STATIC_ROUTE_INFO_KEY_XPATH,
167 "frr-staticd:staticd", "staticd", svrf,
168 buf_prefix,
314825ff 169 yang_afi_safi_value2identity(afi, safi),
ef4b6b22 170 table_id, distance);
88fa5104 171
172 nb_cli_enqueue_change(vty, xpath_prefix, NB_OP_CREATE, NULL);
173
174 /* Tag processing */
175 snprintf(buf_tag, sizeof(buf_tag), "%u", tag);
176 strlcpy(ab_xpath, xpath_prefix, sizeof(ab_xpath));
177 strlcat(ab_xpath, FRR_STATIC_ROUTE_PATH_TAG_XPATH,
178 sizeof(ab_xpath));
179 nb_cli_enqueue_change(vty, ab_xpath, NB_OP_MODIFY, buf_tag);
180
88fa5104 181 /* nexthop processing */
182
183 snprintf(ab_xpath, sizeof(ab_xpath),
184 FRR_STATIC_ROUTE_NH_KEY_XPATH, buf_nh_type, nh_svrf,
185 buf_gate_str, ifname);
186 strlcpy(xpath_nexthop, xpath_prefix, sizeof(xpath_nexthop));
187 strlcat(xpath_nexthop, ab_xpath, sizeof(xpath_nexthop));
188 nb_cli_enqueue_change(vty, xpath_nexthop, NB_OP_CREATE, NULL);
189
190 if (type == STATIC_BLACKHOLE) {
191 strlcpy(ab_xpath, xpath_nexthop, sizeof(ab_xpath));
192 strlcat(ab_xpath, FRR_STATIC_ROUTE_NH_BH_XPATH,
193 sizeof(ab_xpath));
194
195 /* Route flags */
196 if (flag_str) {
197 switch (flag_str[0]) {
198 case 'r':
199 bh_type = "reject";
200 break;
201 case 'b':
202 bh_type = "unspec";
203 break;
204 case 'N':
205 bh_type = "null";
206 break;
207 default:
208 bh_type = NULL;
209 break;
210 }
211 nb_cli_enqueue_change(vty, ab_xpath,
212 NB_OP_MODIFY, bh_type);
213 } else {
214 nb_cli_enqueue_change(vty, ab_xpath,
215 NB_OP_MODIFY, "null");
216 }
7e24fdf3 217 }
88fa5104 218 if (type == STATIC_IPV4_GATEWAY_IFNAME
219 || type == STATIC_IPV6_GATEWAY_IFNAME) {
220 strlcpy(ab_xpath, xpath_nexthop, sizeof(ab_xpath));
221 strlcat(ab_xpath, FRR_STATIC_ROUTE_NH_ONLINK_XPATH,
222 sizeof(ab_xpath));
223
224 if (onlink)
225 nb_cli_enqueue_change(vty, ab_xpath,
226 NB_OP_MODIFY, "true");
7e24fdf3 227 else
88fa5104 228 nb_cli_enqueue_change(vty, ab_xpath,
229 NB_OP_MODIFY, "false");
7e24fdf3 230 }
065276ae
SM
231 if (type == STATIC_IPV4_GATEWAY
232 || type == STATIC_IPV6_GATEWAY
233 || type == STATIC_IPV4_GATEWAY_IFNAME
234 || type == STATIC_IPV6_GATEWAY_IFNAME) {
235 strlcpy(ab_xpath, xpath_nexthop, sizeof(ab_xpath));
236 strlcat(ab_xpath, FRR_STATIC_ROUTE_NH_COLOR_XPATH,
237 sizeof(ab_xpath));
77463bc8
RW
238 if (color_str)
239 nb_cli_enqueue_change(vty, ab_xpath,
240 NB_OP_MODIFY, color_str);
065276ae 241 }
88fa5104 242 if (label_str) {
243 /* copy of label string (start) */
244 char *ostr;
245 /* pointer to next segment */
246 char *nump;
247
248 strlcpy(xpath_mpls, xpath_nexthop, sizeof(xpath_mpls));
249 strlcat(xpath_mpls, FRR_STATIC_ROUTE_NH_LABEL_XPATH,
250 sizeof(xpath_mpls));
251
252 nb_cli_enqueue_change(vty, xpath_mpls, NB_OP_DESTROY,
253 NULL);
254
255 ostr = XSTRDUP(MTYPE_TMP, label_str);
256 while ((nump = strsep(&ostr, "/")) != NULL) {
257 snprintf(ab_xpath, sizeof(ab_xpath),
258 FRR_STATIC_ROUTE_NHLB_KEY_XPATH,
259 label_stack_id);
260 strlcpy(xpath_label, xpath_mpls,
261 sizeof(xpath_label));
262 strlcat(xpath_label, ab_xpath,
263 sizeof(xpath_label));
264 nb_cli_enqueue_change(vty, xpath_label,
265 NB_OP_MODIFY, nump);
266 label_stack_id++;
267 }
268 XFREE(MTYPE_TMP, ostr);
269 } else {
270 strlcpy(xpath_mpls, xpath_nexthop, sizeof(xpath_mpls));
271 strlcat(xpath_mpls, FRR_STATIC_ROUTE_NH_LABEL_XPATH,
272 sizeof(xpath_mpls));
273 nb_cli_enqueue_change(vty, xpath_mpls, NB_OP_DESTROY,
274 NULL);
b1ab2876 275 }
88fa5104 276 ret = nb_cli_apply_changes(vty, xpath_prefix);
7e24fdf3 277 } else {
88fa5104 278 if (src_str)
279 snprintf(ab_xpath, sizeof(ab_xpath),
280 FRR_DEL_S_ROUTE_SRC_NH_KEY_XPATH,
281 "frr-staticd:staticd", "staticd", svrf,
282 buf_prefix,
314825ff 283 yang_afi_safi_value2identity(afi, safi),
ef4b6b22 284 buf_src_prefix, table_id, distance,
285 buf_nh_type, nh_svrf, buf_gate_str, ifname);
88fa5104 286 else
287 snprintf(ab_xpath, sizeof(ab_xpath),
288 FRR_DEL_S_ROUTE_NH_KEY_XPATH,
289 "frr-staticd:staticd", "staticd", svrf,
290 buf_prefix,
314825ff 291 yang_afi_safi_value2identity(afi, safi),
ef4b6b22 292 table_id, distance, buf_nh_type, nh_svrf,
293 buf_gate_str, ifname);
88fa5104 294
295 dnode = yang_dnode_get(vty->candidate_config->dnode, ab_xpath);
ff0e8ee8
WC
296 if (!dnode) {
297 vty_out(vty,
298 "%% Refusing to remove a non-existent route\n");
88fa5104 299 return ret;
ff0e8ee8 300 }
88fa5104 301
302 dnode = yang_get_subtree_with_no_sibling(dnode);
303 assert(dnode);
304 yang_dnode_get_path(dnode, ab_xpath, XPATH_MAXLEN);
305
306 nb_cli_enqueue_change(vty, ab_xpath, NB_OP_DESTROY, NULL);
307 ret = nb_cli_apply_changes(vty, ab_xpath);
7e24fdf3
DS
308 }
309
88fa5104 310 return ret;
7e24fdf3 311}
7e24fdf3
DS
312static int static_route(struct vty *vty, afi_t afi, safi_t safi,
313 const char *negate, const char *dest_str,
314 const char *mask_str, const char *src_str,
315 const char *gate_str, const char *ifname,
316 const char *flag_str, const char *tag_str,
317 const char *distance_str, const char *vrf_name,
318 const char *label_str, const char *table_str)
319{
88fa5104 320 if (!vrf_name)
321 vrf_name = VRF_DEFAULT_NAME;
7e24fdf3 322
88fa5104 323 return static_route_leak(vty, vrf_name, vrf_name, afi, safi, negate,
324 dest_str, mask_str, src_str, gate_str, ifname,
325 flag_str, tag_str, distance_str, label_str,
065276ae 326 table_str, false, NULL);
7e24fdf3
DS
327}
328
329/* Write static route configuration. */
330int static_config(struct vty *vty, struct static_vrf *svrf, afi_t afi,
331 safi_t safi, const char *cmd)
332{
7e24fdf3
DS
333 char spacing[100];
334 struct route_node *rn;
88fa5104 335 struct static_nexthop *nh;
336 struct static_path *pn;
7e24fdf3 337 struct route_table *stable;
88fa5104 338 struct static_route_info *si;
7e24fdf3
DS
339 char buf[SRCDEST2STR_BUFFER];
340 int write = 0;
88fa5104 341 struct stable_info *info;
7e24fdf3
DS
342
343 stable = svrf->stable[afi][safi];
344 if (stable == NULL)
345 return write;
346
772270f3
QY
347 snprintf(spacing, sizeof(spacing), "%s%s",
348 (svrf->vrf->vrf_id == VRF_DEFAULT) ? "" : " ", cmd);
7e24fdf3 349
88fa5104 350 for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) {
351 si = static_route_info_from_rnode(rn);
352 if (!si)
7e24fdf3 353 continue;
88fa5104 354 info = static_get_stable_info(rn);
355 frr_each(static_path_list, &si->path_list, pn) {
356 frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
357 vty_out(vty, "%s %s", spacing,
358 srcdest_rnode2str(rn, buf,
359 sizeof(buf)));
360
361 switch (nh->type) {
362 case STATIC_IPV4_GATEWAY:
4a3873a3 363 vty_out(vty, " %pI4", &nh->addr.ipv4);
7e24fdf3 364 break;
88fa5104 365 case STATIC_IPV6_GATEWAY:
366 vty_out(vty, " %s",
367 inet_ntop(AF_INET6,
368 &nh->addr.ipv6, buf,
369 sizeof(buf)));
7e24fdf3 370 break;
88fa5104 371 case STATIC_IFNAME:
372 vty_out(vty, " %s", nh->ifname);
373 break;
374 case STATIC_BLACKHOLE:
375 switch (nh->bh_type) {
376 case STATIC_BLACKHOLE_DROP:
377 vty_out(vty, " blackhole");
378 break;
379 case STATIC_BLACKHOLE_NULL:
380 vty_out(vty, " Null0");
381 break;
382 case STATIC_BLACKHOLE_REJECT:
383 vty_out(vty, " reject");
384 break;
385 }
386 break;
387 case STATIC_IPV4_GATEWAY_IFNAME:
388 vty_out(vty, " %s %s",
389 inet_ntop(AF_INET,
390 &nh->addr.ipv4, buf,
391 sizeof(buf)),
392 nh->ifname);
393 break;
394 case STATIC_IPV6_GATEWAY_IFNAME:
395 vty_out(vty, " %s %s",
396 inet_ntop(AF_INET6,
397 &nh->addr.ipv6, buf,
398 sizeof(buf)),
399 nh->ifname);
7e24fdf3
DS
400 break;
401 }
7e24fdf3 402
88fa5104 403 if (pn->tag)
404 vty_out(vty, " tag %" ROUTE_TAG_PRI,
405 pn->tag);
406
407 if (pn->distance
408 != ZEBRA_STATIC_DISTANCE_DEFAULT)
409 vty_out(vty, " %u", pn->distance);
410
411 /* Label information */
412 if (nh->snh_label.num_labels)
413 vty_out(vty, " label %s",
414 mpls_label2str(
415 nh->snh_label
416 .num_labels,
417 nh->snh_label.label,
418 buf, sizeof(buf), 0));
419
0d0aacea
RW
420 if (!strmatch(nh->nh_vrfname,
421 info->svrf->vrf->name))
88fa5104 422 vty_out(vty, " nexthop-vrf %s",
423 nh->nh_vrfname);
424
425 /*
426 * table ID from VRF overrides
427 * configured
428 */
429 if (pn->table_id
430 && svrf->vrf->data.l.table_id
431 == RT_TABLE_MAIN)
432 vty_out(vty, " table %u", pn->table_id);
433
434 if (nh->onlink)
435 vty_out(vty, " onlink");
436
065276ae
SM
437 /*
438 * SR-TE color
439 */
440 if (nh->color != 0)
441 vty_out(vty, " color %u", nh->color);
442
88fa5104 443 vty_out(vty, "\n");
444
445 write = 1;
446 }
7e24fdf3 447 }
88fa5104 448 }
7e24fdf3
DS
449 return write;
450}
451
452/* Static unicast routes for multicast RPF lookup. */
ca77b518 453DEFPY_YANG (ip_mroute_dist,
7e24fdf3
DS
454 ip_mroute_dist_cmd,
455 "[no] ip mroute A.B.C.D/M$prefix <A.B.C.D$gate|INTERFACE$ifname> [(1-255)$distance]",
456 NO_STR
457 IP_STR
458 "Configure static unicast route into MRIB for multicast RPF lookup\n"
459 "IP destination prefix (e.g. 10.0.0.0/8)\n"
460 "Nexthop address\n"
461 "Nexthop interface name\n"
462 "Distance\n")
463{
464 return static_route(vty, AFI_IP, SAFI_MULTICAST, no, prefix_str,
465 NULL, NULL, gate_str, ifname, NULL, NULL,
466 distance_str, NULL, NULL, NULL);
467}
468
469/* Static route configuration. */
ca77b518 470DEFPY_YANG(ip_route_blackhole,
7e24fdf3
DS
471 ip_route_blackhole_cmd,
472 "[no] ip route\
473 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
474 <reject|blackhole>$flag \
475 [{ \
476 tag (1-4294967295) \
477 |(1-255)$distance \
478 |vrf NAME \
479 |label WORD \
480 |table (1-4294967295) \
481 }]",
482 NO_STR IP_STR
483 "Establish static routes\n"
484 "IP destination prefix (e.g. 10.0.0.0/8)\n"
485 "IP destination prefix\n"
486 "IP destination prefix mask\n"
487 "Emit an ICMP unreachable when matched\n"
488 "Silently discard pkts when matched\n"
489 "Set tag for this route\n"
490 "Tag value\n"
491 "Distance value for this route\n"
492 VRF_CMD_HELP_STR
493 MPLS_LABEL_HELPSTR
494 "Table to configure\n"
495 "The table number to configure\n")
496{
7e24fdf3
DS
497 return static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix,
498 mask_str, NULL, NULL, NULL, flag, tag_str,
499 distance_str, vrf, label, table_str);
500}
501
ca77b518 502DEFPY_YANG(ip_route_blackhole_vrf,
7e24fdf3
DS
503 ip_route_blackhole_vrf_cmd,
504 "[no] ip route\
505 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
506 <reject|blackhole>$flag \
507 [{ \
508 tag (1-4294967295) \
509 |(1-255)$distance \
510 |label WORD \
511 |table (1-4294967295) \
512 }]",
513 NO_STR IP_STR
514 "Establish static routes\n"
515 "IP destination prefix (e.g. 10.0.0.0/8)\n"
516 "IP destination prefix\n"
517 "IP destination prefix mask\n"
518 "Emit an ICMP unreachable when matched\n"
519 "Silently discard pkts when matched\n"
520 "Set tag for this route\n"
521 "Tag value\n"
522 "Distance value for this route\n"
523 MPLS_LABEL_HELPSTR
524 "Table to configure\n"
525 "The table number to configure\n")
526{
88fa5104 527 const struct lyd_node *vrf_dnode;
528 const char *vrfname;
7e24fdf3 529
88fa5104 530 vrf_dnode =
531 yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
532 if (!vrf_dnode) {
533 vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
7e24fdf3
DS
534 return CMD_WARNING_CONFIG_FAILED;
535 }
88fa5104 536 vrfname = yang_dnode_get_string(vrf_dnode, "./name");
7e24fdf3
DS
537 /*
538 * Coverity is complaining that prefix could
539 * be dereferenced, but we know that prefix will
540 * valid. Add an assert to make it happy
541 */
542 assert(prefix);
88fa5104 543 return static_route_leak(vty, vrfname, vrfname, AFI_IP, SAFI_UNICAST,
544 no, prefix, mask_str, NULL, NULL, NULL, flag,
02dc8ba3 545 tag_str, distance_str, label, table_str,
065276ae 546 false, NULL);
7e24fdf3
DS
547}
548
ca77b518 549DEFPY_YANG(ip_route_address_interface,
7e24fdf3
DS
550 ip_route_address_interface_cmd,
551 "[no] ip route\
552 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
553 A.B.C.D$gate \
54a3d7cb 554 <INTERFACE|Null0>$ifname \
7e24fdf3
DS
555 [{ \
556 tag (1-4294967295) \
557 |(1-255)$distance \
558 |vrf NAME \
559 |label WORD \
560 |table (1-4294967295) \
561 |nexthop-vrf NAME \
02dc8ba3 562 |onlink$onlink \
065276ae 563 |color (1-4294967295) \
7e24fdf3
DS
564 }]",
565 NO_STR IP_STR
566 "Establish static routes\n"
567 "IP destination prefix (e.g. 10.0.0.0/8)\n"
568 "IP destination prefix\n"
569 "IP destination prefix mask\n"
570 "IP gateway address\n"
54a3d7cb
QY
571 "IP gateway interface name\n"
572 "Null interface\n"
7e24fdf3
DS
573 "Set tag for this route\n"
574 "Tag value\n"
575 "Distance value for this route\n"
576 VRF_CMD_HELP_STR
577 MPLS_LABEL_HELPSTR
578 "Table to configure\n"
579 "The table number to configure\n"
02dc8ba3 580 VRF_CMD_HELP_STR
065276ae
SM
581 "Treat the nexthop as directly attached to the interface\n"
582 "SR-TE color\n"
583 "The SR-TE color to configure\n")
7e24fdf3 584{
88fa5104 585 const char *nh_vrf;
7e24fdf3
DS
586 const char *flag = NULL;
587
588 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
589 flag = "Null0";
590 ifname = NULL;
591 }
88fa5104 592 if (!vrf)
593 vrf = VRF_DEFAULT_NAME;
7e24fdf3
DS
594
595 if (nexthop_vrf)
88fa5104 596 nh_vrf = nexthop_vrf;
7e24fdf3 597 else
88fa5104 598 nh_vrf = vrf;
7e24fdf3 599
88fa5104 600 return static_route_leak(vty, vrf, nh_vrf, AFI_IP, SAFI_UNICAST, no,
02dc8ba3
QY
601 prefix, mask_str, NULL, gate_str, ifname, flag,
602 tag_str, distance_str, label, table_str,
065276ae 603 !!onlink, color_str);
7e24fdf3
DS
604}
605
ca77b518 606DEFPY_YANG(ip_route_address_interface_vrf,
7e24fdf3
DS
607 ip_route_address_interface_vrf_cmd,
608 "[no] ip route\
609 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
610 A.B.C.D$gate \
54a3d7cb 611 <INTERFACE|Null0>$ifname \
7e24fdf3
DS
612 [{ \
613 tag (1-4294967295) \
614 |(1-255)$distance \
615 |label WORD \
616 |table (1-4294967295) \
617 |nexthop-vrf NAME \
02dc8ba3 618 |onlink$onlink \
065276ae
SM
619 |color (1-4294967295) \
620 }]",
7e24fdf3
DS
621 NO_STR IP_STR
622 "Establish static routes\n"
623 "IP destination prefix (e.g. 10.0.0.0/8)\n"
624 "IP destination prefix\n"
625 "IP destination prefix mask\n"
626 "IP gateway address\n"
54a3d7cb
QY
627 "IP gateway interface name\n"
628 "Null interface\n"
7e24fdf3
DS
629 "Set tag for this route\n"
630 "Tag value\n"
631 "Distance value for this route\n"
632 MPLS_LABEL_HELPSTR
633 "Table to configure\n"
634 "The table number to configure\n"
02dc8ba3 635 VRF_CMD_HELP_STR
065276ae
SM
636 "Treat the nexthop as directly attached to the interface\n"
637 "SR-TE color\n"
638 "The SR-TE color to configure\n")
7e24fdf3 639{
88fa5104 640 const char *nh_vrf;
7e24fdf3 641 const char *flag = NULL;
88fa5104 642 const struct lyd_node *vrf_dnode;
643 const char *vrfname;
7e24fdf3 644
88fa5104 645 vrf_dnode =
646 yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
647 if (!vrf_dnode) {
648 vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
7e24fdf3
DS
649 return CMD_WARNING_CONFIG_FAILED;
650 }
88fa5104 651 vrfname = yang_dnode_get_string(vrf_dnode, "./name");
7e24fdf3
DS
652
653 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
654 flag = "Null0";
655 ifname = NULL;
656 }
7e24fdf3 657 if (nexthop_vrf)
88fa5104 658 nh_vrf = nexthop_vrf;
7e24fdf3 659 else
88fa5104 660 nh_vrf = vrfname;
7e24fdf3 661
88fa5104 662 return static_route_leak(vty, vrfname, nh_vrf, AFI_IP, SAFI_UNICAST, no,
02dc8ba3
QY
663 prefix, mask_str, NULL, gate_str, ifname, flag,
664 tag_str, distance_str, label, table_str,
065276ae 665 !!onlink, color_str);
7e24fdf3
DS
666}
667
ca77b518 668DEFPY_YANG(ip_route,
7e24fdf3
DS
669 ip_route_cmd,
670 "[no] ip route\
671 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
54a3d7cb 672 <A.B.C.D$gate|<INTERFACE|Null0>$ifname> \
7e24fdf3
DS
673 [{ \
674 tag (1-4294967295) \
675 |(1-255)$distance \
676 |vrf NAME \
677 |label WORD \
678 |table (1-4294967295) \
679 |nexthop-vrf NAME \
065276ae 680 |color (1-4294967295) \
7e24fdf3
DS
681 }]",
682 NO_STR IP_STR
683 "Establish static routes\n"
684 "IP destination prefix (e.g. 10.0.0.0/8)\n"
685 "IP destination prefix\n"
686 "IP destination prefix mask\n"
687 "IP gateway address\n"
688 "IP gateway interface name\n"
54a3d7cb 689 "Null interface\n"
7e24fdf3
DS
690 "Set tag for this route\n"
691 "Tag value\n"
692 "Distance value for this route\n"
693 VRF_CMD_HELP_STR
694 MPLS_LABEL_HELPSTR
695 "Table to configure\n"
696 "The table number to configure\n"
065276ae
SM
697 VRF_CMD_HELP_STR
698 "SR-TE color\n"
699 "The SR-TE color to configure\n")
7e24fdf3 700{
88fa5104 701 const char *nh_vrf;
7e24fdf3
DS
702 const char *flag = NULL;
703
7e24fdf3
DS
704 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
705 flag = "Null0";
706 ifname = NULL;
707 }
708
88fa5104 709 if (!vrf)
710 vrf = VRF_DEFAULT_NAME;
7e24fdf3
DS
711
712 if (nexthop_vrf)
88fa5104 713 nh_vrf = nexthop_vrf;
7e24fdf3 714 else
88fa5104 715 nh_vrf = vrf;
7e24fdf3 716
88fa5104 717 return static_route_leak(vty, vrf, nh_vrf, AFI_IP, SAFI_UNICAST, no,
718 prefix, mask_str, NULL, gate_str, ifname, flag,
719 tag_str, distance_str, label, table_str,
065276ae 720 false, color_str);
7e24fdf3
DS
721}
722
ca77b518 723DEFPY_YANG(ip_route_vrf,
7e24fdf3
DS
724 ip_route_vrf_cmd,
725 "[no] ip route\
726 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
54a3d7cb 727 <A.B.C.D$gate|<INTERFACE|Null0>$ifname> \
7e24fdf3
DS
728 [{ \
729 tag (1-4294967295) \
730 |(1-255)$distance \
731 |label WORD \
732 |table (1-4294967295) \
733 |nexthop-vrf NAME \
065276ae 734 |color (1-4294967295) \
7e24fdf3
DS
735 }]",
736 NO_STR IP_STR
737 "Establish static routes\n"
738 "IP destination prefix (e.g. 10.0.0.0/8)\n"
739 "IP destination prefix\n"
740 "IP destination prefix mask\n"
741 "IP gateway address\n"
742 "IP gateway interface name\n"
54a3d7cb 743 "Null interface\n"
7e24fdf3
DS
744 "Set tag for this route\n"
745 "Tag value\n"
746 "Distance value for this route\n"
747 MPLS_LABEL_HELPSTR
748 "Table to configure\n"
749 "The table number to configure\n"
065276ae
SM
750 VRF_CMD_HELP_STR
751 "SR-TE color\n"
752 "The SR-TE color to configure\n")
7e24fdf3 753{
88fa5104 754 const char *nh_vrf;
51c4ed0a 755 const char *flag = NULL;
88fa5104 756 const struct lyd_node *vrf_dnode;
757 const char *vrfname;
7e24fdf3 758
88fa5104 759 vrf_dnode =
760 yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
761 if (!vrf_dnode) {
762 vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
7e24fdf3
DS
763 return CMD_WARNING_CONFIG_FAILED;
764 }
765
88fa5104 766 vrfname = yang_dnode_get_string(vrf_dnode, "./name");
767
7e24fdf3
DS
768 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
769 flag = "Null0";
770 ifname = NULL;
771 }
7e24fdf3 772 if (nexthop_vrf)
88fa5104 773 nh_vrf = nexthop_vrf;
7e24fdf3 774 else
88fa5104 775 nh_vrf = vrfname;
7e24fdf3 776
88fa5104 777 return static_route_leak(vty, vrfname, nh_vrf, AFI_IP, SAFI_UNICAST, no,
778 prefix, mask_str, NULL, gate_str, ifname, flag,
779 tag_str, distance_str, label, table_str,
065276ae 780 false, color_str);
7e24fdf3
DS
781}
782
ca77b518 783DEFPY_YANG(ipv6_route_blackhole,
7e24fdf3
DS
784 ipv6_route_blackhole_cmd,
785 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
54a3d7cb 786 <reject|blackhole>$flag \
7e24fdf3
DS
787 [{ \
788 tag (1-4294967295) \
789 |(1-255)$distance \
790 |vrf NAME \
791 |label WORD \
792 |table (1-4294967295) \
793 }]",
794 NO_STR
795 IPV6_STR
796 "Establish static routes\n"
797 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
798 "IPv6 source-dest route\n"
799 "IPv6 source prefix\n"
7e24fdf3
DS
800 "Emit an ICMP unreachable when matched\n"
801 "Silently discard pkts when matched\n"
802 "Set tag for this route\n"
803 "Tag value\n"
804 "Distance value for this prefix\n"
805 VRF_CMD_HELP_STR
806 MPLS_LABEL_HELPSTR
807 "Table to configure\n"
808 "The table number to configure\n")
809{
7e24fdf3
DS
810 return static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str,
811 NULL, from_str, NULL, NULL, flag, tag_str,
812 distance_str, vrf, label, table_str);
813}
814
ca77b518 815DEFPY_YANG(ipv6_route_blackhole_vrf,
7e24fdf3
DS
816 ipv6_route_blackhole_vrf_cmd,
817 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
54a3d7cb 818 <reject|blackhole>$flag \
7e24fdf3
DS
819 [{ \
820 tag (1-4294967295) \
821 |(1-255)$distance \
822 |label WORD \
823 |table (1-4294967295) \
824 }]",
825 NO_STR
826 IPV6_STR
827 "Establish static routes\n"
828 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
829 "IPv6 source-dest route\n"
830 "IPv6 source prefix\n"
7e24fdf3
DS
831 "Emit an ICMP unreachable when matched\n"
832 "Silently discard pkts when matched\n"
833 "Set tag for this route\n"
834 "Tag value\n"
835 "Distance value for this prefix\n"
836 MPLS_LABEL_HELPSTR
837 "Table to configure\n"
838 "The table number to configure\n")
839{
88fa5104 840 const struct lyd_node *vrf_dnode;
841 const char *vrfname;
7e24fdf3 842
88fa5104 843 vrf_dnode =
844 yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
845 if (!vrf_dnode) {
846 vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
7e24fdf3
DS
847 return CMD_WARNING_CONFIG_FAILED;
848 }
88fa5104 849 vrfname = yang_dnode_get_string(vrf_dnode, "./name");
7e24fdf3
DS
850
851 /*
852 * Coverity is complaining that prefix could
853 * be dereferenced, but we know that prefix will
854 * valid. Add an assert to make it happy
855 */
856 assert(prefix);
88fa5104 857
858 return static_route_leak(vty, vrfname, vrfname, AFI_IP6, SAFI_UNICAST,
859 no, prefix_str, NULL, from_str, NULL, NULL,
860 flag, tag_str, distance_str, label, table_str,
065276ae 861 false, NULL);
7e24fdf3
DS
862}
863
ca77b518 864DEFPY_YANG(ipv6_route_address_interface,
7e24fdf3
DS
865 ipv6_route_address_interface_cmd,
866 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
867 X:X::X:X$gate \
54a3d7cb 868 <INTERFACE|Null0>$ifname \
7e24fdf3
DS
869 [{ \
870 tag (1-4294967295) \
871 |(1-255)$distance \
872 |vrf NAME \
873 |label WORD \
874 |table (1-4294967295) \
875 |nexthop-vrf NAME \
02dc8ba3 876 |onlink$onlink \
065276ae 877 |color (1-4294967295) \
7e24fdf3
DS
878 }]",
879 NO_STR
880 IPV6_STR
881 "Establish static routes\n"
882 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
883 "IPv6 source-dest route\n"
884 "IPv6 source prefix\n"
885 "IPv6 gateway address\n"
886 "IPv6 gateway interface name\n"
54a3d7cb 887 "Null interface\n"
7e24fdf3
DS
888 "Set tag for this route\n"
889 "Tag value\n"
890 "Distance value for this prefix\n"
891 VRF_CMD_HELP_STR
892 MPLS_LABEL_HELPSTR
893 "Table to configure\n"
894 "The table number to configure\n"
02dc8ba3 895 VRF_CMD_HELP_STR
065276ae
SM
896 "Treat the nexthop as directly attached to the interface\n"
897 "SR-TE color\n"
898 "The SR-TE color to configure\n")
7e24fdf3 899{
88fa5104 900 const char *nh_vrf;
c66861af 901 const char *flag = NULL;
7e24fdf3 902
88fa5104 903 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
904 flag = "Null0";
905 ifname = NULL;
7e24fdf3
DS
906 }
907
88fa5104 908 if (!vrf)
909 vrf = VRF_DEFAULT_NAME;
7e24fdf3
DS
910
911 if (nexthop_vrf)
88fa5104 912 nh_vrf = nexthop_vrf;
7e24fdf3 913 else
88fa5104 914 nh_vrf = vrf;
7e24fdf3 915
88fa5104 916 return static_route_leak(vty, vrf, nh_vrf, AFI_IP6, SAFI_UNICAST, no,
917 prefix_str, NULL, from_str, gate_str, ifname,
918 flag, tag_str, distance_str, label, table_str,
065276ae 919 !!onlink, color_str);
7e24fdf3
DS
920}
921
ca77b518 922DEFPY_YANG(ipv6_route_address_interface_vrf,
7e24fdf3
DS
923 ipv6_route_address_interface_vrf_cmd,
924 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
925 X:X::X:X$gate \
54a3d7cb 926 <INTERFACE|Null0>$ifname \
7e24fdf3
DS
927 [{ \
928 tag (1-4294967295) \
929 |(1-255)$distance \
930 |label WORD \
931 |table (1-4294967295) \
932 |nexthop-vrf NAME \
02dc8ba3 933 |onlink$onlink \
065276ae 934 |color (1-4294967295) \
7e24fdf3
DS
935 }]",
936 NO_STR
937 IPV6_STR
938 "Establish static routes\n"
939 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
940 "IPv6 source-dest route\n"
941 "IPv6 source prefix\n"
942 "IPv6 gateway address\n"
943 "IPv6 gateway interface name\n"
54a3d7cb 944 "Null interface\n"
7e24fdf3
DS
945 "Set tag for this route\n"
946 "Tag value\n"
947 "Distance value for this prefix\n"
948 MPLS_LABEL_HELPSTR
949 "Table to configure\n"
950 "The table number to configure\n"
02dc8ba3 951 VRF_CMD_HELP_STR
065276ae
SM
952 "Treat the nexthop as directly attached to the interface\n"
953 "SR-TE color\n"
954 "The SR-TE color to configure\n")
7e24fdf3 955{
88fa5104 956 const char *nh_vrf;
c66861af 957 const char *flag = NULL;
88fa5104 958 const struct lyd_node *vrf_dnode;
959 const char *vrfname;
7e24fdf3 960
88fa5104 961 vrf_dnode =
962 yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
963 if (!vrf_dnode) {
964 vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
7e24fdf3
DS
965 return CMD_WARNING_CONFIG_FAILED;
966 }
88fa5104 967 vrfname = yang_dnode_get_string(vrf_dnode, "./name");
7e24fdf3
DS
968
969 if (nexthop_vrf)
88fa5104 970 nh_vrf = nexthop_vrf;
7e24fdf3 971 else
88fa5104 972 nh_vrf = vrfname;
7e24fdf3 973
54a3d7cb
QY
974 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
975 flag = "Null0";
976 ifname = NULL;
977 }
88fa5104 978 return static_route_leak(vty, vrfname, nh_vrf, AFI_IP6, SAFI_UNICAST,
979 no, prefix_str, NULL, from_str, gate_str,
980 ifname, flag, tag_str, distance_str, label,
065276ae 981 table_str, !!onlink, color_str);
7e24fdf3
DS
982}
983
ca77b518 984DEFPY_YANG(ipv6_route,
7e24fdf3
DS
985 ipv6_route_cmd,
986 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
54a3d7cb 987 <X:X::X:X$gate|<INTERFACE|Null0>$ifname> \
7e24fdf3
DS
988 [{ \
989 tag (1-4294967295) \
990 |(1-255)$distance \
991 |vrf NAME \
992 |label WORD \
993 |table (1-4294967295) \
994 |nexthop-vrf NAME \
065276ae 995 |color (1-4294967295) \
7e24fdf3
DS
996 }]",
997 NO_STR
998 IPV6_STR
999 "Establish static routes\n"
1000 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1001 "IPv6 source-dest route\n"
1002 "IPv6 source prefix\n"
1003 "IPv6 gateway address\n"
1004 "IPv6 gateway interface name\n"
54a3d7cb 1005 "Null interface\n"
7e24fdf3
DS
1006 "Set tag for this route\n"
1007 "Tag value\n"
1008 "Distance value for this prefix\n"
1009 VRF_CMD_HELP_STR
1010 MPLS_LABEL_HELPSTR
1011 "Table to configure\n"
1012 "The table number to configure\n"
065276ae
SM
1013 VRF_CMD_HELP_STR
1014 "SR-TE color\n"
1015 "The SR-TE color to configure\n")
7e24fdf3 1016{
88fa5104 1017 const char *nh_vrf;
c66861af 1018 const char *flag = NULL;
7e24fdf3 1019
88fa5104 1020 if (!vrf)
1021 vrf = VRF_DEFAULT_NAME;
7e24fdf3
DS
1022
1023 if (nexthop_vrf)
88fa5104 1024 nh_vrf = nexthop_vrf;
7e24fdf3 1025 else
88fa5104 1026 nh_vrf = vrf;
7e24fdf3 1027
54a3d7cb
QY
1028 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
1029 flag = "Null0";
1030 ifname = NULL;
1031 }
88fa5104 1032 return static_route_leak(vty, vrf, nh_vrf, AFI_IP6, SAFI_UNICAST, no,
1033 prefix_str, NULL, from_str, gate_str, ifname,
1034 flag, tag_str, distance_str, label, table_str,
065276ae 1035 false, color_str);
7e24fdf3
DS
1036}
1037
ca77b518 1038DEFPY_YANG(ipv6_route_vrf,
7e24fdf3
DS
1039 ipv6_route_vrf_cmd,
1040 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
54a3d7cb 1041 <X:X::X:X$gate|<INTERFACE|Null0>$ifname> \
7e24fdf3
DS
1042 [{ \
1043 tag (1-4294967295) \
1044 |(1-255)$distance \
1045 |label WORD \
1046 |table (1-4294967295) \
1047 |nexthop-vrf NAME \
065276ae 1048 |color (1-4294967295) \
7e24fdf3
DS
1049 }]",
1050 NO_STR
1051 IPV6_STR
1052 "Establish static routes\n"
1053 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1054 "IPv6 source-dest route\n"
1055 "IPv6 source prefix\n"
1056 "IPv6 gateway address\n"
1057 "IPv6 gateway interface name\n"
54a3d7cb 1058 "Null interface\n"
7e24fdf3
DS
1059 "Set tag for this route\n"
1060 "Tag value\n"
1061 "Distance value for this prefix\n"
1062 MPLS_LABEL_HELPSTR
1063 "Table to configure\n"
1064 "The table number to configure\n"
065276ae
SM
1065 VRF_CMD_HELP_STR
1066 "SR-TE color\n"
1067 "The SR-TE color to configure\n")
7e24fdf3 1068{
88fa5104 1069 const char *nh_vrf;
c66861af 1070 const char *flag = NULL;
88fa5104 1071 const struct lyd_node *vrf_dnode;
1072 const char *vrfname;
7e24fdf3 1073
88fa5104 1074 vrf_dnode =
1075 yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
1076 if (!vrf_dnode) {
1077 vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
7e24fdf3
DS
1078 return CMD_WARNING_CONFIG_FAILED;
1079 }
88fa5104 1080 vrfname = yang_dnode_get_string(vrf_dnode, "./name");
7e24fdf3
DS
1081
1082 if (nexthop_vrf)
88fa5104 1083 nh_vrf = nexthop_vrf;
7e24fdf3 1084 else
88fa5104 1085 nh_vrf = vrfname;
7e24fdf3 1086
54a3d7cb
QY
1087 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
1088 flag = "Null0";
1089 ifname = NULL;
1090 }
88fa5104 1091 return static_route_leak(vty, vrfname, nh_vrf, AFI_IP6, SAFI_UNICAST,
1092 no, prefix_str, NULL, from_str, gate_str,
1093 ifname, flag, tag_str, distance_str, label,
065276ae 1094 table_str, false, color_str);
7e24fdf3 1095}
b2f6ab67 1096DEFPY_YANG(debug_staticd, debug_staticd_cmd,
1097 "[no] debug static [{events$events|route$route}]",
1098 NO_STR DEBUG_STR STATICD_STR
1099 "Debug events\n"
1100 "Debug route\n")
31ddf3b7
MS
1101{
1102 /* If no specific category, change all */
1103 if (strmatch(argv[argc - 1]->text, "static"))
b2f6ab67 1104 static_debug_set(vty->node, !no, true, true);
31ddf3b7 1105 else
b2f6ab67 1106 static_debug_set(vty->node, !no, !!events, !!route);
7e24fdf3 1107
31ddf3b7
MS
1108 return CMD_SUCCESS;
1109}
1110
1111DEFUN_NOSH (show_debugging_static,
1112 show_debugging_static_cmd,
e60b527e
DS
1113 "show debugging [static]",
1114 SHOW_STR
1115 DEBUG_STR
1116 "Static Information\n")
1117{
31ddf3b7
MS
1118 vty_out(vty, "Staticd debugging status\n");
1119
1120 static_debug_status_write(vty);
e60b527e
DS
1121
1122 return CMD_SUCCESS;
1123}
1124
62b346ee 1125static struct cmd_node debug_node = {
f4b8291f 1126 .name = "debug",
62b346ee
DL
1127 .node = DEBUG_NODE,
1128 .prompt = "",
612c2c15 1129 .config_write = static_config_write_debug,
62b346ee 1130};
31ddf3b7 1131
7e24fdf3
DS
1132void static_vty_init(void)
1133{
612c2c15 1134 install_node(&debug_node);
31ddf3b7 1135
7e24fdf3
DS
1136 install_element(CONFIG_NODE, &ip_mroute_dist_cmd);
1137
1138 install_element(CONFIG_NODE, &ip_route_blackhole_cmd);
1139 install_element(VRF_NODE, &ip_route_blackhole_vrf_cmd);
1140 install_element(CONFIG_NODE, &ip_route_address_interface_cmd);
1141 install_element(VRF_NODE, &ip_route_address_interface_vrf_cmd);
1142 install_element(CONFIG_NODE, &ip_route_cmd);
1143 install_element(VRF_NODE, &ip_route_vrf_cmd);
1144
1145 install_element(CONFIG_NODE, &ipv6_route_blackhole_cmd);
1146 install_element(VRF_NODE, &ipv6_route_blackhole_vrf_cmd);
1147 install_element(CONFIG_NODE, &ipv6_route_address_interface_cmd);
1148 install_element(VRF_NODE, &ipv6_route_address_interface_vrf_cmd);
1149 install_element(CONFIG_NODE, &ipv6_route_cmd);
1150 install_element(VRF_NODE, &ipv6_route_vrf_cmd);
1151
dd73744d 1152 install_element(ENABLE_NODE, &show_debugging_static_cmd);
eed041e8 1153 install_element(ENABLE_NODE, &debug_staticd_cmd);
31ddf3b7 1154 install_element(CONFIG_NODE, &debug_staticd_cmd);
7e24fdf3 1155}