- /* unset old inbound hash entry. packets should stop arriving */
- key = ((u64) old_sa->tunnel_src_addr.ip4.as_u32 << 32 |
- (u64) clib_host_to_net_u32 (old_sa->spi));
- p = hash_get (im->ipsec_if_pool_index_by_key, key);
- if (p)
- hash_unset (im->ipsec_if_pool_index_by_key, key);
+ if (sa->is_tunnel_ip6 ^ old_sa->is_tunnel_ip6)
+ {
+ clib_warning ("IPsec interface SA endpoints type can't be changed");
+ return VNET_API_ERROR_INVALID_VALUE;
+ }
+
+ if (sa->is_tunnel_ip6)
+ {
+ ipsec6_tunnel_key_t key;
+
+ /* unset old inbound hash entry. packets should stop arriving */
+ key.remote_ip = old_sa->tunnel_src_addr.ip6;
+ key.spi = clib_host_to_net_u32 (old_sa->spi);
+
+ p = hash_get_mem (im->ipsec6_if_pool_index_by_key, &key);
+ if (p)
+ hash_unset_mem_free (&im->ipsec6_if_pool_index_by_key, &key);
+
+ /* set new inbound SA, then set new hash entry */
+ t->input_sa_index = sa_index;
+ key.remote_ip = sa->tunnel_src_addr.ip6;
+ key.spi = clib_host_to_net_u32 (sa->spi);
+
+ hash_set_mem_alloc (&im->ipsec6_if_pool_index_by_key, &key,
+ hi->dev_instance);
+ }
+ else
+ {
+ ipsec4_tunnel_key_t key;
+
+ /* unset old inbound hash entry. packets should stop arriving */
+ key.remote_ip = old_sa->tunnel_src_addr.ip4.as_u32;
+ key.spi = clib_host_to_net_u32 (old_sa->spi);
+
+ p = hash_get (im->ipsec4_if_pool_index_by_key, key.as_u64);
+ if (p)
+ hash_unset (im->ipsec4_if_pool_index_by_key, key.as_u64);