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