]>
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 | } |
39c329bb CH |
288 | if (type == STATIC_IPV4_GATEWAY || |
289 | type == STATIC_IPV6_GATEWAY || | |
290 | type == STATIC_IPV4_GATEWAY_IFNAME || | |
291 | type == STATIC_IPV6_GATEWAY_IFNAME) { | |
065276ae SM |
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 { |
1462450e CH |
371 | if (args->source) { |
372 | if (args->distance) | |
39c329bb CH |
373 | snprintf(ab_xpath, sizeof(ab_xpath), |
374 | FRR_DEL_S_ROUTE_SRC_NH_KEY_XPATH, | |
375 | "frr-staticd:staticd", "staticd", | |
376 | args->vrf, buf_prefix, | |
377 | yang_afi_safi_value2identity( | |
378 | args->afi, args->safi), | |
379 | buf_src_prefix, table_id, distance, | |
380 | buf_nh_type, args->nexthop_vrf, | |
381 | buf_gate_str, args->interface_name); | |
1462450e CH |
382 | else |
383 | snprintf( | |
384 | ab_xpath, sizeof(ab_xpath), | |
385 | FRR_DEL_S_ROUTE_SRC_NH_KEY_NO_DISTANCE_XPATH, | |
39c329bb CH |
386 | "frr-staticd:staticd", "staticd", |
387 | args->vrf, buf_prefix, | |
388 | yang_afi_safi_value2identity( | |
389 | args->afi, args->safi), | |
1462450e CH |
390 | buf_src_prefix, table_id, buf_nh_type, |
391 | args->nexthop_vrf, buf_gate_str, | |
392 | args->interface_name); | |
393 | } else { | |
394 | if (args->distance) | |
39c329bb CH |
395 | snprintf(ab_xpath, sizeof(ab_xpath), |
396 | FRR_DEL_S_ROUTE_NH_KEY_XPATH, | |
397 | "frr-staticd:staticd", "staticd", | |
398 | args->vrf, buf_prefix, | |
399 | yang_afi_safi_value2identity( | |
400 | args->afi, args->safi), | |
401 | table_id, distance, buf_nh_type, | |
402 | args->nexthop_vrf, buf_gate_str, | |
403 | args->interface_name); | |
1462450e CH |
404 | else |
405 | snprintf( | |
406 | ab_xpath, sizeof(ab_xpath), | |
407 | FRR_DEL_S_ROUTE_NH_KEY_NO_DISTANCE_XPATH, | |
408 | "frr-staticd:staticd", "staticd", | |
409 | args->vrf, buf_prefix, | |
39c329bb CH |
410 | yang_afi_safi_value2identity( |
411 | args->afi, args->safi), | |
412 | table_id, buf_nh_type, | |
413 | args->nexthop_vrf, buf_gate_str, | |
414 | args->interface_name); | |
1462450e | 415 | } |
88fa5104 | 416 | |
417 | dnode = yang_dnode_get(vty->candidate_config->dnode, ab_xpath); | |
ff0e8ee8 | 418 | if (!dnode) { |
65c99282 WC |
419 | vty_out(vty, |
420 | "%% Refusing to remove a non-existent route\n"); | |
f4194241 | 421 | return CMD_SUCCESS; |
ff0e8ee8 | 422 | } |
88fa5104 | 423 | |
424 | dnode = yang_get_subtree_with_no_sibling(dnode); | |
425 | assert(dnode); | |
426 | yang_dnode_get_path(dnode, ab_xpath, XPATH_MAXLEN); | |
427 | ||
428 | nb_cli_enqueue_change(vty, ab_xpath, NB_OP_DESTROY, NULL); | |
ae08de9f | 429 | ret = nb_cli_apply_changes(vty, "%s", ab_xpath); |
7e24fdf3 DS |
430 | } |
431 | ||
88fa5104 | 432 | return ret; |
7e24fdf3 | 433 | } |
7e24fdf3 | 434 | |
7e24fdf3 | 435 | /* Static unicast routes for multicast RPF lookup. */ |
ca77b518 | 436 | DEFPY_YANG (ip_mroute_dist, |
7e24fdf3 | 437 | ip_mroute_dist_cmd, |
e280279d RZ |
438 | "[no] ip mroute A.B.C.D/M$prefix <A.B.C.D$gate|INTERFACE$ifname> [{" |
439 | "(1-255)$distance" | |
440 | "|bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}]" | |
441 | "}]", | |
7e24fdf3 DS |
442 | NO_STR |
443 | IP_STR | |
444 | "Configure static unicast route into MRIB for multicast RPF lookup\n" | |
445 | "IP destination prefix (e.g. 10.0.0.0/8)\n" | |
446 | "Nexthop address\n" | |
447 | "Nexthop interface name\n" | |
e280279d RZ |
448 | "Distance\n" |
449 | BFD_INTEGRATION_STR | |
450 | BFD_INTEGRATION_MULTI_HOP_STR | |
451 | BFD_INTEGRATION_SOURCE_STR | |
452 | BFD_INTEGRATION_SOURCEV4_STR | |
453 | BFD_PROFILE_STR | |
454 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 455 | { |
fc6f9d74 RZ |
456 | struct static_route_args args = { |
457 | .delete = !!no, | |
458 | .afi = AFI_IP, | |
459 | .safi = SAFI_MULTICAST, | |
460 | .prefix = prefix_str, | |
461 | .gateway = gate_str, | |
462 | .interface_name = ifname, | |
463 | .distance = distance_str, | |
e280279d RZ |
464 | .bfd = !!bfd, |
465 | .bfd_multi_hop = !!bfd_multi_hop, | |
466 | .bfd_source = bfd_source_str, | |
467 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
468 | }; |
469 | ||
470 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
471 | } |
472 | ||
473 | /* Static route configuration. */ | |
ca77b518 | 474 | DEFPY_YANG(ip_route_blackhole, |
7e24fdf3 DS |
475 | ip_route_blackhole_cmd, |
476 | "[no] ip route\ | |
477 | <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ | |
478 | <reject|blackhole>$flag \ | |
479 | [{ \ | |
480 | tag (1-4294967295) \ | |
481 | |(1-255)$distance \ | |
482 | |vrf NAME \ | |
483 | |label WORD \ | |
484 | |table (1-4294967295) \ | |
485 | }]", | |
486 | NO_STR IP_STR | |
487 | "Establish static routes\n" | |
488 | "IP destination prefix (e.g. 10.0.0.0/8)\n" | |
489 | "IP destination prefix\n" | |
490 | "IP destination prefix mask\n" | |
491 | "Emit an ICMP unreachable when matched\n" | |
492 | "Silently discard pkts when matched\n" | |
493 | "Set tag for this route\n" | |
494 | "Tag value\n" | |
495 | "Distance value for this route\n" | |
496 | VRF_CMD_HELP_STR | |
497 | MPLS_LABEL_HELPSTR | |
498 | "Table to configure\n" | |
499 | "The table number to configure\n") | |
500 | { | |
fc6f9d74 RZ |
501 | struct static_route_args args = { |
502 | .delete = !!no, | |
503 | .afi = AFI_IP, | |
504 | .safi = SAFI_UNICAST, | |
505 | .prefix = prefix, | |
506 | .prefix_mask = mask_str, | |
507 | .flag = flag, | |
508 | .tag = tag_str, | |
509 | .distance = distance_str, | |
510 | .label = label, | |
511 | .table = table_str, | |
512 | .vrf = vrf, | |
513 | }; | |
514 | ||
515 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
516 | } |
517 | ||
ca77b518 | 518 | DEFPY_YANG(ip_route_blackhole_vrf, |
7e24fdf3 DS |
519 | ip_route_blackhole_vrf_cmd, |
520 | "[no] ip route\ | |
521 | <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ | |
522 | <reject|blackhole>$flag \ | |
523 | [{ \ | |
524 | tag (1-4294967295) \ | |
525 | |(1-255)$distance \ | |
526 | |label WORD \ | |
527 | |table (1-4294967295) \ | |
528 | }]", | |
529 | NO_STR IP_STR | |
530 | "Establish static routes\n" | |
531 | "IP destination prefix (e.g. 10.0.0.0/8)\n" | |
532 | "IP destination prefix\n" | |
533 | "IP destination prefix mask\n" | |
534 | "Emit an ICMP unreachable when matched\n" | |
535 | "Silently discard pkts when matched\n" | |
536 | "Set tag for this route\n" | |
537 | "Tag value\n" | |
538 | "Distance value for this route\n" | |
539 | MPLS_LABEL_HELPSTR | |
540 | "Table to configure\n" | |
541 | "The table number to configure\n") | |
542 | { | |
fc6f9d74 RZ |
543 | struct static_route_args args = { |
544 | .delete = !!no, | |
545 | .afi = AFI_IP, | |
546 | .safi = SAFI_UNICAST, | |
547 | .prefix = prefix, | |
548 | .prefix_mask = mask_str, | |
549 | .flag = flag, | |
550 | .tag = tag_str, | |
551 | .distance = distance_str, | |
552 | .label = label, | |
553 | .table = table_str, | |
554 | .xpath_vrf = true, | |
555 | }; | |
7e24fdf3 | 556 | |
7e24fdf3 DS |
557 | /* |
558 | * Coverity is complaining that prefix could | |
559 | * be dereferenced, but we know that prefix will | |
560 | * valid. Add an assert to make it happy | |
561 | */ | |
fc6f9d74 RZ |
562 | assert(args.prefix); |
563 | ||
564 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
565 | } |
566 | ||
ca77b518 | 567 | DEFPY_YANG(ip_route_address_interface, |
7e24fdf3 DS |
568 | ip_route_address_interface_cmd, |
569 | "[no] ip route\ | |
570 | <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ | |
571 | A.B.C.D$gate \ | |
54a3d7cb | 572 | <INTERFACE|Null0>$ifname \ |
7e24fdf3 DS |
573 | [{ \ |
574 | tag (1-4294967295) \ | |
575 | |(1-255)$distance \ | |
576 | |vrf NAME \ | |
577 | |label WORD \ | |
578 | |table (1-4294967295) \ | |
579 | |nexthop-vrf NAME \ | |
02dc8ba3 | 580 | |onlink$onlink \ |
065276ae | 581 | |color (1-4294967295) \ |
e280279d | 582 | |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \ |
7e24fdf3 DS |
583 | }]", |
584 | NO_STR IP_STR | |
585 | "Establish static routes\n" | |
586 | "IP destination prefix (e.g. 10.0.0.0/8)\n" | |
587 | "IP destination prefix\n" | |
588 | "IP destination prefix mask\n" | |
589 | "IP gateway address\n" | |
54a3d7cb QY |
590 | "IP gateway interface name\n" |
591 | "Null interface\n" | |
7e24fdf3 DS |
592 | "Set tag for this route\n" |
593 | "Tag value\n" | |
594 | "Distance value for this route\n" | |
595 | VRF_CMD_HELP_STR | |
596 | MPLS_LABEL_HELPSTR | |
597 | "Table to configure\n" | |
598 | "The table number to configure\n" | |
02dc8ba3 | 599 | VRF_CMD_HELP_STR |
065276ae SM |
600 | "Treat the nexthop as directly attached to the interface\n" |
601 | "SR-TE color\n" | |
e280279d RZ |
602 | "The SR-TE color to configure\n" |
603 | BFD_INTEGRATION_STR | |
604 | BFD_INTEGRATION_MULTI_HOP_STR | |
605 | BFD_INTEGRATION_SOURCE_STR | |
606 | BFD_INTEGRATION_SOURCEV4_STR | |
607 | BFD_PROFILE_STR | |
608 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 609 | { |
fc6f9d74 RZ |
610 | struct static_route_args args = { |
611 | .delete = !!no, | |
612 | .afi = AFI_IP, | |
613 | .safi = SAFI_UNICAST, | |
614 | .prefix = prefix, | |
615 | .prefix_mask = mask_str, | |
616 | .gateway = gate_str, | |
617 | .interface_name = ifname, | |
618 | .tag = tag_str, | |
619 | .distance = distance_str, | |
620 | .label = label, | |
621 | .table = table_str, | |
622 | .color = color_str, | |
623 | .onlink = !!onlink, | |
624 | .vrf = vrf, | |
625 | .nexthop_vrf = nexthop_vrf, | |
e280279d RZ |
626 | .bfd = !!bfd, |
627 | .bfd_multi_hop = !!bfd_multi_hop, | |
628 | .bfd_source = bfd_source_str, | |
629 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
630 | }; |
631 | ||
632 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
633 | } |
634 | ||
ca77b518 | 635 | DEFPY_YANG(ip_route_address_interface_vrf, |
7e24fdf3 DS |
636 | ip_route_address_interface_vrf_cmd, |
637 | "[no] ip route\ | |
638 | <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ | |
639 | A.B.C.D$gate \ | |
54a3d7cb | 640 | <INTERFACE|Null0>$ifname \ |
7e24fdf3 DS |
641 | [{ \ |
642 | tag (1-4294967295) \ | |
643 | |(1-255)$distance \ | |
644 | |label WORD \ | |
645 | |table (1-4294967295) \ | |
646 | |nexthop-vrf NAME \ | |
02dc8ba3 | 647 | |onlink$onlink \ |
065276ae | 648 | |color (1-4294967295) \ |
e280279d | 649 | |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \ |
065276ae | 650 | }]", |
7e24fdf3 DS |
651 | NO_STR IP_STR |
652 | "Establish static routes\n" | |
653 | "IP destination prefix (e.g. 10.0.0.0/8)\n" | |
654 | "IP destination prefix\n" | |
655 | "IP destination prefix mask\n" | |
656 | "IP gateway address\n" | |
54a3d7cb QY |
657 | "IP gateway interface name\n" |
658 | "Null interface\n" | |
7e24fdf3 DS |
659 | "Set tag for this route\n" |
660 | "Tag value\n" | |
661 | "Distance value for this route\n" | |
662 | MPLS_LABEL_HELPSTR | |
663 | "Table to configure\n" | |
664 | "The table number to configure\n" | |
02dc8ba3 | 665 | VRF_CMD_HELP_STR |
065276ae SM |
666 | "Treat the nexthop as directly attached to the interface\n" |
667 | "SR-TE color\n" | |
e280279d RZ |
668 | "The SR-TE color to configure\n" |
669 | BFD_INTEGRATION_STR | |
670 | BFD_INTEGRATION_MULTI_HOP_STR | |
671 | BFD_INTEGRATION_SOURCE_STR | |
672 | BFD_INTEGRATION_SOURCEV4_STR | |
673 | BFD_PROFILE_STR | |
674 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 675 | { |
fc6f9d74 RZ |
676 | struct static_route_args args = { |
677 | .delete = !!no, | |
678 | .afi = AFI_IP, | |
679 | .safi = SAFI_UNICAST, | |
680 | .prefix = prefix, | |
681 | .prefix_mask = mask_str, | |
682 | .gateway = gate_str, | |
683 | .interface_name = ifname, | |
684 | .tag = tag_str, | |
685 | .distance = distance_str, | |
686 | .label = label, | |
687 | .table = table_str, | |
688 | .color = color_str, | |
689 | .onlink = !!onlink, | |
690 | .xpath_vrf = true, | |
691 | .nexthop_vrf = nexthop_vrf, | |
e280279d RZ |
692 | .bfd = !!bfd, |
693 | .bfd_multi_hop = !!bfd_multi_hop, | |
694 | .bfd_source = bfd_source_str, | |
695 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
696 | }; |
697 | ||
698 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
699 | } |
700 | ||
ca77b518 | 701 | DEFPY_YANG(ip_route, |
7e24fdf3 DS |
702 | ip_route_cmd, |
703 | "[no] ip route\ | |
704 | <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ | |
54a3d7cb | 705 | <A.B.C.D$gate|<INTERFACE|Null0>$ifname> \ |
7e24fdf3 DS |
706 | [{ \ |
707 | tag (1-4294967295) \ | |
708 | |(1-255)$distance \ | |
709 | |vrf NAME \ | |
710 | |label WORD \ | |
711 | |table (1-4294967295) \ | |
712 | |nexthop-vrf NAME \ | |
065276ae | 713 | |color (1-4294967295) \ |
e280279d | 714 | |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \ |
7e24fdf3 DS |
715 | }]", |
716 | NO_STR IP_STR | |
717 | "Establish static routes\n" | |
718 | "IP destination prefix (e.g. 10.0.0.0/8)\n" | |
719 | "IP destination prefix\n" | |
720 | "IP destination prefix mask\n" | |
721 | "IP gateway address\n" | |
722 | "IP gateway interface name\n" | |
54a3d7cb | 723 | "Null interface\n" |
7e24fdf3 DS |
724 | "Set tag for this route\n" |
725 | "Tag value\n" | |
726 | "Distance value for this route\n" | |
727 | VRF_CMD_HELP_STR | |
728 | MPLS_LABEL_HELPSTR | |
729 | "Table to configure\n" | |
730 | "The table number to configure\n" | |
065276ae SM |
731 | VRF_CMD_HELP_STR |
732 | "SR-TE color\n" | |
e280279d RZ |
733 | "The SR-TE color to configure\n" |
734 | BFD_INTEGRATION_STR | |
735 | BFD_INTEGRATION_MULTI_HOP_STR | |
736 | BFD_INTEGRATION_SOURCE_STR | |
737 | BFD_INTEGRATION_SOURCEV4_STR | |
738 | BFD_PROFILE_STR | |
739 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 740 | { |
fc6f9d74 RZ |
741 | struct static_route_args args = { |
742 | .delete = !!no, | |
743 | .afi = AFI_IP, | |
744 | .safi = SAFI_UNICAST, | |
745 | .prefix = prefix, | |
746 | .prefix_mask = mask_str, | |
747 | .gateway = gate_str, | |
748 | .interface_name = ifname, | |
749 | .tag = tag_str, | |
750 | .distance = distance_str, | |
751 | .label = label, | |
752 | .table = table_str, | |
753 | .color = color_str, | |
754 | .vrf = vrf, | |
755 | .nexthop_vrf = nexthop_vrf, | |
e280279d RZ |
756 | .bfd = !!bfd, |
757 | .bfd_multi_hop = !!bfd_multi_hop, | |
758 | .bfd_source = bfd_source_str, | |
759 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
760 | }; |
761 | ||
762 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
763 | } |
764 | ||
ca77b518 | 765 | DEFPY_YANG(ip_route_vrf, |
7e24fdf3 DS |
766 | ip_route_vrf_cmd, |
767 | "[no] ip route\ | |
768 | <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ | |
54a3d7cb | 769 | <A.B.C.D$gate|<INTERFACE|Null0>$ifname> \ |
7e24fdf3 DS |
770 | [{ \ |
771 | tag (1-4294967295) \ | |
772 | |(1-255)$distance \ | |
773 | |label WORD \ | |
774 | |table (1-4294967295) \ | |
775 | |nexthop-vrf NAME \ | |
065276ae | 776 | |color (1-4294967295) \ |
e280279d | 777 | |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \ |
7e24fdf3 DS |
778 | }]", |
779 | NO_STR IP_STR | |
780 | "Establish static routes\n" | |
781 | "IP destination prefix (e.g. 10.0.0.0/8)\n" | |
782 | "IP destination prefix\n" | |
783 | "IP destination prefix mask\n" | |
784 | "IP gateway address\n" | |
785 | "IP gateway interface name\n" | |
54a3d7cb | 786 | "Null interface\n" |
7e24fdf3 DS |
787 | "Set tag for this route\n" |
788 | "Tag value\n" | |
789 | "Distance value for this route\n" | |
790 | MPLS_LABEL_HELPSTR | |
791 | "Table to configure\n" | |
792 | "The table number to configure\n" | |
065276ae SM |
793 | VRF_CMD_HELP_STR |
794 | "SR-TE color\n" | |
e280279d RZ |
795 | "The SR-TE color to configure\n" |
796 | BFD_INTEGRATION_STR | |
797 | BFD_INTEGRATION_MULTI_HOP_STR | |
798 | BFD_INTEGRATION_SOURCE_STR | |
799 | BFD_INTEGRATION_SOURCEV4_STR | |
800 | BFD_PROFILE_STR | |
801 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 802 | { |
fc6f9d74 RZ |
803 | struct static_route_args args = { |
804 | .delete = !!no, | |
805 | .afi = AFI_IP, | |
806 | .safi = SAFI_UNICAST, | |
807 | .prefix = prefix, | |
808 | .prefix_mask = mask_str, | |
809 | .gateway = gate_str, | |
810 | .interface_name = ifname, | |
811 | .tag = tag_str, | |
812 | .distance = distance_str, | |
813 | .label = label, | |
814 | .table = table_str, | |
815 | .color = color_str, | |
816 | .xpath_vrf = true, | |
817 | .nexthop_vrf = nexthop_vrf, | |
e280279d RZ |
818 | .bfd = !!bfd, |
819 | .bfd_multi_hop = !!bfd_multi_hop, | |
820 | .bfd_source = bfd_source_str, | |
821 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
822 | }; |
823 | ||
824 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
825 | } |
826 | ||
ca77b518 | 827 | DEFPY_YANG(ipv6_route_blackhole, |
7e24fdf3 DS |
828 | ipv6_route_blackhole_cmd, |
829 | "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ | |
54a3d7cb | 830 | <reject|blackhole>$flag \ |
7e24fdf3 DS |
831 | [{ \ |
832 | tag (1-4294967295) \ | |
833 | |(1-255)$distance \ | |
834 | |vrf NAME \ | |
835 | |label WORD \ | |
836 | |table (1-4294967295) \ | |
837 | }]", | |
838 | NO_STR | |
839 | IPV6_STR | |
840 | "Establish static routes\n" | |
841 | "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" | |
842 | "IPv6 source-dest route\n" | |
843 | "IPv6 source prefix\n" | |
7e24fdf3 DS |
844 | "Emit an ICMP unreachable when matched\n" |
845 | "Silently discard pkts when matched\n" | |
846 | "Set tag for this route\n" | |
847 | "Tag value\n" | |
848 | "Distance value for this prefix\n" | |
849 | VRF_CMD_HELP_STR | |
850 | MPLS_LABEL_HELPSTR | |
851 | "Table to configure\n" | |
852 | "The table number to configure\n") | |
853 | { | |
fc6f9d74 RZ |
854 | struct static_route_args args = { |
855 | .delete = !!no, | |
856 | .afi = AFI_IP6, | |
857 | .safi = SAFI_UNICAST, | |
858 | .prefix = prefix_str, | |
859 | .source = from_str, | |
860 | .flag = flag, | |
861 | .tag = tag_str, | |
862 | .distance = distance_str, | |
863 | .label = label, | |
864 | .table = table_str, | |
865 | .vrf = vrf, | |
866 | }; | |
867 | ||
868 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
869 | } |
870 | ||
ca77b518 | 871 | DEFPY_YANG(ipv6_route_blackhole_vrf, |
7e24fdf3 DS |
872 | ipv6_route_blackhole_vrf_cmd, |
873 | "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ | |
54a3d7cb | 874 | <reject|blackhole>$flag \ |
7e24fdf3 DS |
875 | [{ \ |
876 | tag (1-4294967295) \ | |
877 | |(1-255)$distance \ | |
878 | |label WORD \ | |
879 | |table (1-4294967295) \ | |
880 | }]", | |
881 | NO_STR | |
882 | IPV6_STR | |
883 | "Establish static routes\n" | |
884 | "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" | |
885 | "IPv6 source-dest route\n" | |
886 | "IPv6 source prefix\n" | |
7e24fdf3 DS |
887 | "Emit an ICMP unreachable when matched\n" |
888 | "Silently discard pkts when matched\n" | |
889 | "Set tag for this route\n" | |
890 | "Tag value\n" | |
891 | "Distance value for this prefix\n" | |
892 | MPLS_LABEL_HELPSTR | |
893 | "Table to configure\n" | |
894 | "The table number to configure\n") | |
895 | { | |
fc6f9d74 RZ |
896 | struct static_route_args args = { |
897 | .delete = !!no, | |
898 | .afi = AFI_IP6, | |
899 | .safi = SAFI_UNICAST, | |
900 | .prefix = prefix_str, | |
901 | .source = from_str, | |
902 | .flag = flag, | |
903 | .tag = tag_str, | |
904 | .distance = distance_str, | |
905 | .label = label, | |
906 | .table = table_str, | |
907 | .xpath_vrf = true, | |
908 | }; | |
7e24fdf3 DS |
909 | |
910 | /* | |
911 | * Coverity is complaining that prefix could | |
912 | * be dereferenced, but we know that prefix will | |
913 | * valid. Add an assert to make it happy | |
914 | */ | |
fc6f9d74 | 915 | assert(args.prefix); |
88fa5104 | 916 | |
fc6f9d74 | 917 | return static_route_nb_run(vty, &args); |
7e24fdf3 DS |
918 | } |
919 | ||
ca77b518 | 920 | DEFPY_YANG(ipv6_route_address_interface, |
7e24fdf3 DS |
921 | ipv6_route_address_interface_cmd, |
922 | "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ | |
923 | X:X::X:X$gate \ | |
54a3d7cb | 924 | <INTERFACE|Null0>$ifname \ |
7e24fdf3 DS |
925 | [{ \ |
926 | tag (1-4294967295) \ | |
927 | |(1-255)$distance \ | |
928 | |vrf NAME \ | |
929 | |label WORD \ | |
930 | |table (1-4294967295) \ | |
931 | |nexthop-vrf NAME \ | |
02dc8ba3 | 932 | |onlink$onlink \ |
065276ae | 933 | |color (1-4294967295) \ |
e280279d | 934 | |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \ |
7e24fdf3 DS |
935 | }]", |
936 | NO_STR | |
937 | IPV6_STR | |
938 | "Establish static routes\n" | |
939 | "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" | |
940 | "IPv6 source-dest route\n" | |
941 | "IPv6 source prefix\n" | |
942 | "IPv6 gateway address\n" | |
943 | "IPv6 gateway interface name\n" | |
54a3d7cb | 944 | "Null interface\n" |
7e24fdf3 DS |
945 | "Set tag for this route\n" |
946 | "Tag value\n" | |
947 | "Distance value for this prefix\n" | |
948 | VRF_CMD_HELP_STR | |
949 | MPLS_LABEL_HELPSTR | |
950 | "Table to configure\n" | |
951 | "The table number to configure\n" | |
02dc8ba3 | 952 | VRF_CMD_HELP_STR |
065276ae SM |
953 | "Treat the nexthop as directly attached to the interface\n" |
954 | "SR-TE color\n" | |
e280279d RZ |
955 | "The SR-TE color to configure\n" |
956 | BFD_INTEGRATION_STR | |
957 | BFD_INTEGRATION_MULTI_HOP_STR | |
958 | BFD_INTEGRATION_SOURCE_STR | |
959 | BFD_INTEGRATION_SOURCEV4_STR | |
960 | BFD_PROFILE_STR | |
961 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 962 | { |
fc6f9d74 RZ |
963 | struct static_route_args args = { |
964 | .delete = !!no, | |
965 | .afi = AFI_IP6, | |
966 | .safi = SAFI_UNICAST, | |
967 | .prefix = prefix_str, | |
968 | .source = from_str, | |
969 | .gateway = gate_str, | |
970 | .interface_name = ifname, | |
971 | .tag = tag_str, | |
972 | .distance = distance_str, | |
973 | .label = label, | |
974 | .table = table_str, | |
975 | .color = color_str, | |
976 | .onlink = !!onlink, | |
977 | .vrf = vrf, | |
978 | .nexthop_vrf = nexthop_vrf, | |
e280279d RZ |
979 | .bfd = !!bfd, |
980 | .bfd_multi_hop = !!bfd_multi_hop, | |
981 | .bfd_source = bfd_source_str, | |
982 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
983 | }; |
984 | ||
985 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
986 | } |
987 | ||
ca77b518 | 988 | DEFPY_YANG(ipv6_route_address_interface_vrf, |
7e24fdf3 DS |
989 | ipv6_route_address_interface_vrf_cmd, |
990 | "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ | |
991 | X:X::X:X$gate \ | |
54a3d7cb | 992 | <INTERFACE|Null0>$ifname \ |
7e24fdf3 DS |
993 | [{ \ |
994 | tag (1-4294967295) \ | |
995 | |(1-255)$distance \ | |
996 | |label WORD \ | |
997 | |table (1-4294967295) \ | |
998 | |nexthop-vrf NAME \ | |
02dc8ba3 | 999 | |onlink$onlink \ |
065276ae | 1000 | |color (1-4294967295) \ |
e280279d | 1001 | |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \ |
7e24fdf3 DS |
1002 | }]", |
1003 | NO_STR | |
1004 | IPV6_STR | |
1005 | "Establish static routes\n" | |
1006 | "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" | |
1007 | "IPv6 source-dest route\n" | |
1008 | "IPv6 source prefix\n" | |
1009 | "IPv6 gateway address\n" | |
1010 | "IPv6 gateway interface name\n" | |
54a3d7cb | 1011 | "Null interface\n" |
7e24fdf3 DS |
1012 | "Set tag for this route\n" |
1013 | "Tag value\n" | |
1014 | "Distance value for this prefix\n" | |
1015 | MPLS_LABEL_HELPSTR | |
1016 | "Table to configure\n" | |
1017 | "The table number to configure\n" | |
02dc8ba3 | 1018 | VRF_CMD_HELP_STR |
065276ae SM |
1019 | "Treat the nexthop as directly attached to the interface\n" |
1020 | "SR-TE color\n" | |
e280279d RZ |
1021 | "The SR-TE color to configure\n" |
1022 | BFD_INTEGRATION_STR | |
1023 | BFD_INTEGRATION_MULTI_HOP_STR | |
1024 | BFD_INTEGRATION_SOURCE_STR | |
1025 | BFD_INTEGRATION_SOURCEV4_STR | |
1026 | BFD_PROFILE_STR | |
1027 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 1028 | { |
fc6f9d74 RZ |
1029 | struct static_route_args args = { |
1030 | .delete = !!no, | |
1031 | .afi = AFI_IP6, | |
1032 | .safi = SAFI_UNICAST, | |
1033 | .prefix = prefix_str, | |
1034 | .source = from_str, | |
1035 | .gateway = gate_str, | |
1036 | .interface_name = ifname, | |
1037 | .tag = tag_str, | |
1038 | .distance = distance_str, | |
1039 | .label = label, | |
1040 | .table = table_str, | |
1041 | .color = color_str, | |
1042 | .onlink = !!onlink, | |
1043 | .xpath_vrf = true, | |
1044 | .nexthop_vrf = nexthop_vrf, | |
e280279d RZ |
1045 | .bfd = !!bfd, |
1046 | .bfd_multi_hop = !!bfd_multi_hop, | |
1047 | .bfd_source = bfd_source_str, | |
1048 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
1049 | }; |
1050 | ||
1051 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
1052 | } |
1053 | ||
ca77b518 | 1054 | DEFPY_YANG(ipv6_route, |
7e24fdf3 DS |
1055 | ipv6_route_cmd, |
1056 | "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ | |
54a3d7cb | 1057 | <X:X::X:X$gate|<INTERFACE|Null0>$ifname> \ |
7e24fdf3 DS |
1058 | [{ \ |
1059 | tag (1-4294967295) \ | |
1060 | |(1-255)$distance \ | |
1061 | |vrf NAME \ | |
1062 | |label WORD \ | |
1063 | |table (1-4294967295) \ | |
1064 | |nexthop-vrf NAME \ | |
065276ae | 1065 | |color (1-4294967295) \ |
e280279d | 1066 | |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \ |
7e24fdf3 DS |
1067 | }]", |
1068 | NO_STR | |
1069 | IPV6_STR | |
1070 | "Establish static routes\n" | |
1071 | "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" | |
1072 | "IPv6 source-dest route\n" | |
1073 | "IPv6 source prefix\n" | |
1074 | "IPv6 gateway address\n" | |
1075 | "IPv6 gateway interface name\n" | |
54a3d7cb | 1076 | "Null interface\n" |
7e24fdf3 DS |
1077 | "Set tag for this route\n" |
1078 | "Tag value\n" | |
1079 | "Distance value for this prefix\n" | |
1080 | VRF_CMD_HELP_STR | |
1081 | MPLS_LABEL_HELPSTR | |
1082 | "Table to configure\n" | |
1083 | "The table number to configure\n" | |
065276ae SM |
1084 | VRF_CMD_HELP_STR |
1085 | "SR-TE color\n" | |
e280279d RZ |
1086 | "The SR-TE color to configure\n" |
1087 | BFD_INTEGRATION_STR | |
1088 | BFD_INTEGRATION_MULTI_HOP_STR | |
1089 | BFD_INTEGRATION_SOURCE_STR | |
1090 | BFD_INTEGRATION_SOURCEV4_STR | |
1091 | BFD_PROFILE_STR | |
1092 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 1093 | { |
fc6f9d74 RZ |
1094 | struct static_route_args args = { |
1095 | .delete = !!no, | |
1096 | .afi = AFI_IP6, | |
1097 | .safi = SAFI_UNICAST, | |
1098 | .prefix = prefix_str, | |
1099 | .source = from_str, | |
1100 | .gateway = gate_str, | |
1101 | .interface_name = ifname, | |
1102 | .tag = tag_str, | |
1103 | .distance = distance_str, | |
1104 | .label = label, | |
1105 | .table = table_str, | |
1106 | .color = color_str, | |
1107 | .vrf = vrf, | |
1108 | .nexthop_vrf = nexthop_vrf, | |
e280279d RZ |
1109 | .bfd = !!bfd, |
1110 | .bfd_multi_hop = !!bfd_multi_hop, | |
1111 | .bfd_source = bfd_source_str, | |
1112 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
1113 | }; |
1114 | ||
1115 | return static_route_nb_run(vty, &args); | |
7e24fdf3 DS |
1116 | } |
1117 | ||
ca77b518 | 1118 | DEFPY_YANG(ipv6_route_vrf, |
7e24fdf3 DS |
1119 | ipv6_route_vrf_cmd, |
1120 | "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ | |
54a3d7cb | 1121 | <X:X::X:X$gate|<INTERFACE|Null0>$ifname> \ |
7e24fdf3 DS |
1122 | [{ \ |
1123 | tag (1-4294967295) \ | |
1124 | |(1-255)$distance \ | |
1125 | |label WORD \ | |
1126 | |table (1-4294967295) \ | |
1127 | |nexthop-vrf NAME \ | |
065276ae | 1128 | |color (1-4294967295) \ |
e280279d | 1129 | |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \ |
7e24fdf3 DS |
1130 | }]", |
1131 | NO_STR | |
1132 | IPV6_STR | |
1133 | "Establish static routes\n" | |
1134 | "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" | |
1135 | "IPv6 source-dest route\n" | |
1136 | "IPv6 source prefix\n" | |
1137 | "IPv6 gateway address\n" | |
1138 | "IPv6 gateway interface name\n" | |
54a3d7cb | 1139 | "Null interface\n" |
7e24fdf3 DS |
1140 | "Set tag for this route\n" |
1141 | "Tag value\n" | |
1142 | "Distance value for this prefix\n" | |
1143 | MPLS_LABEL_HELPSTR | |
1144 | "Table to configure\n" | |
1145 | "The table number to configure\n" | |
065276ae SM |
1146 | VRF_CMD_HELP_STR |
1147 | "SR-TE color\n" | |
e280279d RZ |
1148 | "The SR-TE color to configure\n" |
1149 | BFD_INTEGRATION_STR | |
1150 | BFD_INTEGRATION_MULTI_HOP_STR | |
1151 | BFD_INTEGRATION_SOURCE_STR | |
1152 | BFD_INTEGRATION_SOURCEV4_STR | |
1153 | BFD_PROFILE_STR | |
1154 | BFD_PROFILE_NAME_STR) | |
7e24fdf3 | 1155 | { |
fc6f9d74 RZ |
1156 | struct static_route_args args = { |
1157 | .delete = !!no, | |
1158 | .afi = AFI_IP6, | |
1159 | .safi = SAFI_UNICAST, | |
1160 | .prefix = prefix_str, | |
1161 | .source = from_str, | |
1162 | .gateway = gate_str, | |
1163 | .interface_name = ifname, | |
1164 | .tag = tag_str, | |
1165 | .distance = distance_str, | |
1166 | .label = label, | |
1167 | .table = table_str, | |
1168 | .color = color_str, | |
1169 | .xpath_vrf = true, | |
1170 | .nexthop_vrf = nexthop_vrf, | |
e280279d RZ |
1171 | .bfd = !!bfd, |
1172 | .bfd_multi_hop = !!bfd_multi_hop, | |
1173 | .bfd_source = bfd_source_str, | |
1174 | .bfd_profile = bfd_profile, | |
fc6f9d74 RZ |
1175 | }; |
1176 | ||
1177 | return static_route_nb_run(vty, &args); | |
7e24fdf3 | 1178 | } |
6cc73dad | 1179 | |
25605051 | 1180 | void static_cli_show(struct vty *vty, const struct lyd_node *dnode, |
6cc73dad IR |
1181 | bool show_defaults) |
1182 | { | |
1183 | const char *vrf; | |
1184 | ||
1185 | vrf = yang_dnode_get_string(dnode, "../vrf"); | |
1186 | if (strcmp(vrf, VRF_DEFAULT_NAME)) | |
1187 | vty_out(vty, "vrf %s\n", vrf); | |
1188 | } | |
1189 | ||
25605051 | 1190 | void static_cli_show_end(struct vty *vty, const struct lyd_node *dnode) |
6cc73dad IR |
1191 | { |
1192 | const char *vrf; | |
1193 | ||
1194 | vrf = yang_dnode_get_string(dnode, "../vrf"); | |
1195 | if (strcmp(vrf, VRF_DEFAULT_NAME)) | |
1196 | vty_out(vty, "exit-vrf\n"); | |
1197 | } | |
1198 | ||
1199 | struct mpls_label_iter { | |
1200 | struct vty *vty; | |
1201 | bool first; | |
1202 | }; | |
1203 | ||
1204 | static int mpls_label_iter_cb(const struct lyd_node *dnode, void *arg) | |
1205 | { | |
1206 | struct mpls_label_iter *iter = arg; | |
1207 | ||
1208 | if (yang_dnode_exists(dnode, "./label")) { | |
1209 | if (iter->first) | |
1210 | vty_out(iter->vty, " label %s", | |
1211 | yang_dnode_get_string(dnode, "./label")); | |
1212 | else | |
1213 | vty_out(iter->vty, "/%s", | |
1214 | yang_dnode_get_string(dnode, "./label")); | |
1215 | iter->first = false; | |
1216 | } | |
1217 | ||
1218 | return YANG_ITER_CONTINUE; | |
1219 | } | |
1220 | ||
1221 | static void nexthop_cli_show(struct vty *vty, const struct lyd_node *route, | |
1222 | const struct lyd_node *src, | |
1223 | const struct lyd_node *path, | |
1224 | const struct lyd_node *nexthop, bool show_defaults) | |
1225 | { | |
1226 | const char *vrf; | |
1227 | const char *afi_safi; | |
1228 | afi_t afi; | |
1229 | safi_t safi; | |
1230 | enum static_nh_type nh_type; | |
1231 | enum static_blackhole_type bh_type; | |
1232 | uint32_t tag; | |
1233 | uint8_t distance; | |
1234 | struct mpls_label_iter iter; | |
1235 | const char *nexthop_vrf; | |
1236 | uint32_t table_id; | |
1237 | bool onlink; | |
1238 | ||
1239 | vrf = yang_dnode_get_string(route, "../../vrf"); | |
1240 | ||
1241 | afi_safi = yang_dnode_get_string(route, "./afi-safi"); | |
1242 | yang_afi_safi_identity2value(afi_safi, &afi, &safi); | |
1243 | ||
1244 | if (afi == AFI_IP) | |
1245 | vty_out(vty, "%sip", | |
1246 | strmatch(vrf, VRF_DEFAULT_NAME) ? "" : " "); | |
1247 | else | |
1248 | vty_out(vty, "%sipv6", | |
1249 | strmatch(vrf, VRF_DEFAULT_NAME) ? "" : " "); | |
1250 | ||
1251 | if (safi == SAFI_UNICAST) | |
1252 | vty_out(vty, " route"); | |
1253 | else | |
1254 | vty_out(vty, " mroute"); | |
1255 | ||
1256 | vty_out(vty, " %s", yang_dnode_get_string(route, "./prefix")); | |
1257 | ||
1258 | if (src) | |
1259 | vty_out(vty, " from %s", | |
1260 | yang_dnode_get_string(src, "./src-prefix")); | |
1261 | ||
1262 | nh_type = yang_dnode_get_enum(nexthop, "./nh-type"); | |
1263 | switch (nh_type) { | |
1264 | case STATIC_IFNAME: | |
1265 | vty_out(vty, " %s", | |
1266 | yang_dnode_get_string(nexthop, "./interface")); | |
1267 | break; | |
1268 | case STATIC_IPV4_GATEWAY: | |
1269 | case STATIC_IPV6_GATEWAY: | |
1270 | vty_out(vty, " %s", | |
1271 | yang_dnode_get_string(nexthop, "./gateway")); | |
1272 | break; | |
1273 | case STATIC_IPV4_GATEWAY_IFNAME: | |
1274 | case STATIC_IPV6_GATEWAY_IFNAME: | |
1275 | vty_out(vty, " %s", | |
1276 | yang_dnode_get_string(nexthop, "./gateway")); | |
1277 | vty_out(vty, " %s", | |
1278 | yang_dnode_get_string(nexthop, "./interface")); | |
1279 | break; | |
1280 | case STATIC_BLACKHOLE: | |
1281 | bh_type = yang_dnode_get_enum(nexthop, "./bh-type"); | |
1282 | switch (bh_type) { | |
1283 | case STATIC_BLACKHOLE_DROP: | |
1284 | vty_out(vty, " blackhole"); | |
1285 | break; | |
1286 | case STATIC_BLACKHOLE_NULL: | |
1287 | vty_out(vty, " Null0"); | |
1288 | break; | |
1289 | case STATIC_BLACKHOLE_REJECT: | |
1290 | vty_out(vty, " reject"); | |
1291 | break; | |
1292 | } | |
1293 | break; | |
1294 | } | |
1295 | ||
1296 | if (yang_dnode_exists(path, "./tag")) { | |
1297 | tag = yang_dnode_get_uint32(path, "./tag"); | |
1298 | if (tag != 0 || show_defaults) | |
1299 | vty_out(vty, " tag %" PRIu32, tag); | |
1300 | } | |
1301 | ||
1302 | distance = yang_dnode_get_uint8(path, "./distance"); | |
1303 | if (distance != ZEBRA_STATIC_DISTANCE_DEFAULT || show_defaults) | |
1304 | vty_out(vty, " %" PRIu8, distance); | |
1305 | ||
1306 | iter.vty = vty; | |
1307 | iter.first = true; | |
1308 | yang_dnode_iterate(mpls_label_iter_cb, &iter, nexthop, | |
1309 | "./mpls-label-stack/entry"); | |
1310 | ||
1311 | nexthop_vrf = yang_dnode_get_string(nexthop, "./vrf"); | |
1312 | if (strcmp(vrf, nexthop_vrf)) | |
1313 | vty_out(vty, " nexthop-vrf %s", nexthop_vrf); | |
1314 | ||
1315 | table_id = yang_dnode_get_uint32(path, "./table-id"); | |
1316 | if (table_id || show_defaults) | |
1317 | vty_out(vty, " table %" PRIu32, table_id); | |
1318 | ||
1319 | if (yang_dnode_exists(nexthop, "./onlink")) { | |
1320 | onlink = yang_dnode_get_bool(nexthop, "./onlink"); | |
1321 | if (onlink) | |
1322 | vty_out(vty, " onlink"); | |
1323 | } | |
1324 | ||
1325 | if (yang_dnode_exists(nexthop, "./srte-color")) | |
1326 | vty_out(vty, " color %s", | |
1327 | yang_dnode_get_string(nexthop, "./srte-color")); | |
1328 | ||
e280279d RZ |
1329 | if (yang_dnode_exists(nexthop, "./bfd-monitoring")) { |
1330 | const struct lyd_node *bfd_dnode = | |
1331 | yang_dnode_get(nexthop, "./bfd-monitoring"); | |
1332 | ||
1333 | if (yang_dnode_get_bool(bfd_dnode, "./multi-hop")) { | |
1334 | vty_out(vty, " bfd multi-hop"); | |
1335 | ||
1336 | if (yang_dnode_exists(bfd_dnode, "./source")) | |
1337 | vty_out(vty, " source %s", | |
1338 | yang_dnode_get_string(bfd_dnode, | |
1339 | "./source")); | |
1340 | } else | |
1341 | vty_out(vty, " bfd"); | |
1342 | ||
1343 | if (yang_dnode_exists(bfd_dnode, "./profile")) | |
1344 | vty_out(vty, " profile %s", | |
1345 | yang_dnode_get_string(bfd_dnode, "./profile")); | |
1346 | } | |
1347 | ||
6cc73dad IR |
1348 | vty_out(vty, "\n"); |
1349 | } | |
1350 | ||
25605051 | 1351 | void static_nexthop_cli_show(struct vty *vty, const struct lyd_node *dnode, |
6cc73dad IR |
1352 | bool show_defaults) |
1353 | { | |
1354 | const struct lyd_node *path = yang_dnode_get_parent(dnode, "path-list"); | |
1355 | const struct lyd_node *route = | |
1356 | yang_dnode_get_parent(path, "route-list"); | |
1357 | ||
1358 | nexthop_cli_show(vty, route, NULL, path, dnode, show_defaults); | |
1359 | } | |
1360 | ||
25605051 | 1361 | void static_src_nexthop_cli_show(struct vty *vty, const struct lyd_node *dnode, |
6cc73dad IR |
1362 | bool show_defaults) |
1363 | { | |
1364 | const struct lyd_node *path = yang_dnode_get_parent(dnode, "path-list"); | |
1365 | const struct lyd_node *src = yang_dnode_get_parent(path, "src-list"); | |
1366 | const struct lyd_node *route = yang_dnode_get_parent(src, "route-list"); | |
1367 | ||
1368 | nexthop_cli_show(vty, route, src, path, dnode, show_defaults); | |
1369 | } | |
1370 | ||
25605051 IR |
1371 | int static_nexthop_cli_cmp(const struct lyd_node *dnode1, |
1372 | const struct lyd_node *dnode2) | |
6cc73dad IR |
1373 | { |
1374 | enum static_nh_type nh_type1, nh_type2; | |
1375 | struct prefix prefix1, prefix2; | |
1376 | int ret = 0; | |
1377 | ||
1378 | nh_type1 = yang_dnode_get_enum(dnode1, "./nh-type"); | |
1379 | nh_type2 = yang_dnode_get_enum(dnode2, "./nh-type"); | |
1380 | ||
1381 | if (nh_type1 != nh_type2) | |
1382 | return (int)nh_type1 - (int)nh_type2; | |
1383 | ||
1384 | switch (nh_type1) { | |
1385 | case STATIC_IFNAME: | |
1386 | ret = if_cmp_name_func( | |
1387 | yang_dnode_get_string(dnode1, "./interface"), | |
1388 | yang_dnode_get_string(dnode2, "./interface")); | |
1389 | break; | |
1390 | case STATIC_IPV4_GATEWAY: | |
1391 | case STATIC_IPV6_GATEWAY: | |
1392 | yang_dnode_get_prefix(&prefix1, dnode1, "./gateway"); | |
1393 | yang_dnode_get_prefix(&prefix2, dnode2, "./gateway"); | |
1394 | ret = prefix_cmp(&prefix1, &prefix2); | |
1395 | break; | |
1396 | case STATIC_IPV4_GATEWAY_IFNAME: | |
1397 | case STATIC_IPV6_GATEWAY_IFNAME: | |
1398 | yang_dnode_get_prefix(&prefix1, dnode1, "./gateway"); | |
1399 | yang_dnode_get_prefix(&prefix2, dnode2, "./gateway"); | |
1400 | ret = prefix_cmp(&prefix1, &prefix2); | |
1401 | if (!ret) | |
1402 | ret = if_cmp_name_func( | |
1403 | yang_dnode_get_string(dnode1, "./interface"), | |
1404 | yang_dnode_get_string(dnode2, "./interface")); | |
1405 | break; | |
1406 | case STATIC_BLACKHOLE: | |
1407 | /* There's only one blackhole nexthop per route */ | |
1408 | ret = 0; | |
1409 | break; | |
1410 | } | |
1411 | ||
1412 | if (ret) | |
1413 | return ret; | |
1414 | ||
1415 | return if_cmp_name_func(yang_dnode_get_string(dnode1, "./vrf"), | |
1416 | yang_dnode_get_string(dnode2, "./vrf")); | |
1417 | } | |
1418 | ||
25605051 IR |
1419 | int static_route_list_cli_cmp(const struct lyd_node *dnode1, |
1420 | const struct lyd_node *dnode2) | |
6cc73dad IR |
1421 | { |
1422 | const char *afi_safi1, *afi_safi2; | |
1423 | afi_t afi1, afi2; | |
1424 | safi_t safi1, safi2; | |
1425 | struct prefix prefix1, prefix2; | |
1426 | ||
1427 | afi_safi1 = yang_dnode_get_string(dnode1, "./afi-safi"); | |
1428 | yang_afi_safi_identity2value(afi_safi1, &afi1, &safi1); | |
1429 | ||
1430 | afi_safi2 = yang_dnode_get_string(dnode2, "./afi-safi"); | |
1431 | yang_afi_safi_identity2value(afi_safi2, &afi2, &safi2); | |
1432 | ||
1433 | if (afi1 != afi2) | |
1434 | return (int)afi1 - (int)afi2; | |
1435 | ||
1436 | if (safi1 != safi2) | |
1437 | return (int)safi1 - (int)safi2; | |
1438 | ||
1439 | yang_dnode_get_prefix(&prefix1, dnode1, "./prefix"); | |
1440 | yang_dnode_get_prefix(&prefix2, dnode2, "./prefix"); | |
1441 | ||
1442 | return prefix_cmp(&prefix1, &prefix2); | |
1443 | } | |
1444 | ||
25605051 IR |
1445 | int static_src_list_cli_cmp(const struct lyd_node *dnode1, |
1446 | const struct lyd_node *dnode2) | |
6cc73dad IR |
1447 | { |
1448 | struct prefix prefix1, prefix2; | |
1449 | ||
1450 | yang_dnode_get_prefix(&prefix1, dnode1, "./src-prefix"); | |
1451 | yang_dnode_get_prefix(&prefix2, dnode2, "./src-prefix"); | |
1452 | ||
1453 | return prefix_cmp(&prefix1, &prefix2); | |
1454 | } | |
1455 | ||
25605051 IR |
1456 | int static_path_list_cli_cmp(const struct lyd_node *dnode1, |
1457 | const struct lyd_node *dnode2) | |
6cc73dad IR |
1458 | { |
1459 | uint32_t table_id1, table_id2; | |
1460 | uint8_t distance1, distance2; | |
1461 | ||
1462 | table_id1 = yang_dnode_get_uint32(dnode1, "./table-id"); | |
1463 | table_id2 = yang_dnode_get_uint32(dnode2, "./table-id"); | |
1464 | ||
1465 | if (table_id1 != table_id2) | |
1466 | return (int)table_id1 - (int)table_id2; | |
1467 | ||
1468 | distance1 = yang_dnode_get_uint8(dnode1, "./distance"); | |
1469 | distance2 = yang_dnode_get_uint8(dnode2, "./distance"); | |
1470 | ||
1471 | return (int)distance1 - (int)distance2; | |
1472 | } | |
1473 | ||
b2f6ab67 | 1474 | DEFPY_YANG(debug_staticd, debug_staticd_cmd, |
b27499d6 | 1475 | "[no] debug static [{events$events|route$route|bfd$bfd}]", |
b2f6ab67 | 1476 | NO_STR DEBUG_STR STATICD_STR |
1477 | "Debug events\n" | |
b27499d6 PG |
1478 | "Debug route\n" |
1479 | "Debug bfd\n") | |
31ddf3b7 | 1480 | { |
d1e85e36 | 1481 | #ifndef INCLUDE_MGMTD_CMDDEFS_ONLY |
31ddf3b7 MS |
1482 | /* If no specific category, change all */ |
1483 | if (strmatch(argv[argc - 1]->text, "static")) | |
b27499d6 | 1484 | static_debug_set(vty->node, !no, true, true, true); |
31ddf3b7 | 1485 | else |
b27499d6 | 1486 | static_debug_set(vty->node, !no, !!events, !!route, !!bfd); |
d1e85e36 | 1487 | #endif /* ifndef INCLUDE_MGMTD_CMDDEFS_ONLY */ |
7e24fdf3 | 1488 | |
31ddf3b7 MS |
1489 | return CMD_SUCCESS; |
1490 | } | |
1491 | ||
d1e85e36 | 1492 | #ifndef INCLUDE_MGMTD_CMDDEFS_ONLY |
d8c78a8d RZ |
1493 | DEFPY(staticd_show_bfd_routes, staticd_show_bfd_routes_cmd, |
1494 | "show bfd static route [json]$isjson", | |
1495 | SHOW_STR | |
1496 | BFD_INTEGRATION_STR | |
1497 | STATICD_STR | |
1498 | ROUTE_STR | |
1499 | JSON_STR) | |
1500 | { | |
1501 | static_bfd_show(vty, !!isjson); | |
1502 | return CMD_SUCCESS; | |
1503 | } | |
1504 | ||
31ddf3b7 MS |
1505 | DEFUN_NOSH (show_debugging_static, |
1506 | show_debugging_static_cmd, | |
e60b527e DS |
1507 | "show debugging [static]", |
1508 | SHOW_STR | |
1509 | DEBUG_STR | |
1510 | "Static Information\n") | |
1511 | { | |
31ddf3b7 MS |
1512 | vty_out(vty, "Staticd debugging status\n"); |
1513 | ||
1514 | static_debug_status_write(vty); | |
e60b527e | 1515 | |
cf00164b DS |
1516 | cmd_show_lib_debugs(vty); |
1517 | ||
e60b527e DS |
1518 | return CMD_SUCCESS; |
1519 | } | |
1520 | ||
62b346ee | 1521 | static struct cmd_node debug_node = { |
f4b8291f | 1522 | .name = "debug", |
62b346ee DL |
1523 | .node = DEBUG_NODE, |
1524 | .prompt = "", | |
612c2c15 | 1525 | .config_write = static_config_write_debug, |
62b346ee | 1526 | }; |
31ddf3b7 | 1527 | |
d1e85e36 CH |
1528 | #endif /* ifndef INCLUDE_MGMTD_CMDDEFS_ONLY */ |
1529 | ||
7e24fdf3 DS |
1530 | void static_vty_init(void) |
1531 | { | |
d1e85e36 | 1532 | #ifndef INCLUDE_MGMTD_CMDDEFS_ONLY |
612c2c15 | 1533 | install_node(&debug_node); |
d1e85e36 CH |
1534 | install_element(ENABLE_NODE, &show_debugging_static_cmd); |
1535 | install_element(ENABLE_NODE, &staticd_show_bfd_routes_cmd); | |
1536 | #endif /* ifndef INCLUDE_MGMTD_CMDDEFS_ONLY */ | |
31ddf3b7 | 1537 | |
7e24fdf3 DS |
1538 | install_element(CONFIG_NODE, &ip_mroute_dist_cmd); |
1539 | ||
1540 | install_element(CONFIG_NODE, &ip_route_blackhole_cmd); | |
1541 | install_element(VRF_NODE, &ip_route_blackhole_vrf_cmd); | |
1542 | install_element(CONFIG_NODE, &ip_route_address_interface_cmd); | |
1543 | install_element(VRF_NODE, &ip_route_address_interface_vrf_cmd); | |
1544 | install_element(CONFIG_NODE, &ip_route_cmd); | |
1545 | install_element(VRF_NODE, &ip_route_vrf_cmd); | |
1546 | ||
1547 | install_element(CONFIG_NODE, &ipv6_route_blackhole_cmd); | |
1548 | install_element(VRF_NODE, &ipv6_route_blackhole_vrf_cmd); | |
1549 | install_element(CONFIG_NODE, &ipv6_route_address_interface_cmd); | |
1550 | install_element(VRF_NODE, &ipv6_route_address_interface_vrf_cmd); | |
1551 | install_element(CONFIG_NODE, &ipv6_route_cmd); | |
1552 | install_element(VRF_NODE, &ipv6_route_vrf_cmd); | |
1553 | ||
eed041e8 | 1554 | install_element(ENABLE_NODE, &debug_staticd_cmd); |
31ddf3b7 | 1555 | install_element(CONFIG_NODE, &debug_staticd_cmd); |
7e24fdf3 | 1556 | } |