summary |
shortlog |
log |
commit | commitdiff |
review |
tree
raw |
patch |
inline | side by side (from parent 1:
1e5c07d)
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>
u8 is_add = 1;
u8 esn = 0;
u8 anti_replay = 0;
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)
int ret;
while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ else if (unformat (i, "instance %u", &instance))
+ renumber = 1;
else
{
errmsg ("parse error '%U'\n", format_unformat_error, i);
else
{
errmsg ("parse error '%U'\n", format_unformat_error, i);
clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
}
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;
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" \
_(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") \
_(ipsec_sa_dump, "[sa_id <n>]") \
_(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n" \
" <alg> <hex>\n") \
@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 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;
*/
define ipsec_tunnel_if_add_del {
u32 client_index;
u8 local_integ_key[128];
u8 remote_integ_key_len;
u8 remote_integ_key[128];
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
};
/** \brief Add/delete IPsec tunnel interface response
u8 local_integ_key[128];
u8 remote_integ_key_len;
u8 remote_integ_key[128];
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
} ipsec_add_del_tunnel_args_t;
typedef struct
u32 input_sa_index;
u32 output_sa_index;
u32 hw_if_index;
u32 input_sa_index;
u32 output_sa_index;
u32 hw_if_index;
} ipsec_tunnel_if_t;
typedef struct
} ipsec_tunnel_if_t;
typedef struct
uword *spd_index_by_sw_if_index;
uword *sa_index_by_sa_id;
uword *ipsec_if_pool_index_by_key;
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;
/* node indeces */
u32 error_drop_node_index;
mp->local_integ_key_len);
memcpy (&tun.remote_integ_key, &mp->remote_integ_key,
mp->remote_integ_key_len);
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);
rv = ipsec_add_del_tunnel_if_internal (vnm, &tun, &sw_if_index);
num_m_args++;
else if (unformat (line_input, "remote-spi %u", &a.remote_spi))
num_m_args++;
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
else if (unformat (line_input, "del"))
a.is_add = 0;
else
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (create_ipsec_tunnel_command, static) = {
.path = "create ipsec tunnel",
/* *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* */
.function = create_ipsec_tunnel_command_fn,
};
/* *INDENT-ON* */
format_ipsec_name (u8 * s, va_list * args)
{
u32 dev_instance = va_arg (*args, u32);
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);
u32 hw_if_index = ~0;
uword *p;
ipsec_sa_t *sa;
u32 hw_if_index = ~0;
uword *p;
ipsec_sa_t *sa;
u64 key = (u64) args->remote_ip.as_u32 << 32 | (u64) args->remote_spi;
p = hash_get (im->ipsec_if_pool_index_by_key, key);
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));
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;
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);
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;
hi = vnet_get_hw_interface (vnm, hw_if_index);
hi->output_node_index = ipsec_if_output_node.index;
- vnet_interface_main_t *vim = &vnm->interface_main;
-
/* check if exists */
if (!p)
return VNET_API_ERROR_INVALID_VALUE;
/* 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);
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 */
/* 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);
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);
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);
}
pool_put (im->tunnel_interfaces, t);
}
ipsec_main_t *im = &ipsec_main;
im->ipsec_if_pool_index_by_key = hash_create (0, sizeof (uword));
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));