diff options
author | Filip Tehlar <ftehlar@cisco.com> | 2016-09-30 12:47:59 +0200 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2016-09-30 13:07:51 +0000 |
commit | f3e3fd3e08747b95ce32e7f8de714e82fc0f9597 (patch) | |
tree | 474095d9fd949d04af835550d3efebbc4a632916 | |
parent | f2c6ed1925efa46fc9f17d0b7cad738c71067eb4 (diff) |
VPP-454 Fix LISP GID dictionary issue
GID dictionary IP prefix entries are rewritten with more narrow one
which is not desirable. This patch does exact matching instead of
longest prefix matching.
Change-Id: I0191e23229a69ffe86f82ea4d71e4a5534dbb5b0
Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
-rw-r--r-- | vnet/vnet/lisp-cp/control.c | 5 | ||||
-rw-r--r-- | vnet/vnet/lisp-cp/gid_dictionary.c | 56 |
2 files changed, 54 insertions, 7 deletions
diff --git a/vnet/vnet/lisp-cp/control.c b/vnet/vnet/lisp-cp/control.c index 940d5893e67..4ca30f95479 100644 --- a/vnet/vnet/lisp-cp/control.c +++ b/vnet/vnet/lisp-cp/control.c @@ -394,7 +394,10 @@ dp_add_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index) if (feip) dp_del_fwd_entry (lcm, src_map_index, dst_map_index); - src_map = pool_elt_at_index (lcm->mapping_pool, src_map_index); + if (lcm->lisp_pitr) + src_map = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index); + else + src_map = pool_elt_at_index (lcm->mapping_pool, src_map_index); dst_map = pool_elt_at_index (lcm->mapping_pool, dst_map_index); /* insert data plane forwarding entry */ diff --git a/vnet/vnet/lisp-cp/gid_dictionary.c b/vnet/vnet/lisp-cp/gid_dictionary.c index a422b247a06..2fd909621ae 100644 --- a/vnet/vnet/lisp-cp/gid_dictionary.c +++ b/vnet/vnet/lisp-cp/gid_dictionary.c @@ -49,6 +49,27 @@ mac_sd_lookup (gid_mac_table_t * db, u32 vni, u8 * dst, u8 * src) } static u32 +ip4_lookup_exact_match (gid_ip4_table_t * db, u32 vni, ip_prefix_t * key) +{ + int rv; + BVT (clib_bihash_kv) kv, value; + + ip4_address_t *mask; + + mask = &db->ip4_fib_masks[ip_prefix_len (key)]; + + kv.key[0] = ((u64) vni << 32) | (ip_prefix_v4 (key).as_u32 & mask->as_u32); + kv.key[1] = 0; + kv.key[2] = 0; + + rv = BV (clib_bihash_search_inline_2) (&db->ip4_lookup_table, &kv, &value); + if (rv == 0) + return value.value; + + return GID_LOOKUP_MISS; +} + +static u32 ip4_lookup (gid_ip4_table_t * db, u32 vni, ip_prefix_t * key) { int i, len; @@ -81,6 +102,26 @@ ip4_lookup (gid_ip4_table_t * db, u32 vni, ip_prefix_t * key) } static u32 +ip6_lookup_exact_match (gid_ip6_table_t * db, u32 vni, ip_prefix_t * key) +{ + int rv; + BVT (clib_bihash_kv) kv, value; + + ip6_address_t *mask; + mask = &db->ip6_fib_masks[ip_prefix_len (key)]; + + kv.key[0] = ip_prefix_v6 (key).as_u64[0] & mask->as_u64[0]; + kv.key[1] = ip_prefix_v6 (key).as_u64[1] & mask->as_u64[1]; + kv.key[2] = (u64) vni; + + rv = BV (clib_bihash_search_inline_2) (&db->ip6_lookup_table, &kv, &value); + if (rv == 0) + return value.value; + + return GID_LOOKUP_MISS; +} + +static u32 ip6_lookup (gid_ip6_table_t * db, u32 vni, ip_prefix_t * key) { int i, len; @@ -132,7 +173,7 @@ ip_sd_lookup (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst, { ip_prefix_t sp; memset (&sp, 0, sizeof (sp)); - return ip4_lookup (sfib4, 0, &sp); + return ip4_lookup_exact_match (sfib4, 0, &sp); } else return ip4_lookup (sfib4, 0, src); @@ -150,7 +191,7 @@ ip_sd_lookup (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst, ip_prefix_t sp; memset (&sp, 0, sizeof (sp)); ip_prefix_version (&sp) = IP6; - return ip6_lookup (sfib6, 0, &sp); + return ip6_lookup_exact_match (sfib6, 0, &sp); } else return ip6_lookup (sfib6, 0, src); @@ -329,7 +370,7 @@ add_del_sd_ip4_key (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst_pref, u32 sfi, old_val = ~0; gid_ip4_table_t *sfib; - sfi = ip4_lookup (&db->dst_ip4_table, vni, dst_pref); + sfi = ip4_lookup_exact_match (&db->dst_ip4_table, vni, dst_pref); if (is_add) { @@ -354,7 +395,7 @@ add_del_sd_ip4_key (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst_pref, sfib = pool_elt_at_index (db->src_ip4_table_pool, sfi); if (src_pref) { - old_val = ip4_lookup (sfib, 0, src_pref); + old_val = ip4_lookup_exact_match (sfib, 0, src_pref); add_del_ip4_key (sfib, 0 /* vni */ , src_pref, val, is_add); } else @@ -522,7 +563,7 @@ add_del_sd_ip6_key (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst_pref, u32 sfi, old_val = ~0; gid_ip6_table_t *sfib; - sfi = ip6_lookup (&db->dst_ip6_table, vni, dst_pref); + sfi = ip6_lookup_exact_match (&db->dst_ip6_table, vni, dst_pref); if (is_add) { @@ -538,6 +579,7 @@ add_del_sd_ip6_key (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst_pref, { ip_prefix_t sp; memset (&sp, 0, sizeof (sp)); + ip_prefix_version (&sp) = IP6; add_del_ip6_key (sfib, 0 /* vni */ , &sp, val, is_add); } } @@ -547,13 +589,14 @@ add_del_sd_ip6_key (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst_pref, sfib = pool_elt_at_index (db->src_ip6_table_pool, sfi); if (src_pref) { - old_val = ip6_lookup (sfib, 0, src_pref); + old_val = ip6_lookup_exact_match (sfib, 0, src_pref); add_del_ip6_key (sfib, 0 /* vni */ , src_pref, val, is_add); } else { ip_prefix_t sp; memset (&sp, 0, sizeof (sp)); + ip_prefix_version (&sp) = IP6; old_val = add_del_ip6_key (sfib, 0 /* vni */ , &sp, val, is_add); } @@ -571,6 +614,7 @@ add_del_sd_ip6_key (gid_dictionary_t * db, u32 vni, ip_prefix_t * dst_pref, { ip_prefix_t sp; memset (&sp, 0, sizeof (sp)); + ip_prefix_version (&sp) = IP6; old_val = add_del_ip6_key (sfib, 0, &sp, 0, is_add); } } |