VPP-98 Dedicated storage for VXLAN over IPv6 hash keys

When creating VXLAN over IPv6 the code was using storage for the
hash key that could later be moved. Since the key is larger than
the word size this was being referenced as a pointer; when the
storage moves that breaks the hash.

Instead allocate dedicated storage for the key.

This patch also includes other minor cleanups, including using
clib_memcpy in places it should be used and some whitespace
fixes.

Change-Id: I579f2cb515853ef56dedcca350fcad08aa6111a9
Signed-off-by: Chris Luke <chrisy@flirble.org>
This commit is contained in:
Chris Luke
2016-05-31 10:42:14 -04:00
committed by Dave Wallace
parent db0cf7963b
commit 966bef4ad1
3 changed files with 66 additions and 53 deletions

View File

@ -186,21 +186,21 @@ vxlan_input (vlib_main_t * vm,
key6_0.vni = vxlan0->vni_reserved;
if (PREDICT_FALSE (memcmp(&key6_0, &last_key6, sizeof(last_key6)) != 0))
{
p0 = hash_get (vxm->vxlan6_tunnel_by_key, pointer_to_uword(&key6_0));
{
p0 = hash_get_mem (vxm->vxlan6_tunnel_by_key, &key6_0);
if (p0 == 0)
{
error0 = VXLAN_ERROR_NO_SUCH_TUNNEL;
next0 = VXLAN_INPUT_NEXT_DROP;
goto trace0;
}
if (p0 == 0)
{
error0 = VXLAN_ERROR_NO_SUCH_TUNNEL;
next0 = VXLAN_INPUT_NEXT_DROP;
goto trace0;
}
last_key6 = key6_0;
tunnel_index0 = last_tunnel_index = p0[0];
}
else
tunnel_index0 = last_tunnel_index;
clib_memcpy (&last_key6, &key6_0, sizeof(key6_0));
tunnel_index0 = last_tunnel_index = p0[0];
}
else
tunnel_index0 = last_tunnel_index;
}
t0 = pool_elt_at_index (vxm->tunnels, tunnel_index0);
@ -276,21 +276,21 @@ vxlan_input (vlib_main_t * vm,
key6_1.vni = vxlan1->vni_reserved;
if (PREDICT_FALSE (memcmp(&key6_1, &last_key6, sizeof(last_key6)) != 0))
{
p1 = hash_get (vxm->vxlan6_tunnel_by_key, pointer_to_uword(&key6_1));
{
p1 = hash_get_mem (vxm->vxlan6_tunnel_by_key, &key6_1);
if (p1 == 0)
{
error1 = VXLAN_ERROR_NO_SUCH_TUNNEL;
next1 = VXLAN_INPUT_NEXT_DROP;
goto trace1;
}
if (p1 == 0)
{
error1 = VXLAN_ERROR_NO_SUCH_TUNNEL;
next1 = VXLAN_INPUT_NEXT_DROP;
goto trace1;
}
last_key6 = key6_1;
tunnel_index1 = last_tunnel_index = p1[0];
}
else
tunnel_index1 = last_tunnel_index;
clib_memcpy (&last_key6, &key6_1, sizeof(key6_1));
tunnel_index1 = last_tunnel_index = p1[0];
}
else
tunnel_index1 = last_tunnel_index;
}
t1 = pool_elt_at_index (vxm->tunnels, tunnel_index1);
@ -420,21 +420,21 @@ vxlan_input (vlib_main_t * vm,
key6_0.vni = vxlan0->vni_reserved;
if (PREDICT_FALSE (memcmp(&key6_0, &last_key6, sizeof(last_key6)) != 0))
{
p0 = hash_get (vxm->vxlan6_tunnel_by_key, pointer_to_uword(&key6_0));
{
p0 = hash_get_mem (vxm->vxlan6_tunnel_by_key, &key6_0);
if (p0 == 0)
{
error0 = VXLAN_ERROR_NO_SUCH_TUNNEL;
next0 = VXLAN_INPUT_NEXT_DROP;
goto trace00;
}
if (p0 == 0)
{
error0 = VXLAN_ERROR_NO_SUCH_TUNNEL;
next0 = VXLAN_INPUT_NEXT_DROP;
goto trace00;
}
last_key6 = key6_0;
tunnel_index0 = last_tunnel_index = p0[0];
}
else
tunnel_index0 = last_tunnel_index;
clib_memcpy (&last_key6, &key6_0, sizeof(key6_0));
tunnel_index0 = last_tunnel_index = p0[0];
}
else
tunnel_index0 = last_tunnel_index;
}
t0 = pool_elt_at_index (vxm->tunnels, tunnel_index0);

View File

@ -218,7 +218,7 @@ int vnet_vxlan_add_del_tunnel
key6.src.as_u64[1] = a->dst.ip6.as_u64[1];
key6.vni = clib_host_to_net_u32 (a->vni << 8);
p = hash_get (vxm->vxlan6_tunnel_by_key, pointer_to_uword(&key6));
p = hash_get_mem (vxm->vxlan6_tunnel_by_key, &key6);
}
if (a->is_add)
@ -243,10 +243,16 @@ int vnet_vxlan_add_del_tunnel
else foreach_copy_ipv6
#undef _
if (a->is_ip6) {
/* copy the key */
t->key6 = key6;
}
/* copy the key */
if (a->is_ip6)
{
t->key6 = clib_mem_alloc (sizeof(vxlan6_tunnel_key_t));
clib_memcpy (t->key6, &key6, sizeof(key6));
}
else
{
t->key4 = 0; /* not yet used */
}
if (!a->is_ip6) t->flags |= VXLAN_TUNNEL_IS_IPV4;
@ -265,7 +271,7 @@ int vnet_vxlan_add_del_tunnel
if (!a->is_ip6)
hash_set (vxm->vxlan4_tunnel_by_key, key4.as_u64, t - vxm->tunnels);
else
hash_set (vxm->vxlan6_tunnel_by_key, pointer_to_uword(&t->key6), t - vxm->tunnels);
hash_set_mem (vxm->vxlan6_tunnel_by_key, t->key6, t - vxm->tunnels);
if (vec_len (vxm->free_vxlan_tunnel_hw_if_indices) > 0)
{
@ -340,14 +346,21 @@ int vnet_vxlan_add_del_tunnel
if (!a->is_ip6)
hash_unset (vxm->vxlan4_tunnel_by_key, key4.as_u64);
else
hash_unset (vxm->vxlan6_tunnel_by_key, pointer_to_uword(&key6));
hash_unset_mem (vxm->vxlan6_tunnel_by_key, t->key6);
vec_free (t->rewrite);
if (!a->is_ip6) {
t->rewrite = vxlan4_dummy_rewrite;
} else {
t->rewrite = vxlan6_dummy_rewrite;
}
if (!a->is_ip6)
{
t->rewrite = vxlan4_dummy_rewrite;
t->key4 = 0;
}
else
{
t->rewrite = vxlan6_dummy_rewrite;
clib_mem_free (t->key6);
t->key6 = 0;
}
pool_put (vxm->tunnels, t);
}

View File

@ -84,8 +84,8 @@ typedef struct {
u32 sw_if_index;
union { /* storage for the hash key */
vxlan4_tunnel_key_t key4;
vxlan6_tunnel_key_t key6;
vxlan4_tunnel_key_t *key4;
vxlan6_tunnel_key_t *key6;
};
/* flags */