1 /* Zebra MPLS VTY functions
2 * Copyright (C) 2002 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra 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
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
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
34 #include "zebra/zserv.h"
35 #include "zebra/zebra_vrf.h"
36 #include "zebra/zebra_mpls.h"
37 #include "zebra/zebra_rnh.h"
38 #include "zebra/redistribute.h"
39 #include "zebra/zebra_routemap.h"
40 #include "zebra/zebra_static.h"
42 static int zebra_mpls_transit_lsp(struct vty
*vty
, int add_cmd
,
43 const char *inlabel_str
, const char *gate_str
,
44 const char *outlabel_str
,
47 struct zebra_vrf
*zvrf
;
49 enum nexthop_types_t gtype
;
52 mpls_label_t in_label
, out_label
;
56 "%% MPLS not turned on in kernel, ignoring command\n");
57 return CMD_WARNING_CONFIG_FAILED
;
60 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
62 vty_out(vty
, "%% Default VRF does not exist\n");
63 return CMD_WARNING_CONFIG_FAILED
;
67 vty_out(vty
, "%% No Label Information\n");
68 return CMD_WARNING_CONFIG_FAILED
;
71 out_label
= MPLS_IMP_NULL_LABEL
; /* as initialization */
72 label
= atoi(inlabel_str
);
73 if (!IS_MPLS_UNRESERVED_LABEL(label
)) {
74 vty_out(vty
, "%% Invalid label\n");
75 return CMD_WARNING_CONFIG_FAILED
;
80 vty_out(vty
, "%% No Nexthop Information\n");
81 return CMD_WARNING_CONFIG_FAILED
;
84 vty_out(vty
, "%% No Outgoing label Information\n");
85 return CMD_WARNING_CONFIG_FAILED
;
90 gtype
= NEXTHOP_TYPE_BLACKHOLE
; /* as initialization */
93 /* Gateway is a IPv4 or IPv6 nexthop. */
94 ret
= inet_pton(AF_INET6
, gate_str
, &gate
.ipv6
);
96 gtype
= NEXTHOP_TYPE_IPV6
;
98 ret
= inet_pton(AF_INET
, gate_str
, &gate
.ipv4
);
100 gtype
= NEXTHOP_TYPE_IPV4
;
102 vty_out(vty
, "%% Invalid nexthop\n");
103 return CMD_WARNING_CONFIG_FAILED
;
109 if (outlabel_str
[0] == 'i')
110 out_label
= MPLS_IMP_NULL_LABEL
;
111 else if (outlabel_str
[0] == 'e' && gtype
== NEXTHOP_TYPE_IPV4
)
112 out_label
= MPLS_V4_EXP_NULL_LABEL
;
113 else if (outlabel_str
[0] == 'e' && gtype
== NEXTHOP_TYPE_IPV6
)
114 out_label
= MPLS_V6_EXP_NULL_LABEL
;
116 out_label
= atoi(outlabel_str
);
120 #if defined(HAVE_CUMULUS)
121 /* Check that label value is consistent. */
122 if (!zebra_mpls_lsp_label_consistent(zvrf
, in_label
, out_label
,
124 vty_out(vty
, "%% Label value not consistent\n");
125 return CMD_WARNING_CONFIG_FAILED
;
127 #endif /* HAVE_CUMULUS */
129 ret
= zebra_mpls_static_lsp_add(zvrf
, in_label
, out_label
,
132 ret
= zebra_mpls_static_lsp_del(zvrf
, in_label
, gtype
, &gate
,
136 vty_out(vty
, "%% LSP cannot be %s\n",
137 add_cmd
? "added" : "deleted");
138 return CMD_WARNING_CONFIG_FAILED
;
144 DEFUN (mpls_transit_lsp
,
145 mpls_transit_lsp_cmd
,
146 "mpls lsp (16-1048575) <A.B.C.D|X:X::X:X> <(16-1048575)|explicit-null|implicit-null>",
148 "Establish label switched path\n"
149 "Incoming MPLS label\n"
150 "IPv4 gateway address\n"
151 "IPv6 gateway address\n"
152 "Outgoing MPLS label\n"
153 "Use Explicit-Null label\n"
154 "Use Implicit-Null label\n")
156 return zebra_mpls_transit_lsp(vty
, 1, argv
[2]->arg
, argv
[3]->arg
,
160 DEFUN (no_mpls_transit_lsp
,
161 no_mpls_transit_lsp_cmd
,
162 "no mpls lsp (16-1048575) <A.B.C.D|X:X::X:X>",
165 "Establish label switched path\n"
166 "Incoming MPLS label\n"
167 "IPv4 gateway address\n"
168 "IPv6 gateway address\n")
170 return zebra_mpls_transit_lsp(vty
, 0, argv
[3]->arg
, argv
[4]->arg
, NULL
,
174 ALIAS(no_mpls_transit_lsp
, no_mpls_transit_lsp_out_label_cmd
,
175 "no mpls lsp (16-1048575) <A.B.C.D|X:X::X:X> <(16-1048575)|explicit-null|implicit-null>",
177 "Establish label switched path\n"
178 "Incoming MPLS label\n"
179 "IPv4 gateway address\n"
180 "IPv6 gateway address\n"
181 "Outgoing MPLS label\n"
182 "Use Explicit-Null label\n"
183 "Use Implicit-Null label\n")
185 DEFUN (no_mpls_transit_lsp_all
,
186 no_mpls_transit_lsp_all_cmd
,
187 "no mpls lsp (16-1048575)",
190 "Establish label switched path\n"
191 "Incoming MPLS label\n")
193 return zebra_mpls_transit_lsp(vty
, 0, argv
[3]->arg
, NULL
, NULL
, NULL
);
196 static int zebra_mpls_bind(struct vty
*vty
, int add_cmd
, const char *prefix
,
197 const char *label_str
)
199 struct zebra_vrf
*zvrf
;
204 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
206 vty_out(vty
, "%% Default VRF does not exist\n");
207 return CMD_WARNING_CONFIG_FAILED
;
210 memset(&p
, 0, sizeof(struct prefix
));
211 ret
= str2prefix(prefix
, &p
);
213 vty_out(vty
, "%% Malformed address\n");
214 return CMD_WARNING_CONFIG_FAILED
;
219 vty_out(vty
, "%% No label binding specified\n");
220 return CMD_WARNING_CONFIG_FAILED
;
223 if (!strcmp(label_str
, "implicit-null"))
224 label
= MPLS_IMP_NULL_LABEL
;
225 else if (!strcmp(label_str
, "explicit-null")) {
226 if (p
.family
== AF_INET
)
227 label
= MPLS_V4_EXP_NULL_LABEL
;
229 label
= MPLS_V6_EXP_NULL_LABEL
;
231 label
= atoi(label_str
);
232 if (!IS_MPLS_UNRESERVED_LABEL(label
)) {
233 vty_out(vty
, "%% Invalid label\n");
234 return CMD_WARNING_CONFIG_FAILED
;
236 if (zebra_mpls_label_already_bound(zvrf
, label
)) {
238 "%% Label already bound to a FEC\n");
239 return CMD_WARNING_CONFIG_FAILED
;
243 ret
= zebra_mpls_static_fec_add(zvrf
, &p
, label
);
245 ret
= zebra_mpls_static_fec_del(zvrf
, &p
);
248 vty_out(vty
, "%% FEC to label binding cannot be %s\n",
249 add_cmd
? "added" : "deleted");
250 return CMD_WARNING_CONFIG_FAILED
;
256 DEFUN (mpls_label_bind
,
258 "mpls label bind <A.B.C.D/M|X:X::X:X/M> <(16-1048575)|implicit-null|explicit-null>",
260 "Label configuration\n"
261 "Establish FEC to label binding\n"
264 "MPLS Label to bind\n"
265 "Use Implicit-Null Label\n"
266 "Use Explicit-Null Label\n")
268 return zebra_mpls_bind(vty
, 1, argv
[3]->arg
, argv
[4]->arg
);
271 DEFUN (no_mpls_label_bind
,
272 no_mpls_label_bind_cmd
,
273 "no mpls label bind <A.B.C.D/M|X:X::X:X/M> [<(16-1048575)|implicit-null>]",
276 "Label configuration\n"
277 "Establish FEC to label binding\n"
280 "MPLS Label to bind\n"
281 "Use Implicit-Null Label\n")
283 return zebra_mpls_bind(vty
, 0, argv
[4]->arg
, NULL
);
286 /* MPLS LSP configuration write function. */
287 static int zebra_mpls_config(struct vty
*vty
)
290 struct zebra_vrf
*zvrf
;
292 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
296 write
+= zebra_mpls_write_lsp_config(vty
, zvrf
);
297 write
+= zebra_mpls_write_fec_config(vty
, zvrf
);
298 write
+= zebra_mpls_write_label_block_config(vty
, zvrf
);
302 DEFUN (show_mpls_fec
,
304 "show mpls fec [<A.B.C.D/M|X:X::X:X/M>]",
308 "FEC to display information about\n"
309 "FEC to display information about\n")
311 struct zebra_vrf
*zvrf
;
315 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
320 zebra_mpls_print_fec_table(vty
, zvrf
);
322 memset(&p
, 0, sizeof(struct prefix
));
323 ret
= str2prefix(argv
[3]->arg
, &p
);
325 vty_out(vty
, "%% Malformed address\n");
328 zebra_mpls_print_fec(vty
, zvrf
, &p
);
334 DEFUN (show_mpls_table
,
336 "show mpls table [json]",
342 struct zebra_vrf
*zvrf
;
343 u_char uj
= use_json(argc
, argv
);
345 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
346 zebra_mpls_print_lsp_table(vty
, zvrf
, uj
);
350 DEFUN (show_mpls_table_lsp
,
351 show_mpls_table_lsp_cmd
,
352 "show mpls table (16-1048575) [json]",
356 "LSP to display information about\n"
360 struct zebra_vrf
*zvrf
;
361 u_char uj
= use_json(argc
, argv
);
363 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
364 label
= atoi(argv
[3]->arg
);
365 zebra_mpls_print_lsp(vty
, zvrf
, label
, uj
);
369 DEFUN (show_mpls_status
,
370 show_mpls_status_cmd
,
376 vty_out(vty
, "MPLS support enabled: %s\n",
377 (mpls_enabled
) ? "yes"
378 : "no (mpls kernel extensions not detected)");
382 static int zebra_mpls_global_block(struct vty
*vty
, int add_cmd
,
383 const char *start_label_str
,
384 const char *end_label_str
)
387 u_int32_t start_label
;
389 struct zebra_vrf
*zvrf
;
391 zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
393 vty_out(vty
, "%% Default VRF does not exist\n");
394 return CMD_WARNING_CONFIG_FAILED
;
398 if (!start_label_str
|| !end_label_str
) {
399 vty_out(vty
, "%% Labels not specified\n");
400 return CMD_WARNING_CONFIG_FAILED
;
403 start_label
= atoi(start_label_str
);
404 end_label
= atoi(end_label_str
);
405 if (!IS_MPLS_UNRESERVED_LABEL(start_label
)
406 || !IS_MPLS_UNRESERVED_LABEL(end_label
)) {
407 vty_out(vty
, "%% Invalid label\n");
408 return CMD_WARNING_CONFIG_FAILED
;
410 if (end_label
< start_label
) {
411 vty_out(vty
, "%% End label is less than Start label\n");
412 return CMD_WARNING_CONFIG_FAILED
;
415 ret
= zebra_mpls_label_block_add(zvrf
, start_label
, end_label
);
417 ret
= zebra_mpls_label_block_del(zvrf
);
420 vty_out(vty
, "%% Global label block could not be %s\n",
421 add_cmd
? "added" : "deleted");
422 return CMD_WARNING_CONFIG_FAILED
;
428 DEFUN (mpls_label_global_block
,
429 mpls_label_global_block_cmd
,
430 "mpls label global-block (16-1048575) (16-1048575)",
432 "Label configuration\n"
433 "Configure global label block\n"
437 return zebra_mpls_global_block(vty
, 1, argv
[3]->arg
, argv
[4]->arg
);
440 DEFUN (no_mpls_label_global_block
,
441 no_mpls_label_global_block_cmd
,
442 "no mpls label global-block [(16-1048575) (16-1048575)]",
445 "Label configuration\n"
446 "Configure global label block\n"
450 return zebra_mpls_global_block(vty
, 0, NULL
, NULL
);
453 /* MPLS node for MPLS LSP. */
454 static struct cmd_node mpls_node
= {MPLS_NODE
, "", 1};
457 void zebra_mpls_vty_init(void)
459 install_element(VIEW_NODE
, &show_mpls_status_cmd
);
461 install_node(&mpls_node
, zebra_mpls_config
);
463 install_element(CONFIG_NODE
, &mpls_transit_lsp_cmd
);
464 install_element(CONFIG_NODE
, &no_mpls_transit_lsp_cmd
);
465 install_element(CONFIG_NODE
, &no_mpls_transit_lsp_out_label_cmd
);
466 install_element(CONFIG_NODE
, &no_mpls_transit_lsp_all_cmd
);
468 install_element(CONFIG_NODE
, &mpls_label_bind_cmd
);
469 install_element(CONFIG_NODE
, &no_mpls_label_bind_cmd
);
471 install_element(CONFIG_NODE
, &mpls_label_global_block_cmd
);
472 install_element(CONFIG_NODE
, &no_mpls_label_global_block_cmd
);
474 install_element(VIEW_NODE
, &show_mpls_table_cmd
);
475 install_element(VIEW_NODE
, &show_mpls_table_lsp_cmd
);
476 install_element(VIEW_NODE
, &show_mpls_fec_cmd
);