blob: 606a1f53f9af57c8b4179353c5f6c92bc562ab33 [file] [log] [blame]
Ole Troan298c6952018-03-08 12:30:43 +01001/*
2 * Copyright (c) 2018 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "ipip.h"
17#include <vppinfra/error.h>
18#include <vnet/vnet.h>
Neale Ranns61502112018-08-22 00:21:14 -070019#include <vnet/fib/fib_table.h>
Ole Troan298c6952018-03-08 12:30:43 +010020
Mohammed Hawari8b552612020-12-01 11:20:31 +010021static clib_error_t *
22create_ipip_tunnel_command_fn (vlib_main_t * vm,
23 unformat_input_t * input,
24 vlib_cli_command_t * cmd)
25{
Ole Troan298c6952018-03-08 12:30:43 +010026 unformat_input_t _line_input, *line_input = &_line_input;
Mohammed Hawari8b552612020-12-01 11:20:31 +010027 ip46_address_t src = ip46_address_initializer, dst =
28 ip46_address_initializer;
Ole Troan298c6952018-03-08 12:30:43 +010029 u32 instance = ~0;
30 u32 fib_index = 0;
Neale Ranns61502112018-08-22 00:21:14 -070031 u32 table_id = 0;
Ole Troan298c6952018-03-08 12:30:43 +010032 int rv;
33 u32 num_m_args = 0;
34 u32 sw_if_index;
35 clib_error_t *error = NULL;
36 bool ip4_set = false, ip6_set = false;
Neale Ranns14053c92019-12-29 23:55:18 +000037 tunnel_mode_t mode = TUNNEL_MODE_P2P;
Mohammed Hawari59b792f2020-12-01 11:30:57 +010038 tunnel_encap_decap_flags_t flags = TUNNEL_ENCAP_DECAP_FLAG_NONE;
Ole Troan298c6952018-03-08 12:30:43 +010039
40 /* Get a line of input. */
Mohammed Hawari8b552612020-12-01 11:20:31 +010041 if (!unformat_user (input, unformat_line_input, line_input))
Ole Troan298c6952018-03-08 12:30:43 +010042 return 0;
43
Mohammed Hawari8b552612020-12-01 11:20:31 +010044 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
45 {
46 if (unformat (line_input, "instance %d", &instance))
47 ;
48 else
49 if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
50 {
51 num_m_args++;
52 ip4_set = true;
53 }
54 else
55 if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
56 {
57 num_m_args++;
58 ip4_set = true;
59 }
60 else
61 if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
62 {
63 num_m_args++;
64 ip6_set = true;
65 }
66 else
67 if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
68 {
69 num_m_args++;
70 ip6_set = true;
71 }
72 else if (unformat (line_input, "%U", unformat_tunnel_mode, &mode))
73 {
74 num_m_args++;
75 }
76 else if (unformat (line_input, "outer-table-id %d", &table_id))
77 ;
78 else
Mohammed Hawari59b792f2020-12-01 11:30:57 +010079 if (unformat
80 (line_input, "flags %U", unformat_tunnel_encap_decap_flags,
81 &flags))
82 ;
83 else
Mohammed Hawari8b552612020-12-01 11:20:31 +010084 {
85 error =
86 clib_error_return (0, "unknown input `%U'", format_unformat_error,
87 line_input);
88 goto done;
89 }
90 }
91
92 if (num_m_args < 2)
93 {
94 error = clib_error_return (0, "mandatory argument(s) missing");
Ole Troan298c6952018-03-08 12:30:43 +010095 goto done;
96 }
Mohammed Hawari8b552612020-12-01 11:20:31 +010097 if (ip4_set && ip6_set)
98 {
99 error =
100 clib_error_return (0,
101 "source and destination must be of same address family");
102 goto done;
Neale Ranns61502112018-08-22 00:21:14 -0700103 }
104
Mohammed Hawari8b552612020-12-01 11:20:31 +0100105 fib_index = fib_table_find (fib_ip_proto (ip6_set), table_id);
106
107 if (~0 == fib_index)
108 {
109 rv = VNET_API_ERROR_NO_SUCH_FIB;
110 }
111 else
112 {
113 rv = ipip_add_tunnel (ip6_set ? IPIP_TRANSPORT_IP6 : IPIP_TRANSPORT_IP4,
114 instance,
115 &src,
116 &dst,
117 fib_index,
Mohammed Hawari59b792f2020-12-01 11:30:57 +0100118 flags, IP_DSCP_CS0, mode, &sw_if_index);
Mohammed Hawari8b552612020-12-01 11:20:31 +0100119 }
120
121 switch (rv)
122 {
123 case 0:
124 vlib_cli_output (vm, "%U\n", format_vnet_sw_if_index_name,
125 vnet_get_main (), sw_if_index);
126 break;
127 case VNET_API_ERROR_IF_ALREADY_EXISTS:
128 error = clib_error_return (0, "IPIP tunnel already exists...");
129 goto done;
130 case VNET_API_ERROR_NO_SUCH_FIB:
131 error =
132 clib_error_return (0, "outer fib ID %d doesn't exist\n", fib_index);
133 goto done;
134 case VNET_API_ERROR_NO_SUCH_ENTRY:
135 error = clib_error_return (0, "IPIP tunnel doesn't exist");
136 goto done;
137 case VNET_API_ERROR_INSTANCE_IN_USE:
138 error = clib_error_return (0, "Instance is in use");
139 goto done;
140 case VNET_API_ERROR_INVALID_DST_ADDRESS:
141 error =
142 clib_error_return (0,
143 "destination IP address when mode is multi-point");
144 goto done;
145 default:
146 error =
147 clib_error_return (0, "vnet_ipip_add_del_tunnel returned %d", rv);
148 goto done;
149 }
Ole Troan298c6952018-03-08 12:30:43 +0100150
151done:
Mohammed Hawari8b552612020-12-01 11:20:31 +0100152 unformat_free (line_input);
Ole Troan298c6952018-03-08 12:30:43 +0100153
154 return error;
155}
156
Mohammed Hawari8b552612020-12-01 11:20:31 +0100157static clib_error_t *
158delete_ipip_tunnel_command_fn (vlib_main_t * vm,
159 unformat_input_t * input,
160 vlib_cli_command_t * cmd)
161{
Ole Troan298c6952018-03-08 12:30:43 +0100162 unformat_input_t _line_input, *line_input = &_line_input;
163 int rv;
164 u32 num_m_args = 0;
165 u32 sw_if_index = ~0;
166 clib_error_t *error = NULL;
167
168 /* Get a line of input. */
Mohammed Hawari8b552612020-12-01 11:20:31 +0100169 if (!unformat_user (input, unformat_line_input, line_input))
Ole Troan298c6952018-03-08 12:30:43 +0100170 return 0;
171
Mohammed Hawari8b552612020-12-01 11:20:31 +0100172 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
173 {
174 if (unformat (line_input, "sw_if_index %d", &sw_if_index))
175 num_m_args++;
176 else
177 {
178 error =
179 clib_error_return (0, "unknown input `%U'", format_unformat_error,
180 line_input);
181 goto done;
182 }
183 }
184
185 if (num_m_args < 1)
186 {
187 error = clib_error_return (0, "mandatory argument(s) missing");
Ole Troan298c6952018-03-08 12:30:43 +0100188 goto done;
189 }
Ole Troan298c6952018-03-08 12:30:43 +0100190
Mohammed Hawari8b552612020-12-01 11:20:31 +0100191 rv = ipip_del_tunnel (sw_if_index);
192 printf ("RV %d\n", rv);
Ole Troan298c6952018-03-08 12:30:43 +0100193
194done:
Mohammed Hawari8b552612020-12-01 11:20:31 +0100195 unformat_free (line_input);
Ole Troan298c6952018-03-08 12:30:43 +0100196
197 return error;
198}
199
Ole Troan298c6952018-03-08 12:30:43 +0100200VLIB_CLI_COMMAND(create_ipip_tunnel_command, static) = {
201 .path = "create ipip tunnel",
202 .short_help = "create ipip tunnel src <addr> dst <addr> [instance <n>] "
Neale Rannsae0d46e2020-09-22 13:20:27 +0000203 "[outer-table-id <ID>] [p2mp]",
Ole Troan298c6952018-03-08 12:30:43 +0100204 .function = create_ipip_tunnel_command_fn,
205};
206VLIB_CLI_COMMAND(delete_ipip_tunnel_command, static) = {
207 .path = "delete ipip tunnel",
Ignas Bacius3d93ad92019-10-10 16:14:47 +0300208 .short_help = "delete ipip tunnel sw_if_index <sw_if_index>",
Ole Troan298c6952018-03-08 12:30:43 +0100209 .function = delete_ipip_tunnel_command_fn,
210};
Ole Troan298c6952018-03-08 12:30:43 +0100211
Mohammed Hawari8b552612020-12-01 11:20:31 +0100212static u8 *
213format_ipip_tunnel (u8 * s, va_list * args)
214{
215 ipip_tunnel_t *t = va_arg (*args, ipip_tunnel_t *);
Ole Troan298c6952018-03-08 12:30:43 +0100216
Mohammed Hawari8b552612020-12-01 11:20:31 +0100217 ip46_type_t type =
218 (t->transport == IPIP_TRANSPORT_IP4) ? IP46_TYPE_IP4 : IP46_TYPE_IP6;
Neale Ranns61502112018-08-22 00:21:14 -0700219 u32 table_id;
220
Mohammed Hawari8b552612020-12-01 11:20:31 +0100221 table_id = fib_table_get_table_id (t->fib_index,
222 fib_proto_from_ip46 (type));
223 switch (t->mode)
224 {
225 case IPIP_MODE_6RD:
226 s = format (s, "[%d] 6rd src %U ip6-pfx %U/%d ",
227 t->dev_instance,
228 format_ip46_address, &t->tunnel_src, type,
229 format_ip6_address, &t->sixrd.ip6_prefix,
230 t->sixrd.ip6_prefix_len);
231 break;
232 case IPIP_MODE_P2P:
233 s = format (s, "[%d] instance %d src %U dst %U ",
234 t->dev_instance, t->user_instance,
235 format_ip46_address, &t->tunnel_src, type,
236 format_ip46_address, &t->tunnel_dst, type);
237 break;
238 case IPIP_MODE_P2MP:
239 s = format (s, "[%d] instance %d p2mp src %U ",
240 t->dev_instance, t->user_instance,
241 format_ip46_address, &t->tunnel_src, type);
242 break;
243 }
Ole Troan298c6952018-03-08 12:30:43 +0100244
Mohammed Hawari8b552612020-12-01 11:20:31 +0100245 s = format (s, "table-ID %d sw-if-idx %d flags [%U] dscp %U",
246 table_id, t->sw_if_index,
247 format_tunnel_encap_decap_flags, t->flags,
248 format_ip_dscp, t->dscp);
Neale Ranns95346962019-11-25 13:04:44 +0000249
Ole Troan298c6952018-03-08 12:30:43 +0100250 return s;
251}
252
Mohammed Hawari8b552612020-12-01 11:20:31 +0100253static clib_error_t *
254show_ipip_tunnel_command_fn (vlib_main_t * vm,
255 unformat_input_t * input,
256 vlib_cli_command_t * cmd)
257{
Ole Troan298c6952018-03-08 12:30:43 +0100258 ipip_main_t *gm = &ipip_main;
259 ipip_tunnel_t *t;
260 u32 ti = ~0;
261
Mohammed Hawari8b552612020-12-01 11:20:31 +0100262 if (pool_elts (gm->tunnels) == 0)
263 vlib_cli_output (vm, "No IPIP tunnels configured...");
Ole Troan298c6952018-03-08 12:30:43 +0100264
Mohammed Hawari8b552612020-12-01 11:20:31 +0100265 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
266 {
267 if (unformat (input, "%d", &ti))
268 ;
269 else
270 break;
271 }
Ole Troan298c6952018-03-08 12:30:43 +0100272
Mohammed Hawari8b552612020-12-01 11:20:31 +0100273 if (ti == ~0)
274 {
Damjan Marionb2c31b62020-12-13 21:47:40 +0100275 pool_foreach (t, gm->tunnels)
276 {vlib_cli_output(vm, "%U", format_ipip_tunnel, t); }
Mohammed Hawari8b552612020-12-01 11:20:31 +0100277 }
278 else
279 {
280 if (pool_is_free_index (gm->tunnels, ti))
281 return clib_error_return (0, "unknown index:%d", ti);
282 t = pool_elt_at_index (gm->tunnels, ti);
283 if (t)
284 vlib_cli_output (vm, "%U", format_ipip_tunnel, t);
285 }
Ole Troan298c6952018-03-08 12:30:43 +0100286 return 0;
287}
288
Ole Troan298c6952018-03-08 12:30:43 +0100289VLIB_CLI_COMMAND(show_ipip_tunnel_command, static) = {
290 .path = "show ipip tunnel",
291 .function = show_ipip_tunnel_command_fn,
292};
Ole Troan298c6952018-03-08 12:30:43 +0100293
Neale Ranns14053c92019-12-29 23:55:18 +0000294static u8 *
Mohammed Hawari8b552612020-12-01 11:20:31 +0100295format_ipip_tunnel_key (u8 * s, va_list * args)
Neale Ranns14053c92019-12-29 23:55:18 +0000296{
Mohammed Hawari8b552612020-12-01 11:20:31 +0100297 ipip_tunnel_key_t *t = va_arg (*args, ipip_tunnel_key_t *);
Neale Ranns14053c92019-12-29 23:55:18 +0000298
299 s = format (s, "src:%U dst:%U fib:%d transport:%d mode:%d",
Mohammed Hawari8b552612020-12-01 11:20:31 +0100300 format_ip46_address, &t->src, IP46_TYPE_ANY,
301 format_ip46_address, &t->dst, IP46_TYPE_ANY,
302 t->fib_index, t->transport, t->mode);
Neale Ranns14053c92019-12-29 23:55:18 +0000303
304 return (s);
305}
306
307static clib_error_t *
308ipip_tunnel_hash_show (vlib_main_t * vm,
Mohammed Hawari8b552612020-12-01 11:20:31 +0100309 unformat_input_t * input, vlib_cli_command_t * cmd)
Neale Ranns14053c92019-12-29 23:55:18 +0000310{
311 ipip_main_t *im = &ipip_main;
312 ipip_tunnel_key_t *key;
313 u32 index;
314
Neale Ranns14053c92019-12-29 23:55:18 +0000315 hash_foreach(key, index, im->tunnel_by_key,
316 ({
317 vlib_cli_output (vm, " %U -> %d", format_ipip_tunnel_key, key, index);
318 }));
Neale Ranns14053c92019-12-29 23:55:18 +0000319
320 return NULL;
321}
322
323/**
324 * show IPSEC tunnel protection hash tables
325 */
Neale Ranns14053c92019-12-29 23:55:18 +0000326VLIB_CLI_COMMAND (ipip_tunnel_hash_show_node, static) =
327{
328 .path = "show ipip tunnel-hash",
329 .function = ipip_tunnel_hash_show,
330 .short_help = "show ipip tunnel-hash",
331};
Neale Ranns14053c92019-12-29 23:55:18 +0000332
Mohammed Hawari8b552612020-12-01 11:20:31 +0100333static clib_error_t *
334create_sixrd_tunnel_command_fn (vlib_main_t * vm,
335 unformat_input_t * input,
336 vlib_cli_command_t * cmd)
337{
Ole Troan298c6952018-03-08 12:30:43 +0100338 unformat_input_t _line_input, *line_input = &_line_input;
339 ip4_address_t ip4_prefix;
340 ip6_address_t ip6_prefix;
341 ip4_address_t ip4_src;
342 u32 ip6_prefix_len = 0, ip4_prefix_len = 0, sixrd_tunnel_index;
343 u32 num_m_args = 0;
344 /* Optional arguments */
Neale Ranns61502112018-08-22 00:21:14 -0700345 u32 ip4_table_id = 0, ip4_fib_index;
346 u32 ip6_table_id = 0, ip6_fib_index;
Ole Troan298c6952018-03-08 12:30:43 +0100347 clib_error_t *error = 0;
348 bool security_check = false;
Neale Ranns61502112018-08-22 00:21:14 -0700349 int rv;
Ole Troan298c6952018-03-08 12:30:43 +0100350
351 /* Get a line of input. */
Mohammed Hawari8b552612020-12-01 11:20:31 +0100352 if (!unformat_user (input, unformat_line_input, line_input))
Ole Troan298c6952018-03-08 12:30:43 +0100353 return 0;
Mohammed Hawari8b552612020-12-01 11:20:31 +0100354 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
355 {
356 if (unformat (line_input, "security-check"))
357 security_check = true;
358 else if (unformat (line_input, "ip6-pfx %U/%d", unformat_ip6_address,
359 &ip6_prefix, &ip6_prefix_len))
360 num_m_args++;
361 else if (unformat (line_input, "ip4-pfx %U/%d", unformat_ip4_address,
362 &ip4_prefix, &ip4_prefix_len))
363 num_m_args++;
364 else
365 if (unformat
366 (line_input, "ip4-src %U", unformat_ip4_address, &ip4_src))
367 num_m_args++;
368 else if (unformat (line_input, "ip4-table-id %d", &ip4_table_id))
369 ;
370 else if (unformat (line_input, "ip6-table-id %d", &ip6_table_id))
371 ;
372 else
373 {
374 error =
375 clib_error_return (0, "unknown input `%U'", format_unformat_error,
376 line_input);
377 goto done;
378 }
379 }
380
381 if (num_m_args < 3)
382 {
383 error = clib_error_return (0, "mandatory argument(s) missing");
Ole Troan298c6952018-03-08 12:30:43 +0100384 goto done;
385 }
Mohammed Hawari8b552612020-12-01 11:20:31 +0100386 ip4_fib_index = fib_table_find (FIB_PROTOCOL_IP4, ip4_table_id);
387 ip6_fib_index = fib_table_find (FIB_PROTOCOL_IP6, ip6_table_id);
Ole Troan298c6952018-03-08 12:30:43 +0100388
Neale Ranns61502112018-08-22 00:21:14 -0700389 if (~0 == ip4_fib_index)
Mohammed Hawari8b552612020-12-01 11:20:31 +0100390 {
391 error = clib_error_return (0, "No such IP4 table %d", ip4_table_id);
Neale Ranns61502112018-08-22 00:21:14 -0700392 rv = VNET_API_ERROR_NO_SUCH_FIB;
Mohammed Hawari8b552612020-12-01 11:20:31 +0100393 }
Neale Ranns61502112018-08-22 00:21:14 -0700394 else if (~0 == ip6_fib_index)
Mohammed Hawari8b552612020-12-01 11:20:31 +0100395 {
396 error = clib_error_return (0, "No such IP6 table %d", ip6_table_id);
Neale Ranns61502112018-08-22 00:21:14 -0700397 rv = VNET_API_ERROR_NO_SUCH_FIB;
Mohammed Hawari8b552612020-12-01 11:20:31 +0100398 }
Neale Ranns61502112018-08-22 00:21:14 -0700399 else
Mohammed Hawari8b552612020-12-01 11:20:31 +0100400 {
401 rv = sixrd_add_tunnel (&ip6_prefix, ip6_prefix_len, &ip4_prefix,
402 ip4_prefix_len, &ip4_src, security_check,
403 ip4_fib_index, ip6_fib_index,
404 &sixrd_tunnel_index);
Neale Ranns61502112018-08-22 00:21:14 -0700405
406 if (rv)
Mohammed Hawari8b552612020-12-01 11:20:31 +0100407 error = clib_error_return (0, "adding tunnel failed %d", rv);
408 }
Neale Ranns61502112018-08-22 00:21:14 -0700409
410done:
Mohammed Hawari8b552612020-12-01 11:20:31 +0100411 unformat_free (line_input);
Ole Troan298c6952018-03-08 12:30:43 +0100412
413 return error;
414}
415
Mohammed Hawari8b552612020-12-01 11:20:31 +0100416static clib_error_t *
417delete_sixrd_tunnel_command_fn (vlib_main_t * vm,
418 unformat_input_t * input,
419 vlib_cli_command_t * cmd)
420{
Ole Troan298c6952018-03-08 12:30:43 +0100421 unformat_input_t _line_input, *line_input = &_line_input;
422 u32 num_m_args = 0;
423 /* Optional arguments */
424 clib_error_t *error = 0;
425 u32 sw_if_index = ~0;
426
427 /* Get a line of input. */
Mohammed Hawari8b552612020-12-01 11:20:31 +0100428 if (!unformat_user (input, unformat_line_input, line_input))
Ole Troan298c6952018-03-08 12:30:43 +0100429 return 0;
Mohammed Hawari8b552612020-12-01 11:20:31 +0100430 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
431 {
432 if (unformat (line_input, "sw_if_index %d", &sw_if_index))
433 num_m_args++;
434 else
435 {
436 error =
437 clib_error_return (0, "unknown input `%U'", format_unformat_error,
438 line_input);
439 goto done;
440 }
441 }
442
443 if (num_m_args < 1)
444 {
445 error = clib_error_return (0, "mandatory argument(s) missing");
Ole Troan298c6952018-03-08 12:30:43 +0100446 goto done;
447 }
Mohammed Hawari8b552612020-12-01 11:20:31 +0100448 int rv = sixrd_del_tunnel (sw_if_index);
449 printf ("RV %d\n", rv);
Ole Troan298c6952018-03-08 12:30:43 +0100450
451done:
Mohammed Hawari8b552612020-12-01 11:20:31 +0100452 unformat_free (line_input);
Ole Troan298c6952018-03-08 12:30:43 +0100453
454 return error;
455}
456
Ole Troan298c6952018-03-08 12:30:43 +0100457VLIB_CLI_COMMAND(create_sixrd_tunnel_command, static) = {
458 .path = "create 6rd tunnel",
459 .short_help = "create 6rd tunnel ip6-pfx <ip6-pfx> ip4-pfx <ip4-pfx> "
Ignas Bacius3d93ad92019-10-10 16:14:47 +0300460 "ip4-src <ip4-addr> ip4-table-id <ID> ip6-table-id <ID> "
BenoƮt Ganne1b52ca92019-04-19 10:12:42 +0200461 "[security-check]",
Ole Troan298c6952018-03-08 12:30:43 +0100462 .function = create_sixrd_tunnel_command_fn,
463};
464VLIB_CLI_COMMAND(delete_sixrd_tunnel_command, static) = {
465 .path = "delete 6rd tunnel",
Ignas Bacius3d93ad92019-10-10 16:14:47 +0300466 .short_help = "delete 6rd tunnel sw_if_index <sw_if_index>",
Ole Troan298c6952018-03-08 12:30:43 +0100467 .function = delete_sixrd_tunnel_command_fn,
468};
Mohammed Hawari8b552612020-12-01 11:20:31 +0100469
470/*
471 * fd.io coding-style-patch-verification: ON
472 *
473 * Local Variables:
474 * eval: (c-set-style "gnu")
475 * End:
476 */