]> git.proxmox.com Git - mirror_frr.git/blame - staticd/static_vty.c
Merge pull request #8191 from idryzhov/bfd-cli-fixes
[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);
ff0e8ee8
WC
297 if (!dnode) {
298 vty_out(vty,
299 "%% Refusing to remove a non-existent route\n");
88fa5104 300 return ret;
ff0e8ee8 301 }
88fa5104 302
303 dnode = yang_get_subtree_with_no_sibling(dnode);
304 assert(dnode);
305 yang_dnode_get_path(dnode, ab_xpath, XPATH_MAXLEN);
306
307 nb_cli_enqueue_change(vty, ab_xpath, NB_OP_DESTROY, NULL);
308 ret = nb_cli_apply_changes(vty, ab_xpath);
7e24fdf3
DS
309 }
310
88fa5104 311 return ret;
7e24fdf3 312}
7e24fdf3
DS
313static int static_route(struct vty *vty, afi_t afi, safi_t safi,
314 const char *negate, const char *dest_str,
315 const char *mask_str, const char *src_str,
316 const char *gate_str, const char *ifname,
317 const char *flag_str, const char *tag_str,
318 const char *distance_str, const char *vrf_name,
319 const char *label_str, const char *table_str)
320{
88fa5104 321 if (!vrf_name)
322 vrf_name = VRF_DEFAULT_NAME;
7e24fdf3 323
88fa5104 324 return static_route_leak(vty, vrf_name, vrf_name, afi, safi, negate,
325 dest_str, mask_str, src_str, gate_str, ifname,
326 flag_str, tag_str, distance_str, label_str,
065276ae 327 table_str, false, NULL);
7e24fdf3
DS
328}
329
330/* Write static route configuration. */
331int static_config(struct vty *vty, struct static_vrf *svrf, afi_t afi,
332 safi_t safi, const char *cmd)
333{
7e24fdf3
DS
334 char spacing[100];
335 struct route_node *rn;
88fa5104 336 struct static_nexthop *nh;
337 struct static_path *pn;
7e24fdf3 338 struct route_table *stable;
88fa5104 339 struct static_route_info *si;
7e24fdf3
DS
340 char buf[SRCDEST2STR_BUFFER];
341 int write = 0;
88fa5104 342 struct stable_info *info;
7e24fdf3
DS
343
344 stable = svrf->stable[afi][safi];
345 if (stable == NULL)
346 return write;
347
772270f3
QY
348 snprintf(spacing, sizeof(spacing), "%s%s",
349 (svrf->vrf->vrf_id == VRF_DEFAULT) ? "" : " ", cmd);
7e24fdf3 350
88fa5104 351 for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) {
352 si = static_route_info_from_rnode(rn);
353 if (!si)
7e24fdf3 354 continue;
88fa5104 355 info = static_get_stable_info(rn);
356 frr_each(static_path_list, &si->path_list, pn) {
357 frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
358 vty_out(vty, "%s %s", spacing,
359 srcdest_rnode2str(rn, buf,
360 sizeof(buf)));
361
362 switch (nh->type) {
363 case STATIC_IPV4_GATEWAY:
4a3873a3 364 vty_out(vty, " %pI4", &nh->addr.ipv4);
7e24fdf3 365 break;
88fa5104 366 case STATIC_IPV6_GATEWAY:
367 vty_out(vty, " %s",
368 inet_ntop(AF_INET6,
369 &nh->addr.ipv6, buf,
370 sizeof(buf)));
7e24fdf3 371 break;
88fa5104 372 case STATIC_IFNAME:
373 vty_out(vty, " %s", nh->ifname);
374 break;
375 case STATIC_BLACKHOLE:
376 switch (nh->bh_type) {
377 case STATIC_BLACKHOLE_DROP:
378 vty_out(vty, " blackhole");
379 break;
380 case STATIC_BLACKHOLE_NULL:
381 vty_out(vty, " Null0");
382 break;
383 case STATIC_BLACKHOLE_REJECT:
384 vty_out(vty, " reject");
385 break;
386 }
387 break;
388 case STATIC_IPV4_GATEWAY_IFNAME:
389 vty_out(vty, " %s %s",
390 inet_ntop(AF_INET,
391 &nh->addr.ipv4, buf,
392 sizeof(buf)),
393 nh->ifname);
394 break;
395 case STATIC_IPV6_GATEWAY_IFNAME:
396 vty_out(vty, " %s %s",
397 inet_ntop(AF_INET6,
398 &nh->addr.ipv6, buf,
399 sizeof(buf)),
400 nh->ifname);
7e24fdf3
DS
401 break;
402 }
7e24fdf3 403
88fa5104 404 if (pn->tag)
405 vty_out(vty, " tag %" ROUTE_TAG_PRI,
406 pn->tag);
407
408 if (pn->distance
409 != ZEBRA_STATIC_DISTANCE_DEFAULT)
410 vty_out(vty, " %u", pn->distance);
411
412 /* Label information */
413 if (nh->snh_label.num_labels)
414 vty_out(vty, " label %s",
415 mpls_label2str(
416 nh->snh_label
417 .num_labels,
418 nh->snh_label.label,
419 buf, sizeof(buf), 0));
420
0d0aacea
RW
421 if (!strmatch(nh->nh_vrfname,
422 info->svrf->vrf->name))
88fa5104 423 vty_out(vty, " nexthop-vrf %s",
424 nh->nh_vrfname);
425
426 /*
427 * table ID from VRF overrides
428 * configured
429 */
430 if (pn->table_id
431 && svrf->vrf->data.l.table_id
432 == RT_TABLE_MAIN)
433 vty_out(vty, " table %u", pn->table_id);
434
435 if (nh->onlink)
436 vty_out(vty, " onlink");
437
065276ae
SM
438 /*
439 * SR-TE color
440 */
441 if (nh->color != 0)
442 vty_out(vty, " color %u", nh->color);
443
88fa5104 444 vty_out(vty, "\n");
445
446 write = 1;
447 }
7e24fdf3 448 }
88fa5104 449 }
7e24fdf3
DS
450 return write;
451}
452
453/* Static unicast routes for multicast RPF lookup. */
ca77b518 454DEFPY_YANG (ip_mroute_dist,
7e24fdf3
DS
455 ip_mroute_dist_cmd,
456 "[no] ip mroute A.B.C.D/M$prefix <A.B.C.D$gate|INTERFACE$ifname> [(1-255)$distance]",
457 NO_STR
458 IP_STR
459 "Configure static unicast route into MRIB for multicast RPF lookup\n"
460 "IP destination prefix (e.g. 10.0.0.0/8)\n"
461 "Nexthop address\n"
462 "Nexthop interface name\n"
463 "Distance\n")
464{
465 return static_route(vty, AFI_IP, SAFI_MULTICAST, no, prefix_str,
466 NULL, NULL, gate_str, ifname, NULL, NULL,
467 distance_str, NULL, NULL, NULL);
468}
469
470/* Static route configuration. */
ca77b518 471DEFPY_YANG(ip_route_blackhole,
7e24fdf3
DS
472 ip_route_blackhole_cmd,
473 "[no] ip route\
474 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
475 <reject|blackhole>$flag \
476 [{ \
477 tag (1-4294967295) \
478 |(1-255)$distance \
479 |vrf NAME \
480 |label WORD \
481 |table (1-4294967295) \
482 }]",
483 NO_STR IP_STR
484 "Establish static routes\n"
485 "IP destination prefix (e.g. 10.0.0.0/8)\n"
486 "IP destination prefix\n"
487 "IP destination prefix mask\n"
488 "Emit an ICMP unreachable when matched\n"
489 "Silently discard pkts when matched\n"
490 "Set tag for this route\n"
491 "Tag value\n"
492 "Distance value for this route\n"
493 VRF_CMD_HELP_STR
494 MPLS_LABEL_HELPSTR
495 "Table to configure\n"
496 "The table number to configure\n")
497{
7e24fdf3
DS
498 return static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix,
499 mask_str, NULL, NULL, NULL, flag, tag_str,
500 distance_str, vrf, label, table_str);
501}
502
ca77b518 503DEFPY_YANG(ip_route_blackhole_vrf,
7e24fdf3
DS
504 ip_route_blackhole_vrf_cmd,
505 "[no] ip route\
506 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
507 <reject|blackhole>$flag \
508 [{ \
509 tag (1-4294967295) \
510 |(1-255)$distance \
511 |label WORD \
512 |table (1-4294967295) \
513 }]",
514 NO_STR IP_STR
515 "Establish static routes\n"
516 "IP destination prefix (e.g. 10.0.0.0/8)\n"
517 "IP destination prefix\n"
518 "IP destination prefix mask\n"
519 "Emit an ICMP unreachable when matched\n"
520 "Silently discard pkts when matched\n"
521 "Set tag for this route\n"
522 "Tag value\n"
523 "Distance value for this route\n"
524 MPLS_LABEL_HELPSTR
525 "Table to configure\n"
526 "The table number to configure\n")
527{
88fa5104 528 const struct lyd_node *vrf_dnode;
529 const char *vrfname;
7e24fdf3 530
88fa5104 531 vrf_dnode =
532 yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
533 if (!vrf_dnode) {
534 vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
7e24fdf3
DS
535 return CMD_WARNING_CONFIG_FAILED;
536 }
88fa5104 537 vrfname = yang_dnode_get_string(vrf_dnode, "./name");
7e24fdf3
DS
538 /*
539 * Coverity is complaining that prefix could
540 * be dereferenced, but we know that prefix will
541 * valid. Add an assert to make it happy
542 */
543 assert(prefix);
88fa5104 544 return static_route_leak(vty, vrfname, vrfname, AFI_IP, SAFI_UNICAST,
545 no, prefix, mask_str, NULL, NULL, NULL, flag,
02dc8ba3 546 tag_str, distance_str, label, table_str,
065276ae 547 false, NULL);
7e24fdf3
DS
548}
549
ca77b518 550DEFPY_YANG(ip_route_address_interface,
7e24fdf3
DS
551 ip_route_address_interface_cmd,
552 "[no] ip route\
553 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
554 A.B.C.D$gate \
54a3d7cb 555 <INTERFACE|Null0>$ifname \
7e24fdf3
DS
556 [{ \
557 tag (1-4294967295) \
558 |(1-255)$distance \
559 |vrf NAME \
560 |label WORD \
561 |table (1-4294967295) \
562 |nexthop-vrf NAME \
02dc8ba3 563 |onlink$onlink \
065276ae 564 |color (1-4294967295) \
7e24fdf3
DS
565 }]",
566 NO_STR IP_STR
567 "Establish static routes\n"
568 "IP destination prefix (e.g. 10.0.0.0/8)\n"
569 "IP destination prefix\n"
570 "IP destination prefix mask\n"
571 "IP gateway address\n"
54a3d7cb
QY
572 "IP gateway interface name\n"
573 "Null interface\n"
7e24fdf3
DS
574 "Set tag for this route\n"
575 "Tag value\n"
576 "Distance value for this route\n"
577 VRF_CMD_HELP_STR
578 MPLS_LABEL_HELPSTR
579 "Table to configure\n"
580 "The table number to configure\n"
02dc8ba3 581 VRF_CMD_HELP_STR
065276ae
SM
582 "Treat the nexthop as directly attached to the interface\n"
583 "SR-TE color\n"
584 "The SR-TE color to configure\n")
7e24fdf3 585{
88fa5104 586 const char *nh_vrf;
7e24fdf3
DS
587 const char *flag = NULL;
588
589 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
590 flag = "Null0";
591 ifname = NULL;
592 }
88fa5104 593 if (!vrf)
594 vrf = VRF_DEFAULT_NAME;
7e24fdf3
DS
595
596 if (nexthop_vrf)
88fa5104 597 nh_vrf = nexthop_vrf;
7e24fdf3 598 else
88fa5104 599 nh_vrf = vrf;
7e24fdf3 600
88fa5104 601 return static_route_leak(vty, vrf, nh_vrf, AFI_IP, SAFI_UNICAST, no,
02dc8ba3
QY
602 prefix, mask_str, NULL, gate_str, ifname, flag,
603 tag_str, distance_str, label, table_str,
065276ae 604 !!onlink, color_str);
7e24fdf3
DS
605}
606
ca77b518 607DEFPY_YANG(ip_route_address_interface_vrf,
7e24fdf3
DS
608 ip_route_address_interface_vrf_cmd,
609 "[no] ip route\
610 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
611 A.B.C.D$gate \
54a3d7cb 612 <INTERFACE|Null0>$ifname \
7e24fdf3
DS
613 [{ \
614 tag (1-4294967295) \
615 |(1-255)$distance \
616 |label WORD \
617 |table (1-4294967295) \
618 |nexthop-vrf NAME \
02dc8ba3 619 |onlink$onlink \
065276ae
SM
620 |color (1-4294967295) \
621 }]",
7e24fdf3
DS
622 NO_STR IP_STR
623 "Establish static routes\n"
624 "IP destination prefix (e.g. 10.0.0.0/8)\n"
625 "IP destination prefix\n"
626 "IP destination prefix mask\n"
627 "IP gateway address\n"
54a3d7cb
QY
628 "IP gateway interface name\n"
629 "Null interface\n"
7e24fdf3
DS
630 "Set tag for this route\n"
631 "Tag value\n"
632 "Distance value for this route\n"
633 MPLS_LABEL_HELPSTR
634 "Table to configure\n"
635 "The table number to configure\n"
02dc8ba3 636 VRF_CMD_HELP_STR
065276ae
SM
637 "Treat the nexthop as directly attached to the interface\n"
638 "SR-TE color\n"
639 "The SR-TE color to configure\n")
7e24fdf3 640{
88fa5104 641 const char *nh_vrf;
7e24fdf3 642 const char *flag = NULL;
88fa5104 643 const struct lyd_node *vrf_dnode;
644 const char *vrfname;
7e24fdf3 645
88fa5104 646 vrf_dnode =
647 yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
648 if (!vrf_dnode) {
649 vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
7e24fdf3
DS
650 return CMD_WARNING_CONFIG_FAILED;
651 }
88fa5104 652 vrfname = yang_dnode_get_string(vrf_dnode, "./name");
7e24fdf3
DS
653
654 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
655 flag = "Null0";
656 ifname = NULL;
657 }
7e24fdf3 658 if (nexthop_vrf)
88fa5104 659 nh_vrf = nexthop_vrf;
7e24fdf3 660 else
88fa5104 661 nh_vrf = vrfname;
7e24fdf3 662
88fa5104 663 return static_route_leak(vty, vrfname, nh_vrf, AFI_IP, SAFI_UNICAST, no,
02dc8ba3
QY
664 prefix, mask_str, NULL, gate_str, ifname, flag,
665 tag_str, distance_str, label, table_str,
065276ae 666 !!onlink, color_str);
7e24fdf3
DS
667}
668
ca77b518 669DEFPY_YANG(ip_route,
7e24fdf3
DS
670 ip_route_cmd,
671 "[no] ip route\
672 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
54a3d7cb 673 <A.B.C.D$gate|<INTERFACE|Null0>$ifname> \
7e24fdf3
DS
674 [{ \
675 tag (1-4294967295) \
676 |(1-255)$distance \
677 |vrf NAME \
678 |label WORD \
679 |table (1-4294967295) \
680 |nexthop-vrf NAME \
065276ae 681 |color (1-4294967295) \
7e24fdf3
DS
682 }]",
683 NO_STR IP_STR
684 "Establish static routes\n"
685 "IP destination prefix (e.g. 10.0.0.0/8)\n"
686 "IP destination prefix\n"
687 "IP destination prefix mask\n"
688 "IP gateway address\n"
689 "IP gateway interface name\n"
54a3d7cb 690 "Null interface\n"
7e24fdf3
DS
691 "Set tag for this route\n"
692 "Tag value\n"
693 "Distance value for this route\n"
694 VRF_CMD_HELP_STR
695 MPLS_LABEL_HELPSTR
696 "Table to configure\n"
697 "The table number to configure\n"
065276ae
SM
698 VRF_CMD_HELP_STR
699 "SR-TE color\n"
700 "The SR-TE color to configure\n")
7e24fdf3 701{
88fa5104 702 const char *nh_vrf;
7e24fdf3
DS
703 const char *flag = NULL;
704
7e24fdf3
DS
705 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
706 flag = "Null0";
707 ifname = NULL;
708 }
709
88fa5104 710 if (!vrf)
711 vrf = VRF_DEFAULT_NAME;
7e24fdf3
DS
712
713 if (nexthop_vrf)
88fa5104 714 nh_vrf = nexthop_vrf;
7e24fdf3 715 else
88fa5104 716 nh_vrf = vrf;
7e24fdf3 717
88fa5104 718 return static_route_leak(vty, vrf, nh_vrf, AFI_IP, SAFI_UNICAST, no,
719 prefix, mask_str, NULL, gate_str, ifname, flag,
720 tag_str, distance_str, label, table_str,
065276ae 721 false, color_str);
7e24fdf3
DS
722}
723
ca77b518 724DEFPY_YANG(ip_route_vrf,
7e24fdf3
DS
725 ip_route_vrf_cmd,
726 "[no] ip route\
727 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
54a3d7cb 728 <A.B.C.D$gate|<INTERFACE|Null0>$ifname> \
7e24fdf3
DS
729 [{ \
730 tag (1-4294967295) \
731 |(1-255)$distance \
732 |label WORD \
733 |table (1-4294967295) \
734 |nexthop-vrf NAME \
065276ae 735 |color (1-4294967295) \
7e24fdf3
DS
736 }]",
737 NO_STR IP_STR
738 "Establish static routes\n"
739 "IP destination prefix (e.g. 10.0.0.0/8)\n"
740 "IP destination prefix\n"
741 "IP destination prefix mask\n"
742 "IP gateway address\n"
743 "IP gateway interface name\n"
54a3d7cb 744 "Null interface\n"
7e24fdf3
DS
745 "Set tag for this route\n"
746 "Tag value\n"
747 "Distance value for this route\n"
748 MPLS_LABEL_HELPSTR
749 "Table to configure\n"
750 "The table number to configure\n"
065276ae
SM
751 VRF_CMD_HELP_STR
752 "SR-TE color\n"
753 "The SR-TE color to configure\n")
7e24fdf3 754{
88fa5104 755 const char *nh_vrf;
51c4ed0a 756 const char *flag = NULL;
88fa5104 757 const struct lyd_node *vrf_dnode;
758 const char *vrfname;
7e24fdf3 759
88fa5104 760 vrf_dnode =
761 yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
762 if (!vrf_dnode) {
763 vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
7e24fdf3
DS
764 return CMD_WARNING_CONFIG_FAILED;
765 }
766
88fa5104 767 vrfname = yang_dnode_get_string(vrf_dnode, "./name");
768
7e24fdf3
DS
769 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
770 flag = "Null0";
771 ifname = NULL;
772 }
7e24fdf3 773 if (nexthop_vrf)
88fa5104 774 nh_vrf = nexthop_vrf;
7e24fdf3 775 else
88fa5104 776 nh_vrf = vrfname;
7e24fdf3 777
88fa5104 778 return static_route_leak(vty, vrfname, nh_vrf, AFI_IP, SAFI_UNICAST, no,
779 prefix, mask_str, NULL, gate_str, ifname, flag,
780 tag_str, distance_str, label, table_str,
065276ae 781 false, color_str);
7e24fdf3
DS
782}
783
ca77b518 784DEFPY_YANG(ipv6_route_blackhole,
7e24fdf3
DS
785 ipv6_route_blackhole_cmd,
786 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
54a3d7cb 787 <reject|blackhole>$flag \
7e24fdf3
DS
788 [{ \
789 tag (1-4294967295) \
790 |(1-255)$distance \
791 |vrf NAME \
792 |label WORD \
793 |table (1-4294967295) \
794 }]",
795 NO_STR
796 IPV6_STR
797 "Establish static routes\n"
798 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
799 "IPv6 source-dest route\n"
800 "IPv6 source prefix\n"
7e24fdf3
DS
801 "Emit an ICMP unreachable when matched\n"
802 "Silently discard pkts when matched\n"
803 "Set tag for this route\n"
804 "Tag value\n"
805 "Distance value for this prefix\n"
806 VRF_CMD_HELP_STR
807 MPLS_LABEL_HELPSTR
808 "Table to configure\n"
809 "The table number to configure\n")
810{
7e24fdf3
DS
811 return static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str,
812 NULL, from_str, NULL, NULL, flag, tag_str,
813 distance_str, vrf, label, table_str);
814}
815
ca77b518 816DEFPY_YANG(ipv6_route_blackhole_vrf,
7e24fdf3
DS
817 ipv6_route_blackhole_vrf_cmd,
818 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
54a3d7cb 819 <reject|blackhole>$flag \
7e24fdf3
DS
820 [{ \
821 tag (1-4294967295) \
822 |(1-255)$distance \
823 |label WORD \
824 |table (1-4294967295) \
825 }]",
826 NO_STR
827 IPV6_STR
828 "Establish static routes\n"
829 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
830 "IPv6 source-dest route\n"
831 "IPv6 source prefix\n"
7e24fdf3
DS
832 "Emit an ICMP unreachable when matched\n"
833 "Silently discard pkts when matched\n"
834 "Set tag for this route\n"
835 "Tag value\n"
836 "Distance value for this prefix\n"
837 MPLS_LABEL_HELPSTR
838 "Table to configure\n"
839 "The table number to configure\n")
840{
88fa5104 841 const struct lyd_node *vrf_dnode;
842 const char *vrfname;
7e24fdf3 843
88fa5104 844 vrf_dnode =
845 yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
846 if (!vrf_dnode) {
847 vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
7e24fdf3
DS
848 return CMD_WARNING_CONFIG_FAILED;
849 }
88fa5104 850 vrfname = yang_dnode_get_string(vrf_dnode, "./name");
7e24fdf3
DS
851
852 /*
853 * Coverity is complaining that prefix could
854 * be dereferenced, but we know that prefix will
855 * valid. Add an assert to make it happy
856 */
857 assert(prefix);
88fa5104 858
859 return static_route_leak(vty, vrfname, vrfname, AFI_IP6, SAFI_UNICAST,
860 no, prefix_str, NULL, from_str, NULL, NULL,
861 flag, tag_str, distance_str, label, table_str,
065276ae 862 false, NULL);
7e24fdf3
DS
863}
864
ca77b518 865DEFPY_YANG(ipv6_route_address_interface,
7e24fdf3
DS
866 ipv6_route_address_interface_cmd,
867 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
868 X:X::X:X$gate \
54a3d7cb 869 <INTERFACE|Null0>$ifname \
7e24fdf3
DS
870 [{ \
871 tag (1-4294967295) \
872 |(1-255)$distance \
873 |vrf NAME \
874 |label WORD \
875 |table (1-4294967295) \
876 |nexthop-vrf NAME \
02dc8ba3 877 |onlink$onlink \
065276ae 878 |color (1-4294967295) \
7e24fdf3
DS
879 }]",
880 NO_STR
881 IPV6_STR
882 "Establish static routes\n"
883 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
884 "IPv6 source-dest route\n"
885 "IPv6 source prefix\n"
886 "IPv6 gateway address\n"
887 "IPv6 gateway interface name\n"
54a3d7cb 888 "Null interface\n"
7e24fdf3
DS
889 "Set tag for this route\n"
890 "Tag value\n"
891 "Distance value for this prefix\n"
892 VRF_CMD_HELP_STR
893 MPLS_LABEL_HELPSTR
894 "Table to configure\n"
895 "The table number to configure\n"
02dc8ba3 896 VRF_CMD_HELP_STR
065276ae
SM
897 "Treat the nexthop as directly attached to the interface\n"
898 "SR-TE color\n"
899 "The SR-TE color to configure\n")
7e24fdf3 900{
88fa5104 901 const char *nh_vrf;
c66861af 902 const char *flag = NULL;
7e24fdf3 903
88fa5104 904 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
905 flag = "Null0";
906 ifname = NULL;
7e24fdf3
DS
907 }
908
88fa5104 909 if (!vrf)
910 vrf = VRF_DEFAULT_NAME;
7e24fdf3
DS
911
912 if (nexthop_vrf)
88fa5104 913 nh_vrf = nexthop_vrf;
7e24fdf3 914 else
88fa5104 915 nh_vrf = vrf;
7e24fdf3 916
88fa5104 917 return static_route_leak(vty, vrf, nh_vrf, AFI_IP6, SAFI_UNICAST, no,
918 prefix_str, NULL, from_str, gate_str, ifname,
919 flag, tag_str, distance_str, label, table_str,
065276ae 920 !!onlink, color_str);
7e24fdf3
DS
921}
922
ca77b518 923DEFPY_YANG(ipv6_route_address_interface_vrf,
7e24fdf3
DS
924 ipv6_route_address_interface_vrf_cmd,
925 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
926 X:X::X:X$gate \
54a3d7cb 927 <INTERFACE|Null0>$ifname \
7e24fdf3
DS
928 [{ \
929 tag (1-4294967295) \
930 |(1-255)$distance \
931 |label WORD \
932 |table (1-4294967295) \
933 |nexthop-vrf NAME \
02dc8ba3 934 |onlink$onlink \
065276ae 935 |color (1-4294967295) \
7e24fdf3
DS
936 }]",
937 NO_STR
938 IPV6_STR
939 "Establish static routes\n"
940 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
941 "IPv6 source-dest route\n"
942 "IPv6 source prefix\n"
943 "IPv6 gateway address\n"
944 "IPv6 gateway interface name\n"
54a3d7cb 945 "Null interface\n"
7e24fdf3
DS
946 "Set tag for this route\n"
947 "Tag value\n"
948 "Distance value for this prefix\n"
949 MPLS_LABEL_HELPSTR
950 "Table to configure\n"
951 "The table number to configure\n"
02dc8ba3 952 VRF_CMD_HELP_STR
065276ae
SM
953 "Treat the nexthop as directly attached to the interface\n"
954 "SR-TE color\n"
955 "The SR-TE color to configure\n")
7e24fdf3 956{
88fa5104 957 const char *nh_vrf;
c66861af 958 const char *flag = NULL;
88fa5104 959 const struct lyd_node *vrf_dnode;
960 const char *vrfname;
7e24fdf3 961
88fa5104 962 vrf_dnode =
963 yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
964 if (!vrf_dnode) {
965 vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
7e24fdf3
DS
966 return CMD_WARNING_CONFIG_FAILED;
967 }
88fa5104 968 vrfname = yang_dnode_get_string(vrf_dnode, "./name");
7e24fdf3
DS
969
970 if (nexthop_vrf)
88fa5104 971 nh_vrf = nexthop_vrf;
7e24fdf3 972 else
88fa5104 973 nh_vrf = vrfname;
7e24fdf3 974
54a3d7cb
QY
975 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
976 flag = "Null0";
977 ifname = NULL;
978 }
88fa5104 979 return static_route_leak(vty, vrfname, nh_vrf, AFI_IP6, SAFI_UNICAST,
980 no, prefix_str, NULL, from_str, gate_str,
981 ifname, flag, tag_str, distance_str, label,
065276ae 982 table_str, !!onlink, color_str);
7e24fdf3
DS
983}
984
ca77b518 985DEFPY_YANG(ipv6_route,
7e24fdf3
DS
986 ipv6_route_cmd,
987 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
54a3d7cb 988 <X:X::X:X$gate|<INTERFACE|Null0>$ifname> \
7e24fdf3
DS
989 [{ \
990 tag (1-4294967295) \
991 |(1-255)$distance \
992 |vrf NAME \
993 |label WORD \
994 |table (1-4294967295) \
995 |nexthop-vrf NAME \
065276ae 996 |color (1-4294967295) \
7e24fdf3
DS
997 }]",
998 NO_STR
999 IPV6_STR
1000 "Establish static routes\n"
1001 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1002 "IPv6 source-dest route\n"
1003 "IPv6 source prefix\n"
1004 "IPv6 gateway address\n"
1005 "IPv6 gateway interface name\n"
54a3d7cb 1006 "Null interface\n"
7e24fdf3
DS
1007 "Set tag for this route\n"
1008 "Tag value\n"
1009 "Distance value for this prefix\n"
1010 VRF_CMD_HELP_STR
1011 MPLS_LABEL_HELPSTR
1012 "Table to configure\n"
1013 "The table number to configure\n"
065276ae
SM
1014 VRF_CMD_HELP_STR
1015 "SR-TE color\n"
1016 "The SR-TE color to configure\n")
7e24fdf3 1017{
88fa5104 1018 const char *nh_vrf;
c66861af 1019 const char *flag = NULL;
7e24fdf3 1020
88fa5104 1021 if (!vrf)
1022 vrf = VRF_DEFAULT_NAME;
7e24fdf3
DS
1023
1024 if (nexthop_vrf)
88fa5104 1025 nh_vrf = nexthop_vrf;
7e24fdf3 1026 else
88fa5104 1027 nh_vrf = vrf;
7e24fdf3 1028
54a3d7cb
QY
1029 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
1030 flag = "Null0";
1031 ifname = NULL;
1032 }
88fa5104 1033 return static_route_leak(vty, vrf, nh_vrf, AFI_IP6, SAFI_UNICAST, no,
1034 prefix_str, NULL, from_str, gate_str, ifname,
1035 flag, tag_str, distance_str, label, table_str,
065276ae 1036 false, color_str);
7e24fdf3
DS
1037}
1038
ca77b518 1039DEFPY_YANG(ipv6_route_vrf,
7e24fdf3
DS
1040 ipv6_route_vrf_cmd,
1041 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
54a3d7cb 1042 <X:X::X:X$gate|<INTERFACE|Null0>$ifname> \
7e24fdf3
DS
1043 [{ \
1044 tag (1-4294967295) \
1045 |(1-255)$distance \
1046 |label WORD \
1047 |table (1-4294967295) \
1048 |nexthop-vrf NAME \
065276ae 1049 |color (1-4294967295) \
7e24fdf3
DS
1050 }]",
1051 NO_STR
1052 IPV6_STR
1053 "Establish static routes\n"
1054 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1055 "IPv6 source-dest route\n"
1056 "IPv6 source prefix\n"
1057 "IPv6 gateway address\n"
1058 "IPv6 gateway interface name\n"
54a3d7cb 1059 "Null interface\n"
7e24fdf3
DS
1060 "Set tag for this route\n"
1061 "Tag value\n"
1062 "Distance value for this prefix\n"
1063 MPLS_LABEL_HELPSTR
1064 "Table to configure\n"
1065 "The table number to configure\n"
065276ae
SM
1066 VRF_CMD_HELP_STR
1067 "SR-TE color\n"
1068 "The SR-TE color to configure\n")
7e24fdf3 1069{
88fa5104 1070 const char *nh_vrf;
c66861af 1071 const char *flag = NULL;
88fa5104 1072 const struct lyd_node *vrf_dnode;
1073 const char *vrfname;
7e24fdf3 1074
88fa5104 1075 vrf_dnode =
1076 yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
1077 if (!vrf_dnode) {
1078 vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
7e24fdf3
DS
1079 return CMD_WARNING_CONFIG_FAILED;
1080 }
88fa5104 1081 vrfname = yang_dnode_get_string(vrf_dnode, "./name");
7e24fdf3
DS
1082
1083 if (nexthop_vrf)
88fa5104 1084 nh_vrf = nexthop_vrf;
7e24fdf3 1085 else
88fa5104 1086 nh_vrf = vrfname;
7e24fdf3 1087
54a3d7cb
QY
1088 if (ifname && !strncasecmp(ifname, "Null0", 5)) {
1089 flag = "Null0";
1090 ifname = NULL;
1091 }
88fa5104 1092 return static_route_leak(vty, vrfname, nh_vrf, AFI_IP6, SAFI_UNICAST,
1093 no, prefix_str, NULL, from_str, gate_str,
1094 ifname, flag, tag_str, distance_str, label,
065276ae 1095 table_str, false, color_str);
7e24fdf3 1096}
b2f6ab67 1097DEFPY_YANG(debug_staticd, debug_staticd_cmd,
1098 "[no] debug static [{events$events|route$route}]",
1099 NO_STR DEBUG_STR STATICD_STR
1100 "Debug events\n"
1101 "Debug route\n")
31ddf3b7
MS
1102{
1103 /* If no specific category, change all */
1104 if (strmatch(argv[argc - 1]->text, "static"))
b2f6ab67 1105 static_debug_set(vty->node, !no, true, true);
31ddf3b7 1106 else
b2f6ab67 1107 static_debug_set(vty->node, !no, !!events, !!route);
7e24fdf3 1108
31ddf3b7
MS
1109 return CMD_SUCCESS;
1110}
1111
1112DEFUN_NOSH (show_debugging_static,
1113 show_debugging_static_cmd,
e60b527e
DS
1114 "show debugging [static]",
1115 SHOW_STR
1116 DEBUG_STR
1117 "Static Information\n")
1118{
31ddf3b7
MS
1119 vty_out(vty, "Staticd debugging status\n");
1120
1121 static_debug_status_write(vty);
e60b527e
DS
1122
1123 return CMD_SUCCESS;
1124}
1125
62b346ee 1126static struct cmd_node debug_node = {
f4b8291f 1127 .name = "debug",
62b346ee
DL
1128 .node = DEBUG_NODE,
1129 .prompt = "",
612c2c15 1130 .config_write = static_config_write_debug,
62b346ee 1131};
31ddf3b7 1132
7e24fdf3
DS
1133void static_vty_init(void)
1134{
612c2c15 1135 install_node(&debug_node);
31ddf3b7 1136
7e24fdf3
DS
1137 install_element(CONFIG_NODE, &ip_mroute_dist_cmd);
1138
1139 install_element(CONFIG_NODE, &ip_route_blackhole_cmd);
1140 install_element(VRF_NODE, &ip_route_blackhole_vrf_cmd);
1141 install_element(CONFIG_NODE, &ip_route_address_interface_cmd);
1142 install_element(VRF_NODE, &ip_route_address_interface_vrf_cmd);
1143 install_element(CONFIG_NODE, &ip_route_cmd);
1144 install_element(VRF_NODE, &ip_route_vrf_cmd);
1145
1146 install_element(CONFIG_NODE, &ipv6_route_blackhole_cmd);
1147 install_element(VRF_NODE, &ipv6_route_blackhole_vrf_cmd);
1148 install_element(CONFIG_NODE, &ipv6_route_address_interface_cmd);
1149 install_element(VRF_NODE, &ipv6_route_address_interface_vrf_cmd);
1150 install_element(CONFIG_NODE, &ipv6_route_cmd);
1151 install_element(VRF_NODE, &ipv6_route_vrf_cmd);
1152
dd73744d 1153 install_element(ENABLE_NODE, &show_debugging_static_cmd);
eed041e8 1154 install_element(ENABLE_NODE, &debug_staticd_cmd);
31ddf3b7 1155 install_element(CONFIG_NODE, &debug_staticd_cmd);
7e24fdf3 1156}