aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Smith <mgsmith@netgate.com>2018-04-12 07:32:56 -0500
committerDamjan Marion <dmarion.lists@gmail.com>2018-04-19 10:35:25 +0000
commit8e1039a8231cd1d817a24256c421b9fc512f45fa (patch)
tree656a6902ae128794b76e879c74a8dad895c52294
parent1e5c07d379a092f4829e7081aa962d013b31fdfc (diff)
Allow an IPsec tunnel interface to be renumbered
When creating an IPsec tunnel interface, allow a numeric identifier to be set for use in the interface's name in place of the dev instance. Default to using the dev instance if no value is explicitly set. When an IPsec tunnel is deleted, the interface is deleted now instead of being kept in a pool of available hw interfaces. Otherwise there was the possibility of conflicting tx node names between deleted tunnels and newly created ones. Change-Id: Ic525466622a0dec38a845fa5871c084f6d9da380 Signed-off-by: Matthew Smith <mgsmith@netgate.com>
-rw-r--r--src/vat/api_format.c13
-rw-r--r--src/vnet/ipsec/ipsec.api4
-rw-r--r--src/vnet/ipsec/ipsec.h4
-rw-r--r--src/vnet/ipsec/ipsec_api.c2
-rw-r--r--src/vnet/ipsec/ipsec_cli.c4
-rw-r--r--src/vnet/ipsec/ipsec_if.c57
6 files changed, 54 insertions, 30 deletions
diff --git a/src/vat/api_format.c b/src/vat/api_format.c
index ceb074ccfe2..8c2fb13ecfe 100644
--- a/src/vat/api_format.c
+++ b/src/vat/api_format.c
@@ -15285,6 +15285,8 @@ api_ipsec_tunnel_if_add_del (vat_main_t * vam)
u8 is_add = 1;
u8 esn = 0;
u8 anti_replay = 0;
+ u8 renumber = 0;
+ u32 instance = ~0;
int ret;
while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
@@ -15336,6 +15338,8 @@ api_ipsec_tunnel_if_add_del (vat_main_t * vam)
return -99;
}
}
+ else if (unformat (i, "instance %u", &instance))
+ renumber = 1;
else
{
errmsg ("parse error '%U'\n", format_unformat_error, i);
@@ -15394,6 +15398,12 @@ api_ipsec_tunnel_if_add_del (vat_main_t * vam)
clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
}
+ if (renumber)
+ {
+ mp->renumber = renumber;
+ mp->show_instance = ntohl (instance);
+ }
+
S (mp);
W (ret);
return ret;
@@ -23477,7 +23487,8 @@ _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>") \
_(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n" \
" crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
" integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n" \
- " local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n") \
+ " local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n" \
+ " [instance <n>]") \
_(ipsec_sa_dump, "[sa_id <n>]") \
_(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n" \
" <alg> <hex>\n") \
diff --git a/src/vnet/ipsec/ipsec.api b/src/vnet/ipsec/ipsec.api
index bf2bc606e65..89c8a8b8240 100644
--- a/src/vnet/ipsec/ipsec.api
+++ b/src/vnet/ipsec/ipsec.api
@@ -513,6 +513,8 @@ define ipsec_spd_details {
@param local_integ_key - integrity key for outbound IPsec SA
@param remote_integ_key_len - length of remote integrity key in bytes
@param remote_integ_key - integrity key for inbound IPsec SA
+ @param renumber - intf display name uses a specified instance if != 0
+ @param show_instance - instance to display for intf if renumber is set
*/
define ipsec_tunnel_if_add_del {
u32 client_index;
@@ -534,6 +536,8 @@ define ipsec_tunnel_if_add_del {
u8 local_integ_key[128];
u8 remote_integ_key_len;
u8 remote_integ_key[128];
+ u8 renumber;
+ u32 show_instance;
};
/** \brief Add/delete IPsec tunnel interface response
diff --git a/src/vnet/ipsec/ipsec.h b/src/vnet/ipsec/ipsec.h
index 32bdee9c062..0269eb05261 100644
--- a/src/vnet/ipsec/ipsec.h
+++ b/src/vnet/ipsec/ipsec.h
@@ -171,6 +171,8 @@ typedef struct
u8 local_integ_key[128];
u8 remote_integ_key_len;
u8 remote_integ_key[128];
+ u8 renumber;
+ u32 show_instance;
} ipsec_add_del_tunnel_args_t;
typedef struct
@@ -243,6 +245,7 @@ typedef struct
u32 input_sa_index;
u32 output_sa_index;
u32 hw_if_index;
+ u32 show_instance;
} ipsec_tunnel_if_t;
typedef struct
@@ -277,6 +280,7 @@ typedef struct
uword *spd_index_by_sw_if_index;
uword *sa_index_by_sa_id;
uword *ipsec_if_pool_index_by_key;
+ uword *ipsec_if_real_dev_by_show_dev;
/* node indeces */
u32 error_drop_node_index;
diff --git a/src/vnet/ipsec/ipsec_api.c b/src/vnet/ipsec/ipsec_api.c
index da78f3d2496..6fb4f556c50 100644
--- a/src/vnet/ipsec/ipsec_api.c
+++ b/src/vnet/ipsec/ipsec_api.c
@@ -385,6 +385,8 @@ vl_api_ipsec_tunnel_if_add_del_t_handler (vl_api_ipsec_tunnel_if_add_del_t *
mp->local_integ_key_len);
memcpy (&tun.remote_integ_key, &mp->remote_integ_key,
mp->remote_integ_key_len);
+ tun.renumber = mp->renumber;
+ tun.show_instance = ntohl (mp->show_instance);
rv = ipsec_add_del_tunnel_if_internal (vnm, &tun, &sw_if_index);
diff --git a/src/vnet/ipsec/ipsec_cli.c b/src/vnet/ipsec/ipsec_cli.c
index 711403ff81a..09134e3901b 100644
--- a/src/vnet/ipsec/ipsec_cli.c
+++ b/src/vnet/ipsec/ipsec_cli.c
@@ -726,6 +726,8 @@ create_ipsec_tunnel_command_fn (vlib_main_t * vm,
num_m_args++;
else if (unformat (line_input, "remote-spi %u", &a.remote_spi))
num_m_args++;
+ else if (unformat (line_input, "instance %u", &a.show_instance))
+ a.renumber = 1;
else if (unformat (line_input, "del"))
a.is_add = 0;
else
@@ -770,7 +772,7 @@ done:
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (create_ipsec_tunnel_command, static) = {
.path = "create ipsec tunnel",
- .short_help = "create ipsec tunnel local-ip <addr> local-spi <spi> remote-ip <addr> remote-spi <spi>",
+ .short_help = "create ipsec tunnel local-ip <addr> local-spi <spi> remote-ip <addr> remote-spi <spi> [instance <inst_num>]",
.function = create_ipsec_tunnel_command_fn,
};
/* *INDENT-ON* */
diff --git a/src/vnet/ipsec/ipsec_if.c b/src/vnet/ipsec/ipsec_if.c
index 852b142717f..e7536b2756e 100644
--- a/src/vnet/ipsec/ipsec_if.c
+++ b/src/vnet/ipsec/ipsec_if.c
@@ -28,7 +28,10 @@ static u8 *
format_ipsec_name (u8 * s, va_list * args)
{
u32 dev_instance = va_arg (*args, u32);
- return format (s, "ipsec%d", dev_instance);
+ ipsec_main_t *im = &ipsec_main;
+ ipsec_tunnel_if_t *t = im->tunnel_interfaces + dev_instance;
+
+ return format (s, "ipsec%d", t->show_instance);
}
static uword
@@ -158,6 +161,7 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
u32 hw_if_index = ~0;
uword *p;
ipsec_sa_t *sa;
+ u32 dev_instance;
u64 key = (u64) args->remote_ip.as_u32 << 32 | (u64) args->remote_spi;
p = hash_get (im->ipsec_if_pool_index_by_key, key);
@@ -171,6 +175,21 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
pool_get_aligned (im->tunnel_interfaces, t, CLIB_CACHE_LINE_BYTES);
memset (t, 0, sizeof (*t));
+ dev_instance = t - im->tunnel_interfaces;
+ if (args->renumber)
+ t->show_instance = args->show_instance;
+ else
+ t->show_instance = dev_instance;
+
+ if (hash_get (im->ipsec_if_real_dev_by_show_dev, t->show_instance))
+ {
+ pool_put (im->tunnel_interfaces, t);
+ return VNET_API_ERROR_INSTANCE_IN_USE;
+ }
+
+ hash_set (im->ipsec_if_real_dev_by_show_dev, t->show_instance,
+ dev_instance);
+
pool_get (im->sad, sa);
memset (sa, 0, sizeof (*sa));
t->input_sa_index = sa - im->sad;
@@ -222,21 +241,10 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
hash_set (im->ipsec_if_pool_index_by_key, key,
t - im->tunnel_interfaces);
- if (vec_len (im->free_tunnel_if_indices) > 0)
- {
- hw_if_index =
- im->free_tunnel_if_indices[vec_len (im->free_tunnel_if_indices) -
- 1];
- _vec_len (im->free_tunnel_if_indices) -= 1;
- }
- else
- {
- hw_if_index =
- vnet_register_interface (vnm, ipsec_device_class.index,
- t - im->tunnel_interfaces,
- ipsec_hw_class.index,
- t - im->tunnel_interfaces);
- }
+ hw_if_index = vnet_register_interface (vnm, ipsec_device_class.index,
+ t - im->tunnel_interfaces,
+ ipsec_hw_class.index,
+ t - im->tunnel_interfaces);
hi = vnet_get_hw_interface (vnm, hw_if_index);
hi->output_node_index = ipsec_if_output_node.index;
@@ -253,8 +261,6 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
}
else
{
- vnet_interface_main_t *vim = &vnm->interface_main;
-
/* check if exists */
if (!p)
return VNET_API_ERROR_INVALID_VALUE;
@@ -266,25 +272,19 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
vnet_feature_enable_disable ("interface-output", "ipsec-if-output",
hi->sw_if_index, 0, 0, 0);
- vec_add1 (im->free_tunnel_if_indices, t->hw_if_index);
-
- vnet_interface_counter_lock (vim);
- vlib_zero_combined_counter (vim->combined_sw_if_counters +
- VNET_INTERFACE_COUNTER_TX, hi->sw_if_index);
- vlib_zero_combined_counter (vim->combined_sw_if_counters +
- VNET_INTERFACE_COUNTER_RX, hi->sw_if_index);
- vnet_interface_counter_unlock (vim);
+ vnet_delete_hw_interface (vnm, t->hw_if_index);
/* delete input and output SA */
- sa = pool_elt_at_index (im->sad, t->input_sa_index);
+ sa = pool_elt_at_index (im->sad, t->input_sa_index);
pool_put (im->sad, sa);
sa = pool_elt_at_index (im->sad, t->output_sa_index);
-
pool_put (im->sad, sa);
hash_unset (im->ipsec_if_pool_index_by_key, key);
+ hash_unset (im->ipsec_if_real_dev_by_show_dev, t->show_instance);
+
pool_put (im->tunnel_interfaces, t);
}
@@ -491,6 +491,7 @@ ipsec_tunnel_if_init (vlib_main_t * vm)
ipsec_main_t *im = &ipsec_main;
im->ipsec_if_pool_index_by_key = hash_create (0, sizeof (uword));
+ im->ipsec_if_real_dev_by_show_dev = hash_create (0, sizeof (uword));
return 0;
}