aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;
}