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