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)
return -99;
}
}
+ else if (unformat (i, "instance %u", &instance))
+ renumber = 1;
else
{
errmsg ("parse error '%U'\n", format_unformat_error, i);
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;
_(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") \
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
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);
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;
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;
}
else
{
- vnet_interface_main_t *vim = &vnm->interface_main;
-
/* check if exists */
if (!p)
return VNET_API_ERROR_INVALID_VALUE;
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);
}
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;
}