]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_mpls_vty.c
isisd: implement the 'lsp-too-large' notification
[mirror_frr.git] / zebra / zebra_mpls_vty.c
CommitLineData
41675b4c
RW
1/* Zebra MPLS VTY functions
2 * Copyright (C) 2002 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
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
9 * later version.
10 *
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.
15 *
896014f4
DL
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
41675b4c
RW
19 */
20
21#include <zebra.h>
22
41675b4c
RW
23#include "memory.h"
24#include "if.h"
25#include "prefix.h"
26#include "command.h"
27#include "table.h"
28#include "rib.h"
29#include "nexthop.h"
30#include "vrf.h"
31#include "mpls.h"
32#include "lib/json.h"
33
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"
41675b4c 40
d62a17ae 41static int zebra_mpls_transit_lsp(struct vty *vty, int add_cmd,
42 const char *inlabel_str, const char *gate_str,
43 const char *outlabel_str,
44 const char *flag_str)
41675b4c 45{
d62a17ae 46 struct zebra_vrf *zvrf;
47 int ret;
48 enum nexthop_types_t gtype;
49 union g_addr gate;
50 mpls_label_t label;
51 mpls_label_t in_label, out_label;
52
53 if (!mpls_enabled) {
54 vty_out(vty,
55 "%% MPLS not turned on in kernel, ignoring command\n");
56 return CMD_WARNING_CONFIG_FAILED;
57 }
58
59 zvrf = vrf_info_lookup(VRF_DEFAULT);
60 if (!zvrf) {
61 vty_out(vty, "%% Default VRF does not exist\n");
62 return CMD_WARNING_CONFIG_FAILED;
63 }
64
65 if (!inlabel_str) {
66 vty_out(vty, "%% No Label Information\n");
67 return CMD_WARNING_CONFIG_FAILED;
68 }
69
70e98a7f 70 out_label = MPLS_LABEL_IMPLICIT_NULL; /* as initialization */
d62a17ae 71 label = atoi(inlabel_str);
72 if (!IS_MPLS_UNRESERVED_LABEL(label)) {
73 vty_out(vty, "%% Invalid label\n");
74 return CMD_WARNING_CONFIG_FAILED;
75 }
76
77 if (add_cmd) {
78 if (!gate_str) {
79 vty_out(vty, "%% No Nexthop Information\n");
80 return CMD_WARNING_CONFIG_FAILED;
81 }
82 if (!outlabel_str) {
83 vty_out(vty, "%% No Outgoing label Information\n");
84 return CMD_WARNING_CONFIG_FAILED;
85 }
86 }
87
88 in_label = label;
89 gtype = NEXTHOP_TYPE_BLACKHOLE; /* as initialization */
90
91 if (gate_str) {
92 /* Gateway is a IPv4 or IPv6 nexthop. */
93 ret = inet_pton(AF_INET6, gate_str, &gate.ipv6);
94 if (ret)
95 gtype = NEXTHOP_TYPE_IPV6;
96 else {
97 ret = inet_pton(AF_INET, gate_str, &gate.ipv4);
98 if (ret)
99 gtype = NEXTHOP_TYPE_IPV4;
100 else {
101 vty_out(vty, "%% Invalid nexthop\n");
102 return CMD_WARNING_CONFIG_FAILED;
103 }
104 }
105 }
106
107 if (outlabel_str) {
108 if (outlabel_str[0] == 'i')
70e98a7f 109 out_label = MPLS_LABEL_IMPLICIT_NULL;
d62a17ae 110 else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV4)
70e98a7f 111 out_label = MPLS_LABEL_IPV4_EXPLICIT_NULL;
d62a17ae 112 else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV6)
70e98a7f 113 out_label = MPLS_LABEL_IPV6_EXPLICIT_NULL;
d62a17ae 114 else
115 out_label = atoi(outlabel_str);
116 }
117
118 if (add_cmd) {
41675b4c 119#if defined(HAVE_CUMULUS)
d62a17ae 120 /* Check that label value is consistent. */
121 if (!zebra_mpls_lsp_label_consistent(zvrf, in_label, out_label,
122 gtype, &gate, 0)) {
123 vty_out(vty, "%% Label value not consistent\n");
124 return CMD_WARNING_CONFIG_FAILED;
125 }
41675b4c
RW
126#endif /* HAVE_CUMULUS */
127
d62a17ae 128 ret = zebra_mpls_static_lsp_add(zvrf, in_label, out_label,
129 gtype, &gate, 0);
130 } else
131 ret = zebra_mpls_static_lsp_del(zvrf, in_label, gtype, &gate,
132 0);
41675b4c 133
d62a17ae 134 if (ret) {
135 vty_out(vty, "%% LSP cannot be %s\n",
136 add_cmd ? "added" : "deleted");
137 return CMD_WARNING_CONFIG_FAILED;
138 }
41675b4c 139
d62a17ae 140 return CMD_SUCCESS;
41675b4c
RW
141}
142
143DEFUN (mpls_transit_lsp,
144 mpls_transit_lsp_cmd,
e52702f2 145 "mpls lsp (16-1048575) <A.B.C.D|X:X::X:X> <(16-1048575)|explicit-null|implicit-null>",
41675b4c
RW
146 MPLS_STR
147 "Establish label switched path\n"
148 "Incoming MPLS label\n"
149 "IPv4 gateway address\n"
150 "IPv6 gateway address\n"
151 "Outgoing MPLS label\n"
e64f3c32 152 "Use Explicit-Null label\n"
41675b4c
RW
153 "Use Implicit-Null label\n")
154{
d62a17ae 155 return zebra_mpls_transit_lsp(vty, 1, argv[2]->arg, argv[3]->arg,
156 argv[4]->arg, NULL);
41675b4c
RW
157}
158
159DEFUN (no_mpls_transit_lsp,
160 no_mpls_transit_lsp_cmd,
e52702f2 161 "no mpls lsp (16-1048575) <A.B.C.D|X:X::X:X>",
41675b4c
RW
162 NO_STR
163 MPLS_STR
164 "Establish label switched path\n"
165 "Incoming MPLS label\n"
166 "IPv4 gateway address\n"
167 "IPv6 gateway address\n")
168{
d62a17ae 169 return zebra_mpls_transit_lsp(vty, 0, argv[3]->arg, argv[4]->arg, NULL,
170 NULL);
41675b4c
RW
171}
172
d62a17ae 173ALIAS(no_mpls_transit_lsp, no_mpls_transit_lsp_out_label_cmd,
174 "no mpls lsp (16-1048575) <A.B.C.D|X:X::X:X> <(16-1048575)|explicit-null|implicit-null>",
175 NO_STR MPLS_STR
176 "Establish label switched path\n"
177 "Incoming MPLS label\n"
178 "IPv4 gateway address\n"
179 "IPv6 gateway address\n"
180 "Outgoing MPLS label\n"
181 "Use Explicit-Null label\n"
182 "Use Implicit-Null label\n")
183
41675b4c
RW
184DEFUN (no_mpls_transit_lsp_all,
185 no_mpls_transit_lsp_all_cmd,
e52702f2 186 "no mpls lsp (16-1048575)",
41675b4c
RW
187 NO_STR
188 MPLS_STR
189 "Establish label switched path\n"
190 "Incoming MPLS label\n")
191{
d62a17ae 192 return zebra_mpls_transit_lsp(vty, 0, argv[3]->arg, NULL, NULL, NULL);
41675b4c
RW
193}
194
d62a17ae 195static int zebra_mpls_bind(struct vty *vty, int add_cmd, const char *prefix,
196 const char *label_str)
f31e084c 197{
d62a17ae 198 struct zebra_vrf *zvrf;
199 struct prefix p;
d7c0a89a 200 uint32_t label;
d62a17ae 201 int ret;
202
203 zvrf = vrf_info_lookup(VRF_DEFAULT);
204 if (!zvrf) {
205 vty_out(vty, "%% Default VRF does not exist\n");
206 return CMD_WARNING_CONFIG_FAILED;
207 }
208
209 memset(&p, 0, sizeof(struct prefix));
210 ret = str2prefix(prefix, &p);
211 if (ret <= 0) {
212 vty_out(vty, "%% Malformed address\n");
213 return CMD_WARNING_CONFIG_FAILED;
214 }
215
216 if (add_cmd) {
217 if (!label_str) {
218 vty_out(vty, "%% No label binding specified\n");
219 return CMD_WARNING_CONFIG_FAILED;
220 }
221
222 if (!strcmp(label_str, "implicit-null"))
70e98a7f 223 label = MPLS_LABEL_IMPLICIT_NULL;
d62a17ae 224 else if (!strcmp(label_str, "explicit-null")) {
225 if (p.family == AF_INET)
70e98a7f 226 label = MPLS_LABEL_IPV4_EXPLICIT_NULL;
d62a17ae 227 else
70e98a7f 228 label = MPLS_LABEL_IPV6_EXPLICIT_NULL;
d62a17ae 229 } else {
230 label = atoi(label_str);
231 if (!IS_MPLS_UNRESERVED_LABEL(label)) {
232 vty_out(vty, "%% Invalid label\n");
233 return CMD_WARNING_CONFIG_FAILED;
234 }
235 if (zebra_mpls_label_already_bound(zvrf, label)) {
236 vty_out(vty,
237 "%% Label already bound to a FEC\n");
238 return CMD_WARNING_CONFIG_FAILED;
239 }
240 }
241
242 ret = zebra_mpls_static_fec_add(zvrf, &p, label);
243 } else
244 ret = zebra_mpls_static_fec_del(zvrf, &p);
245
246 if (ret) {
247 vty_out(vty, "%% FEC to label binding cannot be %s\n",
248 add_cmd ? "added" : "deleted");
249 return CMD_WARNING_CONFIG_FAILED;
250 }
251
252 return CMD_SUCCESS;
f31e084c
DS
253}
254
255DEFUN (mpls_label_bind,
256 mpls_label_bind_cmd,
bf995813 257 "mpls label bind <A.B.C.D/M|X:X::X:X/M> <(16-1048575)|implicit-null|explicit-null>",
f31e084c
DS
258 MPLS_STR
259 "Label configuration\n"
260 "Establish FEC to label binding\n"
261 "IPv4 prefix\n"
262 "IPv6 prefix\n"
263 "MPLS Label to bind\n"
bf995813
DS
264 "Use Implicit-Null Label\n"
265 "Use Explicit-Null Label\n")
f31e084c 266{
d62a17ae 267 return zebra_mpls_bind(vty, 1, argv[3]->arg, argv[4]->arg);
f31e084c
DS
268}
269
270DEFUN (no_mpls_label_bind,
271 no_mpls_label_bind_cmd,
272 "no mpls label bind <A.B.C.D/M|X:X::X:X/M> [<(16-1048575)|implicit-null>]",
273 NO_STR
274 MPLS_STR
275 "Label configuration\n"
276 "Establish FEC to label binding\n"
277 "IPv4 prefix\n"
278 "IPv6 prefix\n"
279 "MPLS Label to bind\n"
280 "Use Implicit-Null Label\n")
f31e084c 281{
d62a17ae 282 return zebra_mpls_bind(vty, 0, argv[4]->arg, NULL);
f31e084c
DS
283}
284
41675b4c 285/* MPLS LSP configuration write function. */
d62a17ae 286static int zebra_mpls_config(struct vty *vty)
41675b4c 287{
d62a17ae 288 int write = 0;
289 struct zebra_vrf *zvrf;
41675b4c 290
d62a17ae 291 zvrf = vrf_info_lookup(VRF_DEFAULT);
292 if (!zvrf)
293 return 0;
41675b4c 294
d62a17ae 295 write += zebra_mpls_write_lsp_config(vty, zvrf);
296 write += zebra_mpls_write_fec_config(vty, zvrf);
297 write += zebra_mpls_write_label_block_config(vty, zvrf);
298 return write;
41675b4c
RW
299}
300
f31e084c
DS
301DEFUN (show_mpls_fec,
302 show_mpls_fec_cmd,
303 "show mpls fec [<A.B.C.D/M|X:X::X:X/M>]",
304 SHOW_STR
305 MPLS_STR
306 "MPLS FEC table\n"
307 "FEC to display information about\n"
308 "FEC to display information about\n")
309{
d62a17ae 310 struct zebra_vrf *zvrf;
311 struct prefix p;
312 int ret;
313
314 zvrf = vrf_info_lookup(VRF_DEFAULT);
315 if (!zvrf)
316 return 0;
317
318 if (argc == 3)
319 zebra_mpls_print_fec_table(vty, zvrf);
320 else {
321 memset(&p, 0, sizeof(struct prefix));
322 ret = str2prefix(argv[3]->arg, &p);
323 if (ret <= 0) {
324 vty_out(vty, "%% Malformed address\n");
325 return CMD_WARNING;
326 }
327 zebra_mpls_print_fec(vty, zvrf, &p);
328 }
329
330 return CMD_SUCCESS;
f31e084c
DS
331}
332
41675b4c
RW
333DEFUN (show_mpls_table,
334 show_mpls_table_cmd,
e52702f2 335 "show mpls table [json]",
41675b4c
RW
336 SHOW_STR
337 MPLS_STR
338 "MPLS table\n"
9973d184 339 JSON_STR)
41675b4c 340{
d62a17ae 341 struct zebra_vrf *zvrf;
088f1098 342 bool uj = use_json(argc, argv);
41675b4c 343
d62a17ae 344 zvrf = vrf_info_lookup(VRF_DEFAULT);
345 zebra_mpls_print_lsp_table(vty, zvrf, uj);
346 return CMD_SUCCESS;
41675b4c
RW
347}
348
349DEFUN (show_mpls_table_lsp,
350 show_mpls_table_lsp_cmd,
e52702f2 351 "show mpls table (16-1048575) [json]",
41675b4c
RW
352 SHOW_STR
353 MPLS_STR
354 "MPLS table\n"
355 "LSP to display information about\n"
9973d184 356 JSON_STR)
41675b4c 357{
d7c0a89a 358 uint32_t label;
d62a17ae 359 struct zebra_vrf *zvrf;
088f1098 360 bool uj = use_json(argc, argv);
d62a17ae 361
362 zvrf = vrf_info_lookup(VRF_DEFAULT);
363 label = atoi(argv[3]->arg);
364 zebra_mpls_print_lsp(vty, zvrf, label, uj);
365 return CMD_SUCCESS;
41675b4c
RW
366}
367
fe6c7157
RW
368DEFUN (show_mpls_status,
369 show_mpls_status_cmd,
370 "show mpls status",
371 SHOW_STR
372 "MPLS information\n"
373 "MPLS status\n")
374{
d62a17ae 375 vty_out(vty, "MPLS support enabled: %s\n",
376 (mpls_enabled) ? "yes"
377 : "no (mpls kernel extensions not detected)");
378 return CMD_SUCCESS;
fe6c7157
RW
379}
380
d62a17ae 381static int zebra_mpls_global_block(struct vty *vty, int add_cmd,
382 const char *start_label_str,
383 const char *end_label_str)
1b6d5c7e 384{
d62a17ae 385 int ret;
d7c0a89a
QY
386 uint32_t start_label;
387 uint32_t end_label;
d62a17ae 388 struct zebra_vrf *zvrf;
389
390 zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
391 if (!zvrf) {
392 vty_out(vty, "%% Default VRF does not exist\n");
393 return CMD_WARNING_CONFIG_FAILED;
394 }
395
396 if (add_cmd) {
397 if (!start_label_str || !end_label_str) {
398 vty_out(vty, "%% Labels not specified\n");
399 return CMD_WARNING_CONFIG_FAILED;
400 }
401
402 start_label = atoi(start_label_str);
403 end_label = atoi(end_label_str);
404 if (!IS_MPLS_UNRESERVED_LABEL(start_label)
405 || !IS_MPLS_UNRESERVED_LABEL(end_label)) {
406 vty_out(vty, "%% Invalid label\n");
407 return CMD_WARNING_CONFIG_FAILED;
408 }
409 if (end_label < start_label) {
410 vty_out(vty, "%% End label is less than Start label\n");
411 return CMD_WARNING_CONFIG_FAILED;
412 }
413
414 ret = zebra_mpls_label_block_add(zvrf, start_label, end_label);
415 } else
416 ret = zebra_mpls_label_block_del(zvrf);
417
418 if (ret) {
419 vty_out(vty, "%% Global label block could not be %s\n",
420 add_cmd ? "added" : "deleted");
421 return CMD_WARNING_CONFIG_FAILED;
422 }
423
424 return CMD_SUCCESS;
1b6d5c7e
VV
425}
426
427DEFUN (mpls_label_global_block,
428 mpls_label_global_block_cmd,
429 "mpls label global-block (16-1048575) (16-1048575)",
430 MPLS_STR
431 "Label configuration\n"
432 "Configure global label block\n"
433 "Start label\n"
434 "End label\n")
435{
d62a17ae 436 return zebra_mpls_global_block(vty, 1, argv[3]->arg, argv[4]->arg);
1b6d5c7e
VV
437}
438
439DEFUN (no_mpls_label_global_block,
440 no_mpls_label_global_block_cmd,
441 "no mpls label global-block [(16-1048575) (16-1048575)]",
442 NO_STR
443 MPLS_STR
444 "Label configuration\n"
445 "Configure global label block\n"
446 "Start label\n"
447 "End label\n")
448{
d62a17ae 449 return zebra_mpls_global_block(vty, 0, NULL, NULL);
1b6d5c7e
VV
450}
451
41675b4c 452/* MPLS node for MPLS LSP. */
d62a17ae 453static struct cmd_node mpls_node = {MPLS_NODE, "", 1};
41675b4c
RW
454
455/* MPLS VTY. */
d62a17ae 456void zebra_mpls_vty_init(void)
41675b4c 457{
d62a17ae 458 install_element(VIEW_NODE, &show_mpls_status_cmd);
459
460 install_node(&mpls_node, zebra_mpls_config);
461
d62a17ae 462 install_element(CONFIG_NODE, &mpls_transit_lsp_cmd);
463 install_element(CONFIG_NODE, &no_mpls_transit_lsp_cmd);
464 install_element(CONFIG_NODE, &no_mpls_transit_lsp_out_label_cmd);
465 install_element(CONFIG_NODE, &no_mpls_transit_lsp_all_cmd);
d97c792e 466
d62a17ae 467 install_element(CONFIG_NODE, &mpls_label_bind_cmd);
468 install_element(CONFIG_NODE, &no_mpls_label_bind_cmd);
469
470 install_element(CONFIG_NODE, &mpls_label_global_block_cmd);
471 install_element(CONFIG_NODE, &no_mpls_label_global_block_cmd);
472
473 install_element(VIEW_NODE, &show_mpls_table_cmd);
474 install_element(VIEW_NODE, &show_mpls_table_lsp_cmd);
475 install_element(VIEW_NODE, &show_mpls_fec_cmd);
41675b4c 476}