]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
7e24fdf3 DS |
2 | /* |
3 | * STATICd - vty code | |
4 | * Copyright (C) 2018 Cumulus Networks, Inc. | |
5 | * Donald Sharp | |
7e24fdf3 DS |
6 | */ |
7 | #include <zebra.h> | |
8 | ||
9 | #include "command.h" | |
10 | #include "vty.h" | |
11 | #include "vrf.h" | |
12 | #include "prefix.h" | |
13 | #include "nexthop.h" | |
14 | #include "table.h" | |
15 | #include "srcdest_table.h" | |
16 | #include "mpls.h" | |
88fa5104 | 17 | #include "northbound.h" |
18 | #include "libfrr.h" | |
19 | #include "routing_nb.h" | |
20 | #include "northbound_cli.h" | |
7e24fdf3 DS |
21 | |
22 | #include "static_vrf.h" | |
7e24fdf3 DS |
23 | #include "static_vty.h" |
24 | #include "static_routes.h" | |
31ddf3b7 | 25 | #include "static_debug.h" |
7e24fdf3 | 26 | #include "staticd/static_vty_clippy.c" |
88fa5104 | 27 | #include "static_nb.h" |
31ddf3b7 MS |
28 | |
29 | #define STATICD_STR "Static route daemon\n" | |
30 | ||
fc6f9d74 RZ |
31 | /** All possible route parameters available in CLI. */ |
32 | struct static_route_args { | |
33 | /** "no" command? */ | |
34 | bool delete; | |
35 | /** Is VRF obtained from XPath? */ | |
36 | bool xpath_vrf; | |
37 | ||
38 | bool onlink; | |
39 | afi_t afi; | |
40 | safi_t safi; | |
41 | ||
42 | const char *vrf; | |
43 | const char *nexthop_vrf; | |
44 | const char *prefix; | |
45 | const char *prefix_mask; | |
46 | const char *source; | |
47 | const char *gateway; | |
48 | const char *interface_name; | |
49 | const char *flag; | |
50 | const char *tag; | |
51 | const char *distance; | |
52 | const char *label; | |
53 | const char *table; | |
54 | const char *color; | |
e280279d RZ |
55 | |
56 | bool bfd; | |
57 | bool bfd_multi_hop; | |
58 | const char *bfd_source; | |
59 | const char *bfd_profile; | |
fc6f9d74 RZ |
60 | }; |
61 | ||
62 | static int static_route_nb_run(struct vty *vty, struct static_route_args *args) | |
7e24fdf3 | 63 | { |
7e24fdf3 | 64 | int ret; |
7e24fdf3 | 65 | struct prefix p, src; |
7e24fdf3 | 66 | struct in_addr mask; |
9ccaa12d | 67 | enum static_nh_type type; |
88fa5104 | 68 | const char *bh_type; |
69 | char xpath_prefix[XPATH_MAXLEN]; | |
70 | char xpath_nexthop[XPATH_MAXLEN]; | |
71 | char xpath_mpls[XPATH_MAXLEN]; | |
72 | char xpath_label[XPATH_MAXLEN]; | |
73 | char ab_xpath[XPATH_MAXLEN]; | |
74 | char buf_prefix[PREFIX_STRLEN]; | |
fc6f9d74 RZ |
75 | char buf_src_prefix[PREFIX_STRLEN] = {}; |
76 | char buf_nh_type[PREFIX_STRLEN] = {}; | |
88fa5104 | 77 | char buf_tag[PREFIX_STRLEN]; |
88fa5104 | 78 | uint8_t label_stack_id = 0; |
79 | const char *buf_gate_str; | |
80 | uint8_t distance = ZEBRA_STATIC_DISTANCE_DEFAULT; | |
81 | route_tag_t tag = 0; | |
7e24fdf3 | 82 | uint32_t table_id = 0; |
88fa5104 | 83 | const struct lyd_node *dnode; |
fc6f9d74 | 84 | const struct lyd_node *vrf_dnode; |
88fa5104 | 85 | |
fc6f9d74 RZ |
86 | if (args->xpath_vrf) { |
87 | vrf_dnode = yang_dnode_get(vty->candidate_config->dnode, | |
88 | VTY_CURR_XPATH); | |
89 | if (vrf_dnode == NULL) { | |
90 | vty_out(vty, | |
91 | "%% Failed to get vrf dnode in candidate db\n"); | |
92 | return CMD_WARNING_CONFIG_FAILED; | |
93 | } | |
7e24fdf3 | 94 | |
fc6f9d74 RZ |
95 | args->vrf = yang_dnode_get_string(vrf_dnode, "./name"); |
96 | } else { | |
97 | if (args->vrf == NULL) | |
98 | args->vrf = VRF_DEFAULT_NAME; | |
7e24fdf3 | 99 | } |
fc6f9d74 RZ |
100 | if (args->nexthop_vrf == NULL) |
101 | args->nexthop_vrf = args->vrf; | |
7e24fdf3 | 102 | |
fc6f9d74 RZ |
103 | if (args->interface_name && |
104 | !strcasecmp(args->interface_name, "Null0")) { | |
105 | args->flag = "Null0"; | |
106 | args->interface_name = NULL; | |
107 | } | |
108 | ||
109 | assert(!!str2prefix(args->prefix, &p)); | |
110 | ||
111 | switch (args->afi) { | |
7e24fdf3 DS |
112 | case AFI_IP: |
113 | /* Cisco like mask notation. */ | |
fc6f9d74 RZ |
114 | if (args->prefix_mask) { |
115 | assert(inet_pton(AF_INET, args->prefix_mask, &mask) == | |
116 | 1); | |
7e24fdf3 DS |
117 | p.prefixlen = ip_masklen(mask); |
118 | } | |
119 | break; | |
120 | case AFI_IP6: | |
121 | /* srcdest routing */ | |
fc6f9d74 RZ |
122 | if (args->source) |
123 | assert(!!str2prefix(args->source, &src)); | |
7e24fdf3 | 124 | break; |
7c734d80 DS |
125 | case AFI_L2VPN: |
126 | case AFI_UNSPEC: | |
127 | case AFI_MAX: | |
7e24fdf3 DS |
128 | break; |
129 | } | |
130 | ||
131 | /* Apply mask for given prefix. */ | |
132 | apply_mask(&p); | |
88fa5104 | 133 | prefix2str(&p, buf_prefix, sizeof(buf_prefix)); |
7e24fdf3 | 134 | |
e280279d RZ |
135 | if (args->bfd && args->gateway == NULL) { |
136 | vty_out(vty, "%% Route monitoring requires a gateway\n"); | |
137 | return CMD_WARNING_CONFIG_FAILED; | |
138 | } | |
139 | ||
fc6f9d74 | 140 | if (args->source) |
88fa5104 | 141 | prefix2str(&src, buf_src_prefix, sizeof(buf_src_prefix)); |
fc6f9d74 RZ |
142 | if (args->gateway) |
143 | buf_gate_str = args->gateway; | |
88fa5104 | 144 | else |
145 | buf_gate_str = ""; | |
146 | ||
fc6f9d74 | 147 | if (args->gateway == NULL && args->interface_name == NULL) |
88fa5104 | 148 | type = STATIC_BLACKHOLE; |
fc6f9d74 RZ |
149 | else if (args->gateway && args->interface_name) { |
150 | if (args->afi == AFI_IP) | |
88fa5104 | 151 | type = STATIC_IPV4_GATEWAY_IFNAME; |
152 | else | |
153 | type = STATIC_IPV6_GATEWAY_IFNAME; | |
fc6f9d74 | 154 | } else if (args->interface_name) |
88fa5104 | 155 | type = STATIC_IFNAME; |
156 | else { | |
fc6f9d74 | 157 | if (args->afi == AFI_IP) |
88fa5104 | 158 | type = STATIC_IPV4_GATEWAY; |
159 | else | |
160 | type = STATIC_IPV6_GATEWAY; | |
7e24fdf3 DS |
161 | } |
162 | ||
163 | /* Administrative distance. */ | |
fc6f9d74 RZ |
164 | if (args->distance) |
165 | distance = strtol(args->distance, NULL, 10); | |
7e24fdf3 DS |
166 | |
167 | /* tag */ | |
fc6f9d74 RZ |
168 | if (args->tag) |
169 | tag = strtoul(args->tag, NULL, 10); | |
7e24fdf3 | 170 | |
7e24fdf3 | 171 | /* TableID */ |
fc6f9d74 RZ |
172 | if (args->table) |
173 | table_id = strtol(args->table, NULL, 10); | |
7e24fdf3 | 174 | |
fc6f9d74 RZ |
175 | static_get_nh_type(type, buf_nh_type, sizeof(buf_nh_type)); |
176 | if (!args->delete) { | |
177 | if (args->source) | |
e1ea6b20 IR |
178 | snprintf(ab_xpath, sizeof(ab_xpath), |
179 | FRR_DEL_S_ROUTE_SRC_NH_KEY_NO_DISTANCE_XPATH, | |
fc6f9d74 | 180 | "frr-staticd:staticd", "staticd", args->vrf, |
e1ea6b20 | 181 | buf_prefix, |
fc6f9d74 RZ |
182 | yang_afi_safi_value2identity(args->afi, |
183 | args->safi), | |
184 | buf_src_prefix, table_id, buf_nh_type, | |
185 | args->nexthop_vrf, buf_gate_str, | |
186 | args->interface_name); | |
e1ea6b20 IR |
187 | else |
188 | snprintf(ab_xpath, sizeof(ab_xpath), | |
189 | FRR_DEL_S_ROUTE_NH_KEY_NO_DISTANCE_XPATH, | |
fc6f9d74 | 190 | "frr-staticd:staticd", "staticd", args->vrf, |
e1ea6b20 | 191 | buf_prefix, |
fc6f9d74 RZ |
192 | yang_afi_safi_value2identity(args->afi, |
193 | args->safi), | |
194 | table_id, buf_nh_type, args->nexthop_vrf, | |
195 | buf_gate_str, args->interface_name); | |
e1ea6b20 IR |
196 | |
197 | /* | |
198 | * If there's already the same nexthop but with a different | |
199 | * distance, then remove it for the replacement. | |
200 | */ | |
201 | dnode = yang_dnode_get(vty->candidate_config->dnode, ab_xpath); | |
202 | if (dnode) { | |
203 | dnode = yang_get_subtree_with_no_sibling(dnode); | |
204 | assert(dnode); | |
205 | yang_dnode_get_path(dnode, ab_xpath, XPATH_MAXLEN); | |
206 | ||
207 | nb_cli_enqueue_change(vty, ab_xpath, NB_OP_DESTROY, | |
208 | NULL); | |
209 | } | |
210 | ||
88fa5104 | 211 | /* route + path procesing */ |
fc6f9d74 | 212 | if (args->source) |
88fa5104 | 213 | snprintf(xpath_prefix, sizeof(xpath_prefix), |
214 | FRR_S_ROUTE_SRC_INFO_KEY_XPATH, | |
fc6f9d74 | 215 | "frr-staticd:staticd", "staticd", args->vrf, |
88fa5104 | 216 | buf_prefix, |
fc6f9d74 RZ |
217 | yang_afi_safi_value2identity(args->afi, |
218 | args->safi), | |
ef4b6b22 | 219 | buf_src_prefix, table_id, distance); |
88fa5104 | 220 | else |
221 | snprintf(xpath_prefix, sizeof(xpath_prefix), | |
222 | FRR_STATIC_ROUTE_INFO_KEY_XPATH, | |
fc6f9d74 | 223 | "frr-staticd:staticd", "staticd", args->vrf, |
88fa5104 | 224 | buf_prefix, |
fc6f9d74 RZ |
225 | yang_afi_safi_value2identity(args->afi, |
226 | args->safi), | |
ef4b6b22 | 227 | table_id, distance); |
88fa5104 | 228 | |
229 | nb_cli_enqueue_change(vty, xpath_prefix, NB_OP_CREATE, NULL); | |
230 | ||
231 | /* Tag processing */ | |
232 | snprintf(buf_tag, sizeof(buf_tag), "%u", tag); | |
233 | strlcpy(ab_xpath, xpath_prefix, sizeof(ab_xpath)); | |
234 | strlcat(ab_xpath, FRR_STATIC_ROUTE_PATH_TAG_XPATH, | |
235 | sizeof(ab_xpath)); | |
236 | nb_cli_enqueue_change(vty, ab_xpath, NB_OP_MODIFY, buf_tag); | |
237 | ||
88fa5104 | 238 | /* nexthop processing */ |
239 | ||
240 | snprintf(ab_xpath, sizeof(ab_xpath), | |
fc6f9d74 RZ |
241 | FRR_STATIC_ROUTE_NH_KEY_XPATH, buf_nh_type, |
242 | args->nexthop_vrf, buf_gate_str, args->interface_name); | |
88fa5104 | 243 | strlcpy(xpath_nexthop, xpath_prefix, sizeof(xpath_nexthop)); |
244 | strlcat(xpath_nexthop, ab_xpath, sizeof(xpath_nexthop)); | |
245 | nb_cli_enqueue_change(vty, xpath_nexthop, NB_OP_CREATE, NULL); | |
246 | ||
247 | if (type == STATIC_BLACKHOLE) { | |
248 | strlcpy(ab_xpath, xpath_nexthop, sizeof(ab_xpath)); | |
249 | strlcat(ab_xpath, FRR_STATIC_ROUTE_NH_BH_XPATH, | |
250 | sizeof(ab_xpath)); | |
251 | ||
252 | /* Route flags */ | |
fc6f9d74 RZ |
253 | if (args->flag) { |
254 | switch (args->flag[0]) { | |
88fa5104 | 255 | case 'r': |
256 | bh_type = "reject"; | |
257 | break; | |
258 | case 'b': | |
259 | bh_type = "unspec"; | |
260 | break; | |
261 | case 'N': | |
262 | bh_type = "null"; | |
263 | break; | |
264 | default: | |
265 | bh_type = NULL; | |
266 | break; | |
267 | } | |
268 | nb_cli_enqueue_change(vty, ab_xpath, | |
269 | NB_OP_MODIFY, bh_type); | |
270 | } else { | |
271 | nb_cli_enqueue_change(vty, ab_xpath, | |
272 | NB_OP_MODIFY, "null"); | |
273 | } | |
7e24fdf3 | 274 | } |
88fa5104 | 275 | if (type == STATIC_IPV4_GATEWAY_IFNAME |
276 | || type == STATIC_IPV6_GATEWAY_IFNAME) { | |
277 | strlcpy(ab_xpath, xpath_nexthop, sizeof(ab_xpath)); | |
278 | strlcat(ab_xpath, FRR_STATIC_ROUTE_NH_ONLINK_XPATH, | |
279 | sizeof(ab_xpath)); | |
280 | ||
fc6f9d74 | 281 | if (args->onlink) |
88fa5104 | 282 | nb_cli_enqueue_change(vty, ab_xpath, |
283 | NB_OP_MODIFY, "true"); | |
7e24fdf3 | 284 | else |
88fa5104 | 285 | nb_cli_enqueue_change(vty, ab_xpath, |
286 | NB_OP_MODIFY, "false"); | |
7e24fdf3 | 287 | } |
065276ae SM |
288 | if (type == STATIC_IPV4_GATEWAY |
289 | || type == STATIC_IPV6_GATEWAY | |
290 | || type == STATIC_IPV4_GATEWAY_IFNAME | |
291 | || type == STATIC_IPV6_GATEWAY_IFNAME) { | |
292 | strlcpy(ab_xpath, xpath_nexthop, sizeof(ab_xpath)); | |
293 | strlcat(ab_xpath, FRR_STATIC_ROUTE_NH_COLOR_XPATH, | |
294 | sizeof(ab_xpath)); | |
fc6f9d74 | 295 | if (args->color) |
77463bc8 | 296 | nb_cli_enqueue_change(vty, ab_xpath, |
fc6f9d74 RZ |
297 | NB_OP_MODIFY, |
298 | args->color); | |
065276ae | 299 | } |
fc6f9d74 | 300 | if (args->label) { |
88fa5104 | 301 | /* copy of label string (start) */ |
302 | char *ostr; | |
303 | /* pointer to next segment */ | |
304 | char *nump; | |
305 | ||
306 | strlcpy(xpath_mpls, xpath_nexthop, sizeof(xpath_mpls)); | |
307 | strlcat(xpath_mpls, FRR_STATIC_ROUTE_NH_LABEL_XPATH, | |
308 | sizeof(xpath_mpls)); | |
309 | ||
310 | nb_cli_enqueue_change(vty, xpath_mpls, NB_OP_DESTROY, | |
311 | NULL); | |
312 | ||
fc6f9d74 | 313 | ostr = XSTRDUP(MTYPE_TMP, args->label); |
88fa5104 | 314 | while ((nump = strsep(&ostr, "/")) != NULL) { |
315 | snprintf(ab_xpath, sizeof(ab_xpath), | |
316 | FRR_STATIC_ROUTE_NHLB_KEY_XPATH, | |
317 | label_stack_id); | |
318 | strlcpy(xpath_label, xpath_mpls, | |
319 | sizeof(xpath_label)); | |
320 | strlcat(xpath_label, ab_xpath, | |
321 | sizeof(xpath_label)); | |
322 | nb_cli_enqueue_change(vty, xpath_label, | |
323 | NB_OP_MODIFY, nump); | |
324 | label_stack_id++; | |
325 | } | |
326 | XFREE(MTYPE_TMP, ostr); | |
327 | } else { | |
328 | strlcpy(xpath_mpls, xpath_nexthop, sizeof(xpath_mpls)); | |
329 | strlcat(xpath_mpls, FRR_STATIC_ROUTE_NH_LABEL_XPATH, | |
330 | sizeof(xpath_mpls)); | |
331 | nb_cli_enqueue_change(vty, xpath_mpls, NB_OP_DESTROY, | |
332 | NULL); | |
b1ab2876 | 333 | } |
e280279d RZ |
334 | |
335 | if (args->bfd) { | |
336 | char xpath_bfd[XPATH_MAXLEN]; | |
337 | ||
338 | if (args->bfd_source) { | |
339 | strlcpy(xpath_bfd, xpath_nexthop, | |
340 | sizeof(xpath_bfd)); | |
341 | strlcat(xpath_bfd, | |
342 | "/frr-staticd:bfd-monitoring/source", | |
343 | sizeof(xpath_bfd)); | |
344 | nb_cli_enqueue_change(vty, xpath_bfd, | |
345 | NB_OP_MODIFY, | |
346 | args->bfd_source); | |
347 | } | |
348 | ||
349 | strlcpy(xpath_bfd, xpath_nexthop, sizeof(xpath_bfd)); | |
350 | strlcat(xpath_bfd, | |
351 | "/frr-staticd:bfd-monitoring/multi-hop", | |
352 | sizeof(xpath_bfd)); | |
353 | nb_cli_enqueue_change(vty, xpath_bfd, NB_OP_MODIFY, | |
354 | args->bfd_multi_hop ? "true" | |
355 | : "false"); | |
356 | ||
357 | if (args->bfd_profile) { | |
358 | strlcpy(xpath_bfd, xpath_nexthop, | |
359 | sizeof(xpath_bfd)); | |
360 | strlcat(xpath_bfd, | |
361 | "/frr-staticd:bfd-monitoring/profile", | |
362 | sizeof(xpath_bfd)); | |
363 | nb_cli_enqueue_change(vty, xpath_bfd, | |
364 | NB_OP_MODIFY, | |
365 | args->bfd_profile); | |
366 | } | |
367 | } | |
368 | ||
ae08de9f | 369 | ret = nb_cli_apply_changes(vty, "%s", xpath_prefix); |
7e24fdf3 | 370 | } else { |
fc6f9d74 | 371 | if (args->source) |
88fa5104 | 372 | snprintf(ab_xpath, sizeof(ab_xpath), |
e1ea6b20 | 373 | FRR_DEL_S_ROUTE_SRC_NH_KEY_NO_DISTANCE_XPATH, |
fc6f9d74 | 374 | "frr-staticd:staticd", "staticd", args->vrf, |
88fa5104 | 375 | buf_prefix, |
fc6f9d74 RZ |
376 | yang_afi_safi_value2identity(args->afi, |
377 | args->safi), | |
378 | buf_src_prefix, table_id, buf_nh_type, | |
379 | args->nexthop_vrf, buf_gate_str, | |
380 | args->interface_name); | |
88fa5104 | 381 | else |
382 | snprintf(ab_xpath, sizeof(ab_xpath), | |
e1ea6b20 | 383 | FRR_DEL_S_ROUTE_NH_KEY_NO_DISTANCE_XPATH, |
fc6f9d74 | 384 | "frr-staticd:staticd", "staticd", args->vrf, |
88fa5104 | 385 | buf_prefix, |
fc6f9d74 RZ |
386 | yang_afi_safi_value2identity(args->afi, |
387 | args->safi), | |
388 | table_id, buf_nh_type, args->nexthop_vrf, | |
389 | buf_gate_str, args->interface_name); | |
88fa5104 | 390 | |
391 | dnode = yang_dnode_get(vty->candidate_config->dnode, ab_xpath); | |
ff0e8ee8 | 392 | if (!dnode) { |
65c99282 WC |
393 | vty_out(vty, |
394 | "%% Refusing to remove a non-existent route\n"); | |
f4194241 | 395 | return CMD_SUCCESS; |
ff0e8ee8 | 396 | } |
88fa5104 | 397 | |
398 | dnode = yang_get_subtree_with_no_sibling(dnode); | |
399 | assert(dnode); | |
400 | yang_dnode_get_path(dnode, ab_xpath, XPATH_MAXLEN); | |
401 | ||
402 | nb_cli_enqueue_change(vty, ab_xpath, NB_OP_DESTROY, NULL); | |
ae08de9f | 403 | ret = nb_cli_apply_changes(vty, "%s", ab_xpath); |
7e24fdf3 DS |
404 | } |
405 | ||
88fa5104 | 406 | return ret; |
7e24fdf3 | 407 | } |
7e24fdf3 | 408 | |
7e24fdf3 | 409 | /* Static unicast routes for multicast RPF lookup. */ |
ca77b518 | 410 | DEFPY_YANG (ip_mroute_dist, |
7e24fdf3 | 411 | ip_mroute_dist_cmd, |
e280279d RZ |
412 | "[no] ip mroute A.B.C.D/M$prefix <A.B.C.D$gate|INTERFACE$ifname> [{" |
413 | "(1-255)$distance" | |
414 | "|bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}]" | |
415 | "}]", | |
7e24fdf3 DS |
416 | NO_STR |
417 | IP_STR | |
418 | "Configure static unicast route into MRIB for multicast RPF lookup\n" | |
419 | "IP destination prefix (e.g. 10.0.0.0/8)\n" | |
420 | "Nexthop address\n" | |
421 | "Nexthop interface name\n" | |
e280279d RZ |
422 | "Distance\n" |
423 | BFD_INTEGRATION_STR | |
424 | BFD_INTEGRATION_MULTI_HOP_STR | |
425 | BFD_INTEGRATION_SOURCE_STR | |
426 | BFD_INTEGRATION_SOURCEV4_STR | |
427 | BFD_PROFILE_STR | |
428 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 429 | { |
fc6f9d74 RZ |
430 | struct static_route_args args = { |
431 | .delete = !!no, | |
432 | .afi = AFI_IP, | |
433 | .safi = SAFI_MULTICAST, | |
434 | .prefix = prefix_str, | |
435 | .gateway = gate_str, | |
436 | .interface_name = ifname, | |
437 | .distance = distance_str, | |
e280279d RZ |
438 | .bfd = !!bfd, |
439 | .bfd_multi_hop = !!bfd_multi_hop, | |
440 | .bfd_source = bfd_source_str, | |
441 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
442 | }; |
443 | ||
444 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
445 | } |
446 | ||
447 | /* Static route configuration. */ | |
ca77b518 | 448 | DEFPY_YANG(ip_route_blackhole, |
7e24fdf3 DS |
449 | ip_route_blackhole_cmd, |
450 | "[no] ip route\ | |
451 | <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ | |
452 | <reject|blackhole>$flag \ | |
453 | [{ \ | |
454 | tag (1-4294967295) \ | |
455 | |(1-255)$distance \ | |
456 | |vrf NAME \ | |
457 | |label WORD \ | |
458 | |table (1-4294967295) \ | |
459 | }]", | |
460 | NO_STR IP_STR | |
461 | "Establish static routes\n" | |
462 | "IP destination prefix (e.g. 10.0.0.0/8)\n" | |
463 | "IP destination prefix\n" | |
464 | "IP destination prefix mask\n" | |
465 | "Emit an ICMP unreachable when matched\n" | |
466 | "Silently discard pkts when matched\n" | |
467 | "Set tag for this route\n" | |
468 | "Tag value\n" | |
469 | "Distance value for this route\n" | |
470 | VRF_CMD_HELP_STR | |
471 | MPLS_LABEL_HELPSTR | |
472 | "Table to configure\n" | |
473 | "The table number to configure\n") | |
474 | { | |
fc6f9d74 RZ |
475 | struct static_route_args args = { |
476 | .delete = !!no, | |
477 | .afi = AFI_IP, | |
478 | .safi = SAFI_UNICAST, | |
479 | .prefix = prefix, | |
480 | .prefix_mask = mask_str, | |
481 | .flag = flag, | |
482 | .tag = tag_str, | |
483 | .distance = distance_str, | |
484 | .label = label, | |
485 | .table = table_str, | |
486 | .vrf = vrf, | |
487 | }; | |
488 | ||
489 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
490 | } |
491 | ||
ca77b518 | 492 | DEFPY_YANG(ip_route_blackhole_vrf, |
7e24fdf3 DS |
493 | ip_route_blackhole_vrf_cmd, |
494 | "[no] ip route\ | |
495 | <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ | |
496 | <reject|blackhole>$flag \ | |
497 | [{ \ | |
498 | tag (1-4294967295) \ | |
499 | |(1-255)$distance \ | |
500 | |label WORD \ | |
501 | |table (1-4294967295) \ | |
502 | }]", | |
503 | NO_STR IP_STR | |
504 | "Establish static routes\n" | |
505 | "IP destination prefix (e.g. 10.0.0.0/8)\n" | |
506 | "IP destination prefix\n" | |
507 | "IP destination prefix mask\n" | |
508 | "Emit an ICMP unreachable when matched\n" | |
509 | "Silently discard pkts when matched\n" | |
510 | "Set tag for this route\n" | |
511 | "Tag value\n" | |
512 | "Distance value for this route\n" | |
513 | MPLS_LABEL_HELPSTR | |
514 | "Table to configure\n" | |
515 | "The table number to configure\n") | |
516 | { | |
fc6f9d74 RZ |
517 | struct static_route_args args = { |
518 | .delete = !!no, | |
519 | .afi = AFI_IP, | |
520 | .safi = SAFI_UNICAST, | |
521 | .prefix = prefix, | |
522 | .prefix_mask = mask_str, | |
523 | .flag = flag, | |
524 | .tag = tag_str, | |
525 | .distance = distance_str, | |
526 | .label = label, | |
527 | .table = table_str, | |
528 | .xpath_vrf = true, | |
529 | }; | |
7e24fdf3 | 530 | |
7e24fdf3 DS |
531 | /* |
532 | * Coverity is complaining that prefix could | |
533 | * be dereferenced, but we know that prefix will | |
534 | * valid. Add an assert to make it happy | |
535 | */ | |
fc6f9d74 RZ |
536 | assert(args.prefix); |
537 | ||
538 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
539 | } |
540 | ||
ca77b518 | 541 | DEFPY_YANG(ip_route_address_interface, |
7e24fdf3 DS |
542 | ip_route_address_interface_cmd, |
543 | "[no] ip route\ | |
544 | <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ | |
545 | A.B.C.D$gate \ | |
54a3d7cb | 546 | <INTERFACE|Null0>$ifname \ |
7e24fdf3 DS |
547 | [{ \ |
548 | tag (1-4294967295) \ | |
549 | |(1-255)$distance \ | |
550 | |vrf NAME \ | |
551 | |label WORD \ | |
552 | |table (1-4294967295) \ | |
553 | |nexthop-vrf NAME \ | |
02dc8ba3 | 554 | |onlink$onlink \ |
065276ae | 555 | |color (1-4294967295) \ |
e280279d | 556 | |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \ |
7e24fdf3 DS |
557 | }]", |
558 | NO_STR IP_STR | |
559 | "Establish static routes\n" | |
560 | "IP destination prefix (e.g. 10.0.0.0/8)\n" | |
561 | "IP destination prefix\n" | |
562 | "IP destination prefix mask\n" | |
563 | "IP gateway address\n" | |
54a3d7cb QY |
564 | "IP gateway interface name\n" |
565 | "Null interface\n" | |
7e24fdf3 DS |
566 | "Set tag for this route\n" |
567 | "Tag value\n" | |
568 | "Distance value for this route\n" | |
569 | VRF_CMD_HELP_STR | |
570 | MPLS_LABEL_HELPSTR | |
571 | "Table to configure\n" | |
572 | "The table number to configure\n" | |
02dc8ba3 | 573 | VRF_CMD_HELP_STR |
065276ae SM |
574 | "Treat the nexthop as directly attached to the interface\n" |
575 | "SR-TE color\n" | |
e280279d RZ |
576 | "The SR-TE color to configure\n" |
577 | BFD_INTEGRATION_STR | |
578 | BFD_INTEGRATION_MULTI_HOP_STR | |
579 | BFD_INTEGRATION_SOURCE_STR | |
580 | BFD_INTEGRATION_SOURCEV4_STR | |
581 | BFD_PROFILE_STR | |
582 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 583 | { |
fc6f9d74 RZ |
584 | struct static_route_args args = { |
585 | .delete = !!no, | |
586 | .afi = AFI_IP, | |
587 | .safi = SAFI_UNICAST, | |
588 | .prefix = prefix, | |
589 | .prefix_mask = mask_str, | |
590 | .gateway = gate_str, | |
591 | .interface_name = ifname, | |
592 | .tag = tag_str, | |
593 | .distance = distance_str, | |
594 | .label = label, | |
595 | .table = table_str, | |
596 | .color = color_str, | |
597 | .onlink = !!onlink, | |
598 | .vrf = vrf, | |
599 | .nexthop_vrf = nexthop_vrf, | |
e280279d RZ |
600 | .bfd = !!bfd, |
601 | .bfd_multi_hop = !!bfd_multi_hop, | |
602 | .bfd_source = bfd_source_str, | |
603 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
604 | }; |
605 | ||
606 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
607 | } |
608 | ||
ca77b518 | 609 | DEFPY_YANG(ip_route_address_interface_vrf, |
7e24fdf3 DS |
610 | ip_route_address_interface_vrf_cmd, |
611 | "[no] ip route\ | |
612 | <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ | |
613 | A.B.C.D$gate \ | |
54a3d7cb | 614 | <INTERFACE|Null0>$ifname \ |
7e24fdf3 DS |
615 | [{ \ |
616 | tag (1-4294967295) \ | |
617 | |(1-255)$distance \ | |
618 | |label WORD \ | |
619 | |table (1-4294967295) \ | |
620 | |nexthop-vrf NAME \ | |
02dc8ba3 | 621 | |onlink$onlink \ |
065276ae | 622 | |color (1-4294967295) \ |
e280279d | 623 | |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \ |
065276ae | 624 | }]", |
7e24fdf3 DS |
625 | NO_STR IP_STR |
626 | "Establish static routes\n" | |
627 | "IP destination prefix (e.g. 10.0.0.0/8)\n" | |
628 | "IP destination prefix\n" | |
629 | "IP destination prefix mask\n" | |
630 | "IP gateway address\n" | |
54a3d7cb QY |
631 | "IP gateway interface name\n" |
632 | "Null interface\n" | |
7e24fdf3 DS |
633 | "Set tag for this route\n" |
634 | "Tag value\n" | |
635 | "Distance value for this route\n" | |
636 | MPLS_LABEL_HELPSTR | |
637 | "Table to configure\n" | |
638 | "The table number to configure\n" | |
02dc8ba3 | 639 | VRF_CMD_HELP_STR |
065276ae SM |
640 | "Treat the nexthop as directly attached to the interface\n" |
641 | "SR-TE color\n" | |
e280279d RZ |
642 | "The SR-TE color to configure\n" |
643 | BFD_INTEGRATION_STR | |
644 | BFD_INTEGRATION_MULTI_HOP_STR | |
645 | BFD_INTEGRATION_SOURCE_STR | |
646 | BFD_INTEGRATION_SOURCEV4_STR | |
647 | BFD_PROFILE_STR | |
648 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 649 | { |
fc6f9d74 RZ |
650 | struct static_route_args args = { |
651 | .delete = !!no, | |
652 | .afi = AFI_IP, | |
653 | .safi = SAFI_UNICAST, | |
654 | .prefix = prefix, | |
655 | .prefix_mask = mask_str, | |
656 | .gateway = gate_str, | |
657 | .interface_name = ifname, | |
658 | .tag = tag_str, | |
659 | .distance = distance_str, | |
660 | .label = label, | |
661 | .table = table_str, | |
662 | .color = color_str, | |
663 | .onlink = !!onlink, | |
664 | .xpath_vrf = true, | |
665 | .nexthop_vrf = nexthop_vrf, | |
e280279d RZ |
666 | .bfd = !!bfd, |
667 | .bfd_multi_hop = !!bfd_multi_hop, | |
668 | .bfd_source = bfd_source_str, | |
669 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
670 | }; |
671 | ||
672 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
673 | } |
674 | ||
ca77b518 | 675 | DEFPY_YANG(ip_route, |
7e24fdf3 DS |
676 | ip_route_cmd, |
677 | "[no] ip route\ | |
678 | <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ | |
54a3d7cb | 679 | <A.B.C.D$gate|<INTERFACE|Null0>$ifname> \ |
7e24fdf3 DS |
680 | [{ \ |
681 | tag (1-4294967295) \ | |
682 | |(1-255)$distance \ | |
683 | |vrf NAME \ | |
684 | |label WORD \ | |
685 | |table (1-4294967295) \ | |
686 | |nexthop-vrf NAME \ | |
065276ae | 687 | |color (1-4294967295) \ |
e280279d | 688 | |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \ |
7e24fdf3 DS |
689 | }]", |
690 | NO_STR IP_STR | |
691 | "Establish static routes\n" | |
692 | "IP destination prefix (e.g. 10.0.0.0/8)\n" | |
693 | "IP destination prefix\n" | |
694 | "IP destination prefix mask\n" | |
695 | "IP gateway address\n" | |
696 | "IP gateway interface name\n" | |
54a3d7cb | 697 | "Null interface\n" |
7e24fdf3 DS |
698 | "Set tag for this route\n" |
699 | "Tag value\n" | |
700 | "Distance value for this route\n" | |
701 | VRF_CMD_HELP_STR | |
702 | MPLS_LABEL_HELPSTR | |
703 | "Table to configure\n" | |
704 | "The table number to configure\n" | |
065276ae SM |
705 | VRF_CMD_HELP_STR |
706 | "SR-TE color\n" | |
e280279d RZ |
707 | "The SR-TE color to configure\n" |
708 | BFD_INTEGRATION_STR | |
709 | BFD_INTEGRATION_MULTI_HOP_STR | |
710 | BFD_INTEGRATION_SOURCE_STR | |
711 | BFD_INTEGRATION_SOURCEV4_STR | |
712 | BFD_PROFILE_STR | |
713 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 714 | { |
fc6f9d74 RZ |
715 | struct static_route_args args = { |
716 | .delete = !!no, | |
717 | .afi = AFI_IP, | |
718 | .safi = SAFI_UNICAST, | |
719 | .prefix = prefix, | |
720 | .prefix_mask = mask_str, | |
721 | .gateway = gate_str, | |
722 | .interface_name = ifname, | |
723 | .tag = tag_str, | |
724 | .distance = distance_str, | |
725 | .label = label, | |
726 | .table = table_str, | |
727 | .color = color_str, | |
728 | .vrf = vrf, | |
729 | .nexthop_vrf = nexthop_vrf, | |
e280279d RZ |
730 | .bfd = !!bfd, |
731 | .bfd_multi_hop = !!bfd_multi_hop, | |
732 | .bfd_source = bfd_source_str, | |
733 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
734 | }; |
735 | ||
736 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
737 | } |
738 | ||
ca77b518 | 739 | DEFPY_YANG(ip_route_vrf, |
7e24fdf3 DS |
740 | ip_route_vrf_cmd, |
741 | "[no] ip route\ | |
742 | <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ | |
54a3d7cb | 743 | <A.B.C.D$gate|<INTERFACE|Null0>$ifname> \ |
7e24fdf3 DS |
744 | [{ \ |
745 | tag (1-4294967295) \ | |
746 | |(1-255)$distance \ | |
747 | |label WORD \ | |
748 | |table (1-4294967295) \ | |
749 | |nexthop-vrf NAME \ | |
065276ae | 750 | |color (1-4294967295) \ |
e280279d | 751 | |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \ |
7e24fdf3 DS |
752 | }]", |
753 | NO_STR IP_STR | |
754 | "Establish static routes\n" | |
755 | "IP destination prefix (e.g. 10.0.0.0/8)\n" | |
756 | "IP destination prefix\n" | |
757 | "IP destination prefix mask\n" | |
758 | "IP gateway address\n" | |
759 | "IP gateway interface name\n" | |
54a3d7cb | 760 | "Null interface\n" |
7e24fdf3 DS |
761 | "Set tag for this route\n" |
762 | "Tag value\n" | |
763 | "Distance value for this route\n" | |
764 | MPLS_LABEL_HELPSTR | |
765 | "Table to configure\n" | |
766 | "The table number to configure\n" | |
065276ae SM |
767 | VRF_CMD_HELP_STR |
768 | "SR-TE color\n" | |
e280279d RZ |
769 | "The SR-TE color to configure\n" |
770 | BFD_INTEGRATION_STR | |
771 | BFD_INTEGRATION_MULTI_HOP_STR | |
772 | BFD_INTEGRATION_SOURCE_STR | |
773 | BFD_INTEGRATION_SOURCEV4_STR | |
774 | BFD_PROFILE_STR | |
775 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 776 | { |
fc6f9d74 RZ |
777 | struct static_route_args args = { |
778 | .delete = !!no, | |
779 | .afi = AFI_IP, | |
780 | .safi = SAFI_UNICAST, | |
781 | .prefix = prefix, | |
782 | .prefix_mask = mask_str, | |
783 | .gateway = gate_str, | |
784 | .interface_name = ifname, | |
785 | .tag = tag_str, | |
786 | .distance = distance_str, | |
787 | .label = label, | |
788 | .table = table_str, | |
789 | .color = color_str, | |
790 | .xpath_vrf = true, | |
791 | .nexthop_vrf = nexthop_vrf, | |
e280279d RZ |
792 | .bfd = !!bfd, |
793 | .bfd_multi_hop = !!bfd_multi_hop, | |
794 | .bfd_source = bfd_source_str, | |
795 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
796 | }; |
797 | ||
798 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
799 | } |
800 | ||
ca77b518 | 801 | DEFPY_YANG(ipv6_route_blackhole, |
7e24fdf3 DS |
802 | ipv6_route_blackhole_cmd, |
803 | "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ | |
54a3d7cb | 804 | <reject|blackhole>$flag \ |
7e24fdf3 DS |
805 | [{ \ |
806 | tag (1-4294967295) \ | |
807 | |(1-255)$distance \ | |
808 | |vrf NAME \ | |
809 | |label WORD \ | |
810 | |table (1-4294967295) \ | |
811 | }]", | |
812 | NO_STR | |
813 | IPV6_STR | |
814 | "Establish static routes\n" | |
815 | "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" | |
816 | "IPv6 source-dest route\n" | |
817 | "IPv6 source prefix\n" | |
7e24fdf3 DS |
818 | "Emit an ICMP unreachable when matched\n" |
819 | "Silently discard pkts when matched\n" | |
820 | "Set tag for this route\n" | |
821 | "Tag value\n" | |
822 | "Distance value for this prefix\n" | |
823 | VRF_CMD_HELP_STR | |
824 | MPLS_LABEL_HELPSTR | |
825 | "Table to configure\n" | |
826 | "The table number to configure\n") | |
827 | { | |
fc6f9d74 RZ |
828 | struct static_route_args args = { |
829 | .delete = !!no, | |
830 | .afi = AFI_IP6, | |
831 | .safi = SAFI_UNICAST, | |
832 | .prefix = prefix_str, | |
833 | .source = from_str, | |
834 | .flag = flag, | |
835 | .tag = tag_str, | |
836 | .distance = distance_str, | |
837 | .label = label, | |
838 | .table = table_str, | |
839 | .vrf = vrf, | |
840 | }; | |
841 | ||
842 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
843 | } |
844 | ||
ca77b518 | 845 | DEFPY_YANG(ipv6_route_blackhole_vrf, |
7e24fdf3 DS |
846 | ipv6_route_blackhole_vrf_cmd, |
847 | "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ | |
54a3d7cb | 848 | <reject|blackhole>$flag \ |
7e24fdf3 DS |
849 | [{ \ |
850 | tag (1-4294967295) \ | |
851 | |(1-255)$distance \ | |
852 | |label WORD \ | |
853 | |table (1-4294967295) \ | |
854 | }]", | |
855 | NO_STR | |
856 | IPV6_STR | |
857 | "Establish static routes\n" | |
858 | "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" | |
859 | "IPv6 source-dest route\n" | |
860 | "IPv6 source prefix\n" | |
7e24fdf3 DS |
861 | "Emit an ICMP unreachable when matched\n" |
862 | "Silently discard pkts when matched\n" | |
863 | "Set tag for this route\n" | |
864 | "Tag value\n" | |
865 | "Distance value for this prefix\n" | |
866 | MPLS_LABEL_HELPSTR | |
867 | "Table to configure\n" | |
868 | "The table number to configure\n") | |
869 | { | |
fc6f9d74 RZ |
870 | struct static_route_args args = { |
871 | .delete = !!no, | |
872 | .afi = AFI_IP6, | |
873 | .safi = SAFI_UNICAST, | |
874 | .prefix = prefix_str, | |
875 | .source = from_str, | |
876 | .flag = flag, | |
877 | .tag = tag_str, | |
878 | .distance = distance_str, | |
879 | .label = label, | |
880 | .table = table_str, | |
881 | .xpath_vrf = true, | |
882 | }; | |
7e24fdf3 DS |
883 | |
884 | /* | |
885 | * Coverity is complaining that prefix could | |
886 | * be dereferenced, but we know that prefix will | |
887 | * valid. Add an assert to make it happy | |
888 | */ | |
fc6f9d74 | 889 | assert(args.prefix); |
88fa5104 | 890 | |
fc6f9d74 | 891 | return static_route_nb_run(vty, &args); |
7e24fdf3 DS |
892 | } |
893 | ||
ca77b518 | 894 | DEFPY_YANG(ipv6_route_address_interface, |
7e24fdf3 DS |
895 | ipv6_route_address_interface_cmd, |
896 | "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ | |
897 | X:X::X:X$gate \ | |
54a3d7cb | 898 | <INTERFACE|Null0>$ifname \ |
7e24fdf3 DS |
899 | [{ \ |
900 | tag (1-4294967295) \ | |
901 | |(1-255)$distance \ | |
902 | |vrf NAME \ | |
903 | |label WORD \ | |
904 | |table (1-4294967295) \ | |
905 | |nexthop-vrf NAME \ | |
02dc8ba3 | 906 | |onlink$onlink \ |
065276ae | 907 | |color (1-4294967295) \ |
e280279d | 908 | |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \ |
7e24fdf3 DS |
909 | }]", |
910 | NO_STR | |
911 | IPV6_STR | |
912 | "Establish static routes\n" | |
913 | "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" | |
914 | "IPv6 source-dest route\n" | |
915 | "IPv6 source prefix\n" | |
916 | "IPv6 gateway address\n" | |
917 | "IPv6 gateway interface name\n" | |
54a3d7cb | 918 | "Null interface\n" |
7e24fdf3 DS |
919 | "Set tag for this route\n" |
920 | "Tag value\n" | |
921 | "Distance value for this prefix\n" | |
922 | VRF_CMD_HELP_STR | |
923 | MPLS_LABEL_HELPSTR | |
924 | "Table to configure\n" | |
925 | "The table number to configure\n" | |
02dc8ba3 | 926 | VRF_CMD_HELP_STR |
065276ae SM |
927 | "Treat the nexthop as directly attached to the interface\n" |
928 | "SR-TE color\n" | |
e280279d RZ |
929 | "The SR-TE color to configure\n" |
930 | BFD_INTEGRATION_STR | |
931 | BFD_INTEGRATION_MULTI_HOP_STR | |
932 | BFD_INTEGRATION_SOURCE_STR | |
933 | BFD_INTEGRATION_SOURCEV4_STR | |
934 | BFD_PROFILE_STR | |
935 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 936 | { |
fc6f9d74 RZ |
937 | struct static_route_args args = { |
938 | .delete = !!no, | |
939 | .afi = AFI_IP6, | |
940 | .safi = SAFI_UNICAST, | |
941 | .prefix = prefix_str, | |
942 | .source = from_str, | |
943 | .gateway = gate_str, | |
944 | .interface_name = ifname, | |
945 | .tag = tag_str, | |
946 | .distance = distance_str, | |
947 | .label = label, | |
948 | .table = table_str, | |
949 | .color = color_str, | |
950 | .onlink = !!onlink, | |
951 | .vrf = vrf, | |
952 | .nexthop_vrf = nexthop_vrf, | |
e280279d RZ |
953 | .bfd = !!bfd, |
954 | .bfd_multi_hop = !!bfd_multi_hop, | |
955 | .bfd_source = bfd_source_str, | |
956 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
957 | }; |
958 | ||
959 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
960 | } |
961 | ||
ca77b518 | 962 | DEFPY_YANG(ipv6_route_address_interface_vrf, |
7e24fdf3 DS |
963 | ipv6_route_address_interface_vrf_cmd, |
964 | "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ | |
965 | X:X::X:X$gate \ | |
54a3d7cb | 966 | <INTERFACE|Null0>$ifname \ |
7e24fdf3 DS |
967 | [{ \ |
968 | tag (1-4294967295) \ | |
969 | |(1-255)$distance \ | |
970 | |label WORD \ | |
971 | |table (1-4294967295) \ | |
972 | |nexthop-vrf NAME \ | |
02dc8ba3 | 973 | |onlink$onlink \ |
065276ae | 974 | |color (1-4294967295) \ |
e280279d | 975 | |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \ |
7e24fdf3 DS |
976 | }]", |
977 | NO_STR | |
978 | IPV6_STR | |
979 | "Establish static routes\n" | |
980 | "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" | |
981 | "IPv6 source-dest route\n" | |
982 | "IPv6 source prefix\n" | |
983 | "IPv6 gateway address\n" | |
984 | "IPv6 gateway interface name\n" | |
54a3d7cb | 985 | "Null interface\n" |
7e24fdf3 DS |
986 | "Set tag for this route\n" |
987 | "Tag value\n" | |
988 | "Distance value for this prefix\n" | |
989 | MPLS_LABEL_HELPSTR | |
990 | "Table to configure\n" | |
991 | "The table number to configure\n" | |
02dc8ba3 | 992 | VRF_CMD_HELP_STR |
065276ae SM |
993 | "Treat the nexthop as directly attached to the interface\n" |
994 | "SR-TE color\n" | |
e280279d RZ |
995 | "The SR-TE color to configure\n" |
996 | BFD_INTEGRATION_STR | |
997 | BFD_INTEGRATION_MULTI_HOP_STR | |
998 | BFD_INTEGRATION_SOURCE_STR | |
999 | BFD_INTEGRATION_SOURCEV4_STR | |
1000 | BFD_PROFILE_STR | |
1001 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 1002 | { |
fc6f9d74 RZ |
1003 | struct static_route_args args = { |
1004 | .delete = !!no, | |
1005 | .afi = AFI_IP6, | |
1006 | .safi = SAFI_UNICAST, | |
1007 | .prefix = prefix_str, | |
1008 | .source = from_str, | |
1009 | .gateway = gate_str, | |
1010 | .interface_name = ifname, | |
1011 | .tag = tag_str, | |
1012 | .distance = distance_str, | |
1013 | .label = label, | |
1014 | .table = table_str, | |
1015 | .color = color_str, | |
1016 | .onlink = !!onlink, | |
1017 | .xpath_vrf = true, | |
1018 | .nexthop_vrf = nexthop_vrf, | |
e280279d RZ |
1019 | .bfd = !!bfd, |
1020 | .bfd_multi_hop = !!bfd_multi_hop, | |
1021 | .bfd_source = bfd_source_str, | |
1022 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
1023 | }; |
1024 | ||
1025 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
1026 | } |
1027 | ||
ca77b518 | 1028 | DEFPY_YANG(ipv6_route, |
7e24fdf3 DS |
1029 | ipv6_route_cmd, |
1030 | "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ | |
54a3d7cb | 1031 | <X:X::X:X$gate|<INTERFACE|Null0>$ifname> \ |
7e24fdf3 DS |
1032 | [{ \ |
1033 | tag (1-4294967295) \ | |
1034 | |(1-255)$distance \ | |
1035 | |vrf NAME \ | |
1036 | |label WORD \ | |
1037 | |table (1-4294967295) \ | |
1038 | |nexthop-vrf NAME \ | |
065276ae | 1039 | |color (1-4294967295) \ |
e280279d | 1040 | |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \ |
7e24fdf3 DS |
1041 | }]", |
1042 | NO_STR | |
1043 | IPV6_STR | |
1044 | "Establish static routes\n" | |
1045 | "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" | |
1046 | "IPv6 source-dest route\n" | |
1047 | "IPv6 source prefix\n" | |
1048 | "IPv6 gateway address\n" | |
1049 | "IPv6 gateway interface name\n" | |
54a3d7cb | 1050 | "Null interface\n" |
7e24fdf3 DS |
1051 | "Set tag for this route\n" |
1052 | "Tag value\n" | |
1053 | "Distance value for this prefix\n" | |
1054 | VRF_CMD_HELP_STR | |
1055 | MPLS_LABEL_HELPSTR | |
1056 | "Table to configure\n" | |
1057 | "The table number to configure\n" | |
065276ae SM |
1058 | VRF_CMD_HELP_STR |
1059 | "SR-TE color\n" | |
e280279d RZ |
1060 | "The SR-TE color to configure\n" |
1061 | BFD_INTEGRATION_STR | |
1062 | BFD_INTEGRATION_MULTI_HOP_STR | |
1063 | BFD_INTEGRATION_SOURCE_STR | |
1064 | BFD_INTEGRATION_SOURCEV4_STR | |
1065 | BFD_PROFILE_STR | |
1066 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 1067 | { |
fc6f9d74 RZ |
1068 | struct static_route_args args = { |
1069 | .delete = !!no, | |
1070 | .afi = AFI_IP6, | |
1071 | .safi = SAFI_UNICAST, | |
1072 | .prefix = prefix_str, | |
1073 | .source = from_str, | |
1074 | .gateway = gate_str, | |
1075 | .interface_name = ifname, | |
1076 | .tag = tag_str, | |
1077 | .distance = distance_str, | |
1078 | .label = label, | |
1079 | .table = table_str, | |
1080 | .color = color_str, | |
1081 | .vrf = vrf, | |
1082 | .nexthop_vrf = nexthop_vrf, | |
e280279d RZ |
1083 | .bfd = !!bfd, |
1084 | .bfd_multi_hop = !!bfd_multi_hop, | |
1085 | .bfd_source = bfd_source_str, | |
1086 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
1087 | }; |
1088 | ||
1089 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
1090 | } |
1091 | ||
ca77b518 | 1092 | DEFPY_YANG(ipv6_route_vrf, |
7e24fdf3 DS |
1093 | ipv6_route_vrf_cmd, |
1094 | "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ | |
54a3d7cb | 1095 | <X:X::X:X$gate|<INTERFACE|Null0>$ifname> \ |
7e24fdf3 DS |
1096 | [{ \ |
1097 | tag (1-4294967295) \ | |
1098 | |(1-255)$distance \ | |
1099 | |label WORD \ | |
1100 | |table (1-4294967295) \ | |
1101 | |nexthop-vrf NAME \ | |
065276ae | 1102 | |color (1-4294967295) \ |
e280279d | 1103 | |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \ |
7e24fdf3 DS |
1104 | }]", |
1105 | NO_STR | |
1106 | IPV6_STR | |
1107 | "Establish static routes\n" | |
1108 | "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" | |
1109 | "IPv6 source-dest route\n" | |
1110 | "IPv6 source prefix\n" | |
1111 | "IPv6 gateway address\n" | |
1112 | "IPv6 gateway interface name\n" | |
54a3d7cb | 1113 | "Null interface\n" |
7e24fdf3 DS |
1114 | "Set tag for this route\n" |
1115 | "Tag value\n" | |
1116 | "Distance value for this prefix\n" | |
1117 | MPLS_LABEL_HELPSTR | |
1118 | "Table to configure\n" | |
1119 | "The table number to configure\n" | |
065276ae SM |
1120 | VRF_CMD_HELP_STR |
1121 | "SR-TE color\n" | |
e280279d RZ |
1122 | "The SR-TE color to configure\n" |
1123 | BFD_INTEGRATION_STR | |
1124 | BFD_INTEGRATION_MULTI_HOP_STR | |
1125 | BFD_INTEGRATION_SOURCE_STR | |
1126 | BFD_INTEGRATION_SOURCEV4_STR | |
1127 | BFD_PROFILE_STR | |
1128 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 1129 | { |
fc6f9d74 RZ |
1130 | struct static_route_args args = { |
1131 | .delete = !!no, | |
1132 | .afi = AFI_IP6, | |
1133 | .safi = SAFI_UNICAST, | |
1134 | .prefix = prefix_str, | |
1135 | .source = from_str, | |
1136 | .gateway = gate_str, | |
1137 | .interface_name = ifname, | |
1138 | .tag = tag_str, | |
1139 | .distance = distance_str, | |
1140 | .label = label, | |
1141 | .table = table_str, | |
1142 | .color = color_str, | |
1143 | .xpath_vrf = true, | |
1144 | .nexthop_vrf = nexthop_vrf, | |
e280279d RZ |
1145 | .bfd = !!bfd, |
1146 | .bfd_multi_hop = !!bfd_multi_hop, | |
1147 | .bfd_source = bfd_source_str, | |
1148 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
1149 | }; |
1150 | ||
1151 | return static_route_nb_run(vty, &args); | |
7e24fdf3 | 1152 | } |
6cc73dad | 1153 | |
25605051 | 1154 | void static_cli_show(struct vty *vty, const struct lyd_node *dnode, |
6cc73dad IR |
1155 | bool show_defaults) |
1156 | { | |
1157 | const char *vrf; | |
1158 | ||
1159 | vrf = yang_dnode_get_string(dnode, "../vrf"); | |
1160 | if (strcmp(vrf, VRF_DEFAULT_NAME)) | |
1161 | vty_out(vty, "vrf %s\n", vrf); | |
1162 | } | |
1163 | ||
25605051 | 1164 | void static_cli_show_end(struct vty *vty, const struct lyd_node *dnode) |
6cc73dad IR |
1165 | { |
1166 | const char *vrf; | |
1167 | ||
1168 | vrf = yang_dnode_get_string(dnode, "../vrf"); | |
1169 | if (strcmp(vrf, VRF_DEFAULT_NAME)) | |
1170 | vty_out(vty, "exit-vrf\n"); | |
1171 | } | |
1172 | ||
1173 | struct mpls_label_iter { | |
1174 | struct vty *vty; | |
1175 | bool first; | |
1176 | }; | |
1177 | ||
1178 | static int mpls_label_iter_cb(const struct lyd_node *dnode, void *arg) | |
1179 | { | |
1180 | struct mpls_label_iter *iter = arg; | |
1181 | ||
1182 | if (yang_dnode_exists(dnode, "./label")) { | |
1183 | if (iter->first) | |
1184 | vty_out(iter->vty, " label %s", | |
1185 | yang_dnode_get_string(dnode, "./label")); | |
1186 | else | |
1187 | vty_out(iter->vty, "/%s", | |
1188 | yang_dnode_get_string(dnode, "./label")); | |
1189 | iter->first = false; | |
1190 | } | |
1191 | ||
1192 | return YANG_ITER_CONTINUE; | |
1193 | } | |
1194 | ||
1195 | static void nexthop_cli_show(struct vty *vty, const struct lyd_node *route, | |
1196 | const struct lyd_node *src, | |
1197 | const struct lyd_node *path, | |
1198 | const struct lyd_node *nexthop, bool show_defaults) | |
1199 | { | |
1200 | const char *vrf; | |
1201 | const char *afi_safi; | |
1202 | afi_t afi; | |
1203 | safi_t safi; | |
1204 | enum static_nh_type nh_type; | |
1205 | enum static_blackhole_type bh_type; | |
1206 | uint32_t tag; | |
1207 | uint8_t distance; | |
1208 | struct mpls_label_iter iter; | |
1209 | const char *nexthop_vrf; | |
1210 | uint32_t table_id; | |
1211 | bool onlink; | |
1212 | ||
1213 | vrf = yang_dnode_get_string(route, "../../vrf"); | |
1214 | ||
1215 | afi_safi = yang_dnode_get_string(route, "./afi-safi"); | |
1216 | yang_afi_safi_identity2value(afi_safi, &afi, &safi); | |
1217 | ||
1218 | if (afi == AFI_IP) | |
1219 | vty_out(vty, "%sip", | |
1220 | strmatch(vrf, VRF_DEFAULT_NAME) ? "" : " "); | |
1221 | else | |
1222 | vty_out(vty, "%sipv6", | |
1223 | strmatch(vrf, VRF_DEFAULT_NAME) ? "" : " "); | |
1224 | ||
1225 | if (safi == SAFI_UNICAST) | |
1226 | vty_out(vty, " route"); | |
1227 | else | |
1228 | vty_out(vty, " mroute"); | |
1229 | ||
1230 | vty_out(vty, " %s", yang_dnode_get_string(route, "./prefix")); | |
1231 | ||
1232 | if (src) | |
1233 | vty_out(vty, " from %s", | |
1234 | yang_dnode_get_string(src, "./src-prefix")); | |
1235 | ||
1236 | nh_type = yang_dnode_get_enum(nexthop, "./nh-type"); | |
1237 | switch (nh_type) { | |
1238 | case STATIC_IFNAME: | |
1239 | vty_out(vty, " %s", | |
1240 | yang_dnode_get_string(nexthop, "./interface")); | |
1241 | break; | |
1242 | case STATIC_IPV4_GATEWAY: | |
1243 | case STATIC_IPV6_GATEWAY: | |
1244 | vty_out(vty, " %s", | |
1245 | yang_dnode_get_string(nexthop, "./gateway")); | |
1246 | break; | |
1247 | case STATIC_IPV4_GATEWAY_IFNAME: | |
1248 | case STATIC_IPV6_GATEWAY_IFNAME: | |
1249 | vty_out(vty, " %s", | |
1250 | yang_dnode_get_string(nexthop, "./gateway")); | |
1251 | vty_out(vty, " %s", | |
1252 | yang_dnode_get_string(nexthop, "./interface")); | |
1253 | break; | |
1254 | case STATIC_BLACKHOLE: | |
1255 | bh_type = yang_dnode_get_enum(nexthop, "./bh-type"); | |
1256 | switch (bh_type) { | |
1257 | case STATIC_BLACKHOLE_DROP: | |
1258 | vty_out(vty, " blackhole"); | |
1259 | break; | |
1260 | case STATIC_BLACKHOLE_NULL: | |
1261 | vty_out(vty, " Null0"); | |
1262 | break; | |
1263 | case STATIC_BLACKHOLE_REJECT: | |
1264 | vty_out(vty, " reject"); | |
1265 | break; | |
1266 | } | |
1267 | break; | |
1268 | } | |
1269 | ||
1270 | if (yang_dnode_exists(path, "./tag")) { | |
1271 | tag = yang_dnode_get_uint32(path, "./tag"); | |
1272 | if (tag != 0 || show_defaults) | |
1273 | vty_out(vty, " tag %" PRIu32, tag); | |
1274 | } | |
1275 | ||
1276 | distance = yang_dnode_get_uint8(path, "./distance"); | |
1277 | if (distance != ZEBRA_STATIC_DISTANCE_DEFAULT || show_defaults) | |
1278 | vty_out(vty, " %" PRIu8, distance); | |
1279 | ||
1280 | iter.vty = vty; | |
1281 | iter.first = true; | |
1282 | yang_dnode_iterate(mpls_label_iter_cb, &iter, nexthop, | |
1283 | "./mpls-label-stack/entry"); | |
1284 | ||
1285 | nexthop_vrf = yang_dnode_get_string(nexthop, "./vrf"); | |
1286 | if (strcmp(vrf, nexthop_vrf)) | |
1287 | vty_out(vty, " nexthop-vrf %s", nexthop_vrf); | |
1288 | ||
1289 | table_id = yang_dnode_get_uint32(path, "./table-id"); | |
1290 | if (table_id || show_defaults) | |
1291 | vty_out(vty, " table %" PRIu32, table_id); | |
1292 | ||
1293 | if (yang_dnode_exists(nexthop, "./onlink")) { | |
1294 | onlink = yang_dnode_get_bool(nexthop, "./onlink"); | |
1295 | if (onlink) | |
1296 | vty_out(vty, " onlink"); | |
1297 | } | |
1298 | ||
1299 | if (yang_dnode_exists(nexthop, "./srte-color")) | |
1300 | vty_out(vty, " color %s", | |
1301 | yang_dnode_get_string(nexthop, "./srte-color")); | |
1302 | ||
e280279d RZ |
1303 | if (yang_dnode_exists(nexthop, "./bfd-monitoring")) { |
1304 | const struct lyd_node *bfd_dnode = | |
1305 | yang_dnode_get(nexthop, "./bfd-monitoring"); | |
1306 | ||
1307 | if (yang_dnode_get_bool(bfd_dnode, "./multi-hop")) { | |
1308 | vty_out(vty, " bfd multi-hop"); | |
1309 | ||
1310 | if (yang_dnode_exists(bfd_dnode, "./source")) | |
1311 | vty_out(vty, " source %s", | |
1312 | yang_dnode_get_string(bfd_dnode, | |
1313 | "./source")); | |
1314 | } else | |
1315 | vty_out(vty, " bfd"); | |
1316 | ||
1317 | if (yang_dnode_exists(bfd_dnode, "./profile")) | |
1318 | vty_out(vty, " profile %s", | |
1319 | yang_dnode_get_string(bfd_dnode, "./profile")); | |
1320 | } | |
1321 | ||
6cc73dad IR |
1322 | vty_out(vty, "\n"); |
1323 | } | |
1324 | ||
25605051 | 1325 | void static_nexthop_cli_show(struct vty *vty, const struct lyd_node *dnode, |
6cc73dad IR |
1326 | bool show_defaults) |
1327 | { | |
1328 | const struct lyd_node *path = yang_dnode_get_parent(dnode, "path-list"); | |
1329 | const struct lyd_node *route = | |
1330 | yang_dnode_get_parent(path, "route-list"); | |
1331 | ||
1332 | nexthop_cli_show(vty, route, NULL, path, dnode, show_defaults); | |
1333 | } | |
1334 | ||
25605051 | 1335 | void static_src_nexthop_cli_show(struct vty *vty, const struct lyd_node *dnode, |
6cc73dad IR |
1336 | bool show_defaults) |
1337 | { | |
1338 | const struct lyd_node *path = yang_dnode_get_parent(dnode, "path-list"); | |
1339 | const struct lyd_node *src = yang_dnode_get_parent(path, "src-list"); | |
1340 | const struct lyd_node *route = yang_dnode_get_parent(src, "route-list"); | |
1341 | ||
1342 | nexthop_cli_show(vty, route, src, path, dnode, show_defaults); | |
1343 | } | |
1344 | ||
25605051 IR |
1345 | int static_nexthop_cli_cmp(const struct lyd_node *dnode1, |
1346 | const struct lyd_node *dnode2) | |
6cc73dad IR |
1347 | { |
1348 | enum static_nh_type nh_type1, nh_type2; | |
1349 | struct prefix prefix1, prefix2; | |
1350 | int ret = 0; | |
1351 | ||
1352 | nh_type1 = yang_dnode_get_enum(dnode1, "./nh-type"); | |
1353 | nh_type2 = yang_dnode_get_enum(dnode2, "./nh-type"); | |
1354 | ||
1355 | if (nh_type1 != nh_type2) | |
1356 | return (int)nh_type1 - (int)nh_type2; | |
1357 | ||
1358 | switch (nh_type1) { | |
1359 | case STATIC_IFNAME: | |
1360 | ret = if_cmp_name_func( | |
1361 | yang_dnode_get_string(dnode1, "./interface"), | |
1362 | yang_dnode_get_string(dnode2, "./interface")); | |
1363 | break; | |
1364 | case STATIC_IPV4_GATEWAY: | |
1365 | case STATIC_IPV6_GATEWAY: | |
1366 | yang_dnode_get_prefix(&prefix1, dnode1, "./gateway"); | |
1367 | yang_dnode_get_prefix(&prefix2, dnode2, "./gateway"); | |
1368 | ret = prefix_cmp(&prefix1, &prefix2); | |
1369 | break; | |
1370 | case STATIC_IPV4_GATEWAY_IFNAME: | |
1371 | case STATIC_IPV6_GATEWAY_IFNAME: | |
1372 | yang_dnode_get_prefix(&prefix1, dnode1, "./gateway"); | |
1373 | yang_dnode_get_prefix(&prefix2, dnode2, "./gateway"); | |
1374 | ret = prefix_cmp(&prefix1, &prefix2); | |
1375 | if (!ret) | |
1376 | ret = if_cmp_name_func( | |
1377 | yang_dnode_get_string(dnode1, "./interface"), | |
1378 | yang_dnode_get_string(dnode2, "./interface")); | |
1379 | break; | |
1380 | case STATIC_BLACKHOLE: | |
1381 | /* There's only one blackhole nexthop per route */ | |
1382 | ret = 0; | |
1383 | break; | |
1384 | } | |
1385 | ||
1386 | if (ret) | |
1387 | return ret; | |
1388 | ||
1389 | return if_cmp_name_func(yang_dnode_get_string(dnode1, "./vrf"), | |
1390 | yang_dnode_get_string(dnode2, "./vrf")); | |
1391 | } | |
1392 | ||
25605051 IR |
1393 | int static_route_list_cli_cmp(const struct lyd_node *dnode1, |
1394 | const struct lyd_node *dnode2) | |
6cc73dad IR |
1395 | { |
1396 | const char *afi_safi1, *afi_safi2; | |
1397 | afi_t afi1, afi2; | |
1398 | safi_t safi1, safi2; | |
1399 | struct prefix prefix1, prefix2; | |
1400 | ||
1401 | afi_safi1 = yang_dnode_get_string(dnode1, "./afi-safi"); | |
1402 | yang_afi_safi_identity2value(afi_safi1, &afi1, &safi1); | |
1403 | ||
1404 | afi_safi2 = yang_dnode_get_string(dnode2, "./afi-safi"); | |
1405 | yang_afi_safi_identity2value(afi_safi2, &afi2, &safi2); | |
1406 | ||
1407 | if (afi1 != afi2) | |
1408 | return (int)afi1 - (int)afi2; | |
1409 | ||
1410 | if (safi1 != safi2) | |
1411 | return (int)safi1 - (int)safi2; | |
1412 | ||
1413 | yang_dnode_get_prefix(&prefix1, dnode1, "./prefix"); | |
1414 | yang_dnode_get_prefix(&prefix2, dnode2, "./prefix"); | |
1415 | ||
1416 | return prefix_cmp(&prefix1, &prefix2); | |
1417 | } | |
1418 | ||
25605051 IR |
1419 | int static_src_list_cli_cmp(const struct lyd_node *dnode1, |
1420 | const struct lyd_node *dnode2) | |
6cc73dad IR |
1421 | { |
1422 | struct prefix prefix1, prefix2; | |
1423 | ||
1424 | yang_dnode_get_prefix(&prefix1, dnode1, "./src-prefix"); | |
1425 | yang_dnode_get_prefix(&prefix2, dnode2, "./src-prefix"); | |
1426 | ||
1427 | return prefix_cmp(&prefix1, &prefix2); | |
1428 | } | |
1429 | ||
25605051 IR |
1430 | int static_path_list_cli_cmp(const struct lyd_node *dnode1, |
1431 | const struct lyd_node *dnode2) | |
6cc73dad IR |
1432 | { |
1433 | uint32_t table_id1, table_id2; | |
1434 | uint8_t distance1, distance2; | |
1435 | ||
1436 | table_id1 = yang_dnode_get_uint32(dnode1, "./table-id"); | |
1437 | table_id2 = yang_dnode_get_uint32(dnode2, "./table-id"); | |
1438 | ||
1439 | if (table_id1 != table_id2) | |
1440 | return (int)table_id1 - (int)table_id2; | |
1441 | ||
1442 | distance1 = yang_dnode_get_uint8(dnode1, "./distance"); | |
1443 | distance2 = yang_dnode_get_uint8(dnode2, "./distance"); | |
1444 | ||
1445 | return (int)distance1 - (int)distance2; | |
1446 | } | |
1447 | ||
b2f6ab67 | 1448 | DEFPY_YANG(debug_staticd, debug_staticd_cmd, |
b27499d6 | 1449 | "[no] debug static [{events$events|route$route|bfd$bfd}]", |
b2f6ab67 | 1450 | NO_STR DEBUG_STR STATICD_STR |
1451 | "Debug events\n" | |
b27499d6 PG |
1452 | "Debug route\n" |
1453 | "Debug bfd\n") | |
31ddf3b7 MS |
1454 | { |
1455 | /* If no specific category, change all */ | |
1456 | if (strmatch(argv[argc - 1]->text, "static")) | |
b27499d6 | 1457 | static_debug_set(vty->node, !no, true, true, true); |
31ddf3b7 | 1458 | else |
b27499d6 | 1459 | static_debug_set(vty->node, !no, !!events, !!route, !!bfd); |
7e24fdf3 | 1460 | |
31ddf3b7 MS |
1461 | return CMD_SUCCESS; |
1462 | } | |
1463 | ||
d8c78a8d RZ |
1464 | DEFPY(staticd_show_bfd_routes, staticd_show_bfd_routes_cmd, |
1465 | "show bfd static route [json]$isjson", | |
1466 | SHOW_STR | |
1467 | BFD_INTEGRATION_STR | |
1468 | STATICD_STR | |
1469 | ROUTE_STR | |
1470 | JSON_STR) | |
1471 | { | |
1472 | static_bfd_show(vty, !!isjson); | |
1473 | return CMD_SUCCESS; | |
1474 | } | |
1475 | ||
31ddf3b7 MS |
1476 | DEFUN_NOSH (show_debugging_static, |
1477 | show_debugging_static_cmd, | |
e60b527e DS |
1478 | "show debugging [static]", |
1479 | SHOW_STR | |
1480 | DEBUG_STR | |
1481 | "Static Information\n") | |
1482 | { | |
31ddf3b7 MS |
1483 | vty_out(vty, "Staticd debugging status\n"); |
1484 | ||
1485 | static_debug_status_write(vty); | |
e60b527e | 1486 | |
cf00164b DS |
1487 | cmd_show_lib_debugs(vty); |
1488 | ||
e60b527e DS |
1489 | return CMD_SUCCESS; |
1490 | } | |
1491 | ||
62b346ee | 1492 | static struct cmd_node debug_node = { |
f4b8291f | 1493 | .name = "debug", |
62b346ee DL |
1494 | .node = DEBUG_NODE, |
1495 | .prompt = "", | |
612c2c15 | 1496 | .config_write = static_config_write_debug, |
62b346ee | 1497 | }; |
31ddf3b7 | 1498 | |
7e24fdf3 DS |
1499 | void static_vty_init(void) |
1500 | { | |
612c2c15 | 1501 | install_node(&debug_node); |
31ddf3b7 | 1502 | |
7e24fdf3 DS |
1503 | install_element(CONFIG_NODE, &ip_mroute_dist_cmd); |
1504 | ||
1505 | install_element(CONFIG_NODE, &ip_route_blackhole_cmd); | |
1506 | install_element(VRF_NODE, &ip_route_blackhole_vrf_cmd); | |
1507 | install_element(CONFIG_NODE, &ip_route_address_interface_cmd); | |
1508 | install_element(VRF_NODE, &ip_route_address_interface_vrf_cmd); | |
1509 | install_element(CONFIG_NODE, &ip_route_cmd); | |
1510 | install_element(VRF_NODE, &ip_route_vrf_cmd); | |
1511 | ||
1512 | install_element(CONFIG_NODE, &ipv6_route_blackhole_cmd); | |
1513 | install_element(VRF_NODE, &ipv6_route_blackhole_vrf_cmd); | |
1514 | install_element(CONFIG_NODE, &ipv6_route_address_interface_cmd); | |
1515 | install_element(VRF_NODE, &ipv6_route_address_interface_vrf_cmd); | |
1516 | install_element(CONFIG_NODE, &ipv6_route_cmd); | |
1517 | install_element(VRF_NODE, &ipv6_route_vrf_cmd); | |
1518 | ||
dd73744d | 1519 | install_element(ENABLE_NODE, &show_debugging_static_cmd); |
eed041e8 | 1520 | install_element(ENABLE_NODE, &debug_staticd_cmd); |
31ddf3b7 | 1521 | install_element(CONFIG_NODE, &debug_staticd_cmd); |
d8c78a8d RZ |
1522 | |
1523 | install_element(ENABLE_NODE, &staticd_show_bfd_routes_cmd); | |
7e24fdf3 | 1524 | } |