diff options
author | Ole Troan <ot@cisco.com> | 2018-03-08 12:30:43 +0100 |
---|---|---|
committer | Neale Ranns <nranns@cisco.com> | 2018-03-14 14:06:02 +0000 |
commit | 298c69510ff4b64a262d465eb8877c4e7f4e60e0 (patch) | |
tree | e9ecf5fe32203ff40798841ac6442c9eaca943ca /src/vnet/ipip/ipip_cli.c | |
parent | 1c5ddbb22ba37e022a4cbf7c23d3cf6490d8ac6e (diff) |
IPIP: Add IP{v4,v6} over IP{v4,v6} configured tunnel support.
Change-Id: I166301c9e2388bae5f70ec0179d663a2703e27f5
Signed-off-by: Ole Troan <ot@cisco.com>
Diffstat (limited to 'src/vnet/ipip/ipip_cli.c')
-rw-r--r-- | src/vnet/ipip/ipip_cli.c | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/src/vnet/ipip/ipip_cli.c b/src/vnet/ipip/ipip_cli.c new file mode 100644 index 00000000000..45e6451d69a --- /dev/null +++ b/src/vnet/ipip/ipip_cli.c @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2018 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ipip.h" +#include <vppinfra/error.h> +#include <vnet/vnet.h> + +static clib_error_t *create_ipip_tunnel_command_fn(vlib_main_t *vm, + unformat_input_t *input, + vlib_cli_command_t *cmd) { + unformat_input_t _line_input, *line_input = &_line_input; + ip46_address_t src = ip46_address_initializer, dst = ip46_address_initializer; + u32 instance = ~0; + u32 fib_index = 0; + int rv; + u32 num_m_args = 0; + u32 sw_if_index; + clib_error_t *error = NULL; + bool ip4_set = false, ip6_set = false; + + /* Get a line of input. */ + if (!unformat_user(input, unformat_line_input, line_input)) + return 0; + + while (unformat_check_input(line_input) != UNFORMAT_END_OF_INPUT) { + if (unformat(line_input, "instance %d", &instance)) + ; + else if (unformat(line_input, "src %U", unformat_ip4_address, &src.ip4)) { + num_m_args++; + ip4_set = true; + } else if (unformat(line_input, "dst %U", unformat_ip4_address, &dst.ip4)) { + num_m_args++; + ip4_set = true; + } else if (unformat(line_input, "src %U", unformat_ip6_address, &src.ip6)) { + num_m_args++; + ip6_set = true; + } else if (unformat(line_input, "dst %U", unformat_ip6_address, &dst.ip6)) { + num_m_args++; + ip6_set = true; + } else if (unformat(line_input, "outer-fib-id %d", &fib_index)) + ; + else { + error = clib_error_return(0, "unknown input `%U'", format_unformat_error, + line_input); + goto done; + } + } + + if (num_m_args < 2) { + error = clib_error_return(0, "mandatory argument(s) missing"); + goto done; + } + if (ip4_set && ip6_set) { + error = clib_error_return(0, "source and destination must be of same address family"); + goto done; + } + + rv = ipip_add_tunnel(ip6_set ? IPIP_TRANSPORT_IP6 : IPIP_TRANSPORT_IP4, + instance, + &src, + &dst, + fib_index, + &sw_if_index); + + switch (rv) { + case 0: + vlib_cli_output(vm, "%U\n", format_vnet_sw_if_index_name, vnet_get_main(), + sw_if_index); + break; + case VNET_API_ERROR_IF_ALREADY_EXISTS: + error = clib_error_return(0, "IPIP tunnel already exists..."); + goto done; + case VNET_API_ERROR_NO_SUCH_FIB: + error = clib_error_return(0, "outer fib ID %d doesn't exist\n", fib_index); + goto done; + case VNET_API_ERROR_NO_SUCH_ENTRY: + error = clib_error_return(0, "IPIP tunnel doesn't exist"); + goto done; + case VNET_API_ERROR_INSTANCE_IN_USE: + error = clib_error_return(0, "Instance is in use"); + goto done; + default: + error = clib_error_return(0, "vnet_ipip_add_del_tunnel returned %d", rv); + goto done; + } + +done: + unformat_free(line_input); + + return error; +} + +static clib_error_t *delete_ipip_tunnel_command_fn(vlib_main_t *vm, + unformat_input_t *input, + vlib_cli_command_t *cmd) { + unformat_input_t _line_input, *line_input = &_line_input; + int rv; + u32 num_m_args = 0; + u32 sw_if_index = ~0; + clib_error_t *error = NULL; + + /* Get a line of input. */ + if (!unformat_user(input, unformat_line_input, line_input)) + return 0; + + while (unformat_check_input(line_input) != UNFORMAT_END_OF_INPUT) { + if (unformat(line_input, "sw_if_index %d", &sw_if_index)) + num_m_args++; + else { + error = clib_error_return(0, "unknown input `%U'", format_unformat_error, + line_input); + goto done; + } + } + + if (num_m_args < 1) { + error = clib_error_return(0, "mandatory argument(s) missing"); + goto done; + } + + rv = ipip_del_tunnel(sw_if_index); + printf("RV %d\n", rv); + +done: + unformat_free(line_input); + + return error; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND(create_ipip_tunnel_command, static) = { + .path = "create ipip tunnel", + .short_help = "create ipip tunnel src <addr> dst <addr> [instance <n>] " + "[outer-fib-id <fib>]", + .function = create_ipip_tunnel_command_fn, +}; +VLIB_CLI_COMMAND(delete_ipip_tunnel_command, static) = { + .path = "delete ipip tunnel", + .short_help = "delete ipip tunnel sw_if_index <sw_if_index ", + .function = delete_ipip_tunnel_command_fn, +}; +/* *INDENT-ON* */ + +static u8 *format_ipip_tunnel(u8 *s, va_list *args) { + ipip_tunnel_t *t = va_arg(*args, ipip_tunnel_t *); + + ip46_type_t type = (t->transport == IPIP_TRANSPORT_IP4) ? IP46_TYPE_IP4 : IP46_TYPE_IP6; + switch (t->mode) { + case IPIP_MODE_6RD: + s = format(s, "[%d] 6rd src %U ip6-pfx %U/%d fib-idx %d sw-if-idx %d ", + t->dev_instance, + format_ip46_address, &t->tunnel_src, type, + format_ip6_address, &t->sixrd.ip6_prefix, t->sixrd.ip6_prefix_len, + t->fib_index, t->sw_if_index); + break; + case IPIP_MODE_P2P: + default: + s = format(s, "[%d] instance %d src %U dst %U fib-idx %d sw-if-idx %d ", + t->dev_instance, t->user_instance, + format_ip46_address, &t->tunnel_src, type, + format_ip46_address, &t->tunnel_dst, type, + t->fib_index, t->sw_if_index); + break; + } + + return s; +} + +static clib_error_t *show_ipip_tunnel_command_fn(vlib_main_t *vm, + unformat_input_t *input, + vlib_cli_command_t *cmd) { + ipip_main_t *gm = &ipip_main; + ipip_tunnel_t *t; + u32 ti = ~0; + + if (pool_elts(gm->tunnels) == 0) + vlib_cli_output(vm, "No IPIP tunnels configured..."); + + while (unformat_check_input(input) != UNFORMAT_END_OF_INPUT) { + if (unformat(input, "%d", &ti)) + ; + else + break; + } + + if (ti == ~0) { + /* *INDENT-OFF* */ + pool_foreach(t, gm->tunnels, + ({vlib_cli_output(vm, "%U", format_ipip_tunnel, t); })); + /* *INDENT-ON* */ + } else { + t = pool_elt_at_index(gm->tunnels, ti); + if (t) + vlib_cli_output(vm, "%U", format_ipip_tunnel, t); + } + return 0; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND(show_ipip_tunnel_command, static) = { + .path = "show ipip tunnel", + .function = show_ipip_tunnel_command_fn, +}; +/* *INDENT-ON* */ + +static clib_error_t *create_sixrd_tunnel_command_fn(vlib_main_t *vm, + unformat_input_t *input, + vlib_cli_command_t *cmd) { + unformat_input_t _line_input, *line_input = &_line_input; + ip4_address_t ip4_prefix; + ip6_address_t ip6_prefix; + ip4_address_t ip4_src; + u32 ip6_prefix_len = 0, ip4_prefix_len = 0, sixrd_tunnel_index; + u32 num_m_args = 0; + /* Optional arguments */ + u32 fib_index = 0; + clib_error_t *error = 0; + bool security_check = false; + + /* Get a line of input. */ + if (!unformat_user(input, unformat_line_input, line_input)) + return 0; + while (unformat_check_input(line_input) != UNFORMAT_END_OF_INPUT) { + if (unformat(line_input, "security-check")) + security_check = true; + else if (unformat(line_input, "ip6-pfx %U/%d", unformat_ip6_address, + &ip6_prefix, &ip6_prefix_len)) + num_m_args++; + else if (unformat(line_input, "ip4-pfx %U/%d", unformat_ip4_address, + &ip4_prefix, &ip4_prefix_len)) + num_m_args++; + else if (unformat(line_input, "ip4-src %U", unformat_ip4_address, &ip4_src)) + num_m_args++; + else if (unformat(line_input, "fib-id %d", &fib_index)) + ; + else { + error = clib_error_return(0, "unknown input `%U'", format_unformat_error, + line_input); + goto done; + } + } + + if (num_m_args < 3) { + error = clib_error_return(0, "mandatory argument(s) missing"); + goto done; + } + int rv = sixrd_add_tunnel(&ip6_prefix, ip6_prefix_len, &ip4_prefix, + ip4_prefix_len, &ip4_src, security_check, + fib_index, &sixrd_tunnel_index); + if (rv) + error = clib_error_return(0, "adding tunnel failed %d", rv); + + done: + unformat_free(line_input); + + return error; +} + +static clib_error_t *delete_sixrd_tunnel_command_fn(vlib_main_t *vm, + unformat_input_t *input, + vlib_cli_command_t *cmd) { + unformat_input_t _line_input, *line_input = &_line_input; + u32 num_m_args = 0; + /* Optional arguments */ + clib_error_t *error = 0; + u32 sw_if_index = ~0; + + /* Get a line of input. */ + if (!unformat_user(input, unformat_line_input, line_input)) + return 0; + while (unformat_check_input(line_input) != UNFORMAT_END_OF_INPUT) { + if (unformat(line_input, "sw_if_index %d", &sw_if_index)) + num_m_args++; + else { + error = clib_error_return(0, "unknown input `%U'", format_unformat_error, + line_input); + goto done; + } + } + + if (num_m_args < 1) { + error = clib_error_return(0, "mandatory argument(s) missing"); + goto done; + } + int rv = sixrd_del_tunnel(sw_if_index); + printf("RV %d\n", rv); + +done: + unformat_free(line_input); + + return error; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND(create_sixrd_tunnel_command, static) = { + .path = "create 6rd tunnel", + .short_help = "create 6rd tunnel ip6-pfx <ip6-pfx> ip4-pfx <ip4-pfx> " + "ip4-src <ip4-addr> [del]", + .function = create_sixrd_tunnel_command_fn, +}; +VLIB_CLI_COMMAND(delete_sixrd_tunnel_command, static) = { + .path = "delete 6rd tunnel", + .short_help = "delete 6rd tunnel sw_if_index <sw_if_index", + .function = delete_sixrd_tunnel_command_fn, +}; +/* *INDENT-ON* */ |