aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2019-03-05 06:11:57 -0800
committerNeale Ranns <nranns@cisco.com>2019-03-05 19:58:00 +0000
commit665581a5de364341c8c924d39dbb54a2bda3715c (patch)
treec73a6a9dd89f67bc3121a6f2d60cfc1def6d3f34 /src/vnet
parentd7f872e8d87eedd10189c6a41f1a6a394160f734 (diff)
VXLAN-GBP: decap checks src,dst&VNI for unicast, then checks only dst&VNI for multicast
Change-Id: I17caf3c5a2060de497c44655b66a15a2007f716b Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/vxlan-gbp/decap.c129
-rw-r--r--src/vnet/vxlan-gbp/vxlan_gbp.c4
2 files changed, 62 insertions, 71 deletions
diff --git a/src/vnet/vxlan-gbp/decap.c b/src/vnet/vxlan-gbp/decap.c
index 6c14ef79531..1a8ece702a6 100644
--- a/src/vnet/vxlan-gbp/decap.c
+++ b/src/vnet/vxlan-gbp/decap.c
@@ -70,46 +70,47 @@ typedef vxlan4_gbp_tunnel_key_t last_tunnel_cache4;
always_inline vxlan_gbp_tunnel_t *
vxlan4_gbp_find_tunnel (vxlan_gbp_main_t * vxm, last_tunnel_cache4 * cache,
u32 fib_index, ip4_header_t * ip4_0,
- vxlan_gbp_header_t * vxlan_gbp0,
- vxlan_gbp_tunnel_t ** stats_t0)
+ vxlan_gbp_header_t * vxlan_gbp0)
{
- /* Make sure VXLAN_GBP tunnel exist according to packet SIP and VNI */
+ /*
+ * Check unicast first since that's where most of the traffic comes from
+ * Make sure VXLAN_GBP tunnel exist according to packet SIP, DIP and VNI
+ */
vxlan4_gbp_tunnel_key_t key4;
+ int rv;
+
key4.key[1] = ((u64) fib_index << 32) | vxlan_gbp0->vni_reserved;
+ key4.key[0] = (((u64) ip4_0->dst_address.as_u32 << 32) |
+ ip4_0->src_address.as_u32);
- if (PREDICT_FALSE (key4.key[1] != cache->key[1] ||
- ip4_0->src_address.as_u32 != (u32) cache->key[0]))
+ if (PREDICT_FALSE (key4.key[0] != cache->key[0] ||
+ key4.key[1] != cache->key[1]))
{
- key4.key[0] = ip4_0->src_address.as_u32;
- int rv = clib_bihash_search_inline_16_8 (&vxm->vxlan4_gbp_tunnel_by_key,
- &key4);
- if (PREDICT_FALSE (rv != 0))
- return 0;
-
- *cache = key4;
+ rv = clib_bihash_search_inline_16_8 (&vxm->vxlan4_gbp_tunnel_by_key,
+ &key4);
+ if (PREDICT_FALSE (rv == 0))
+ {
+ *cache = key4;
+ return (pool_elt_at_index (vxm->tunnels, cache->value));
+ }
}
- vxlan_gbp_tunnel_t *t0 = pool_elt_at_index (vxm->tunnels, cache->value);
-
- /* Validate VXLAN_GBP tunnel SIP against packet DIP */
- if (PREDICT_TRUE (ip4_0->dst_address.as_u32 == t0->src.ip4.as_u32))
- *stats_t0 = t0;
else
{
- /* try multicast */
- if (PREDICT_TRUE (!ip4_address_is_multicast (&ip4_0->dst_address)))
- return 0;
+ return (pool_elt_at_index (vxm->tunnels, cache->value));
+ }
- key4.key[0] = ip4_0->dst_address.as_u32;
- /* Make sure mcast VXLAN_GBP tunnel exist by packet DIP and VNI */
- int rv = clib_bihash_search_inline_16_8 (&vxm->vxlan4_gbp_tunnel_by_key,
- &key4);
- if (PREDICT_FALSE (rv != 0))
- return 0;
+ /* No unicast match - try multicast */
+ if (PREDICT_TRUE (!ip4_address_is_multicast (&ip4_0->dst_address)))
+ return (NULL);
- *stats_t0 = pool_elt_at_index (vxm->tunnels, key4.value);
- }
+ key4.key[0] = ip4_0->dst_address.as_u32;
+ /* Make sure mcast VXLAN_GBP tunnel exist by packet DIP and VNI */
+ rv = clib_bihash_search_inline_16_8 (&vxm->vxlan4_gbp_tunnel_by_key, &key4);
- return t0;
+ if (PREDICT_FALSE (rv != 0))
+ return (NULL);
+
+ return (pool_elt_at_index (vxm->tunnels, key4.value));
}
typedef vxlan6_gbp_tunnel_key_t last_tunnel_cache6;
@@ -117,8 +118,7 @@ typedef vxlan6_gbp_tunnel_key_t last_tunnel_cache6;
always_inline vxlan_gbp_tunnel_t *
vxlan6_gbp_find_tunnel (vxlan_gbp_main_t * vxm, last_tunnel_cache6 * cache,
u32 fib_index, ip6_header_t * ip6_0,
- vxlan_gbp_header_t * vxlan_gbp0,
- vxlan_gbp_tunnel_t ** stats_t0)
+ vxlan_gbp_header_t * vxlan_gbp0)
{
/* Make sure VXLAN_GBP tunnel exist according to packet SIP and VNI */
vxlan6_gbp_tunnel_key_t key6 = {
@@ -128,23 +128,23 @@ vxlan6_gbp_find_tunnel (vxlan_gbp_main_t * vxm, last_tunnel_cache6 * cache,
[2] = (((u64) fib_index) << 32) | vxlan_gbp0->vni_reserved,
}
};
+ int rv;
if (PREDICT_FALSE
(clib_bihash_key_compare_24_8 (key6.key, cache->key) == 0))
{
- int rv = clib_bihash_search_inline_24_8 (&vxm->vxlan6_gbp_tunnel_by_key,
- &key6);
+ rv = clib_bihash_search_inline_24_8 (&vxm->vxlan6_gbp_tunnel_by_key,
+ &key6);
if (PREDICT_FALSE (rv != 0))
- return 0;
+ return NULL;
*cache = key6;
}
vxlan_gbp_tunnel_t *t0 = pool_elt_at_index (vxm->tunnels, cache->value);
/* Validate VXLAN_GBP tunnel SIP against packet DIP */
- if (PREDICT_TRUE (ip6_address_is_equal (&ip6_0->dst_address, &t0->src.ip6)))
- *stats_t0 = t0;
- else
+ if (PREDICT_FALSE
+ (!ip6_address_is_equal (&ip6_0->dst_address, &t0->src.ip6)))
{
/* try multicast */
if (PREDICT_TRUE (!ip6_address_is_multicast (&ip6_0->dst_address)))
@@ -153,12 +153,11 @@ vxlan6_gbp_find_tunnel (vxlan_gbp_main_t * vxm, last_tunnel_cache6 * cache,
/* Make sure mcast VXLAN_GBP tunnel exist by packet DIP and VNI */
key6.key[0] = ip6_0->dst_address.as_u64[0];
key6.key[1] = ip6_0->dst_address.as_u64[1];
- int rv = clib_bihash_search_inline_24_8 (&vxm->vxlan6_gbp_tunnel_by_key,
- &key6);
+ rv = clib_bihash_search_inline_24_8 (&vxm->vxlan6_gbp_tunnel_by_key,
+ &key6);
if (PREDICT_FALSE (rv != 0))
return 0;
- *stats_t0 = pool_elt_at_index (vxm->tunnels, key6.value);
}
return t0;
@@ -269,25 +268,20 @@ vxlan_gbp_input (vlib_main_t * vm,
u32 fi0 = buf_fib_index (b0, is_ip4);
u32 fi1 = buf_fib_index (b1, is_ip4);
- vxlan_gbp_tunnel_t *t0, *stats_t0 = 0;
- vxlan_gbp_tunnel_t *t1, *stats_t1 = 0;
+ vxlan_gbp_tunnel_t *t0, *t1;
if (is_ip4)
{
t0 =
- vxlan4_gbp_find_tunnel (vxm, &last4, fi0, ip4_0, vxlan_gbp0,
- &stats_t0);
+ vxlan4_gbp_find_tunnel (vxm, &last4, fi0, ip4_0, vxlan_gbp0);
t1 =
- vxlan4_gbp_find_tunnel (vxm, &last4, fi1, ip4_1, vxlan_gbp1,
- &stats_t1);
+ vxlan4_gbp_find_tunnel (vxm, &last4, fi1, ip4_1, vxlan_gbp1);
}
else
{
t0 =
- vxlan6_gbp_find_tunnel (vxm, &last6, fi0, ip6_0, vxlan_gbp0,
- &stats_t0);
+ vxlan6_gbp_find_tunnel (vxm, &last6, fi0, ip6_0, vxlan_gbp0);
t1 =
- vxlan6_gbp_find_tunnel (vxm, &last6, fi1, ip6_1, vxlan_gbp1,
- &stats_t1);
+ vxlan6_gbp_find_tunnel (vxm, &last6, fi1, ip6_1, vxlan_gbp1);
}
u32 len0 = vlib_buffer_length_in_chain (vm, b0);
@@ -304,15 +298,15 @@ vxlan_gbp_input (vlib_main_t * vm,
/* Validate VXLAN_GBP tunnel encap-fib index against packet */
if (PREDICT_FALSE
- (t0 == 0 || flags0 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G)))
+ (t0 == NULL
+ || flags0 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G)))
{
- if (t0 != 0
+ if (t0 != NULL
&& flags0 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G))
{
error0 = VXLAN_GBP_ERROR_BAD_FLAGS;
vlib_increment_combined_counter
- (drop_counter, thread_index, stats_t0->sw_if_index, 1,
- len0);
+ (drop_counter, thread_index, t0->sw_if_index, 1, len0);
next0 = VXLAN_GBP_INPUT_NEXT_DROP;
}
else
@@ -329,7 +323,7 @@ vxlan_gbp_input (vlib_main_t * vm,
/* Set packet input sw_if_index to unicast VXLAN tunnel for learning */
vnet_buffer (b0)->sw_if_index[VLIB_RX] = t0->sw_if_index;
vlib_increment_combined_counter
- (rx_counter, thread_index, stats_t0->sw_if_index, 1, len0);
+ (rx_counter, thread_index, t0->sw_if_index, 1, len0);
pkts_decapsulated++;
}
@@ -345,8 +339,7 @@ vxlan_gbp_input (vlib_main_t * vm,
{
error1 = VXLAN_GBP_ERROR_BAD_FLAGS;
vlib_increment_combined_counter
- (drop_counter, thread_index, stats_t1->sw_if_index, 1,
- len1);
+ (drop_counter, thread_index, t1->sw_if_index, 1, len1);
next1 = VXLAN_GBP_INPUT_NEXT_DROP;
}
else
@@ -365,7 +358,7 @@ vxlan_gbp_input (vlib_main_t * vm,
pkts_decapsulated++;
vlib_increment_combined_counter
- (rx_counter, thread_index, stats_t1->sw_if_index, 1, len1);
+ (rx_counter, thread_index, t1->sw_if_index, 1, len1);
}
vnet_buffer2 (b1)->gbp.flags = vxlan_gbp_get_gpflags (vxlan_gbp1);
@@ -424,15 +417,11 @@ vxlan_gbp_input (vlib_main_t * vm,
u32 fi0 = buf_fib_index (b0, is_ip4);
- vxlan_gbp_tunnel_t *t0, *stats_t0 = 0;
+ vxlan_gbp_tunnel_t *t0;
if (is_ip4)
- t0 =
- vxlan4_gbp_find_tunnel (vxm, &last4, fi0, ip4_0, vxlan_gbp0,
- &stats_t0);
+ t0 = vxlan4_gbp_find_tunnel (vxm, &last4, fi0, ip4_0, vxlan_gbp0);
else
- t0 =
- vxlan6_gbp_find_tunnel (vxm, &last6, fi0, ip6_0, vxlan_gbp0,
- &stats_t0);
+ t0 = vxlan6_gbp_find_tunnel (vxm, &last6, fi0, ip6_0, vxlan_gbp0);
uword len0 = vlib_buffer_length_in_chain (vm, b0);
@@ -444,15 +433,15 @@ vxlan_gbp_input (vlib_main_t * vm,
vlib_buffer_advance (b0, sizeof (*vxlan_gbp0));
/* Validate VXLAN_GBP tunnel encap-fib index against packet */
if (PREDICT_FALSE
- (t0 == 0 || flags0 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G)))
+ (t0 == NULL
+ || flags0 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G)))
{
- if (t0 != 0
+ if (t0 != NULL
&& flags0 != (VXLAN_GBP_FLAGS_I | VXLAN_GBP_FLAGS_G))
{
error0 = VXLAN_GBP_ERROR_BAD_FLAGS;
vlib_increment_combined_counter
- (drop_counter, thread_index, stats_t0->sw_if_index, 1,
- len0);
+ (drop_counter, thread_index, t0->sw_if_index, 1, len0);
next0 = VXLAN_GBP_INPUT_NEXT_DROP;
}
else
@@ -470,7 +459,7 @@ vxlan_gbp_input (vlib_main_t * vm,
pkts_decapsulated++;
vlib_increment_combined_counter
- (rx_counter, thread_index, stats_t0->sw_if_index, 1, len0);
+ (rx_counter, thread_index, t0->sw_if_index, 1, len0);
}
vnet_buffer2 (b0)->gbp.flags = vxlan_gbp_get_gpflags (vxlan_gbp0);
vnet_buffer2 (b0)->gbp.sclass = vxlan_gbp_get_sclass (vxlan_gbp0);
diff --git a/src/vnet/vxlan-gbp/vxlan_gbp.c b/src/vnet/vxlan-gbp/vxlan_gbp.c
index 691cc762549..db10f5448e4 100644
--- a/src/vnet/vxlan-gbp/vxlan_gbp.c
+++ b/src/vnet/vxlan-gbp/vxlan_gbp.c
@@ -394,7 +394,9 @@ int vnet_vxlan_gbp_tunnel_add_del
int not_found;
if (!is_ip6)
{
- key4.key[0] = a->dst.ip4.as_u32;
+ key4.key[0] = ip46_address_is_multicast (&a->dst) ?
+ a->dst.ip4.as_u32 :
+ a->dst.ip4.as_u32 | (((u64) a->src.ip4.as_u32) << 32);
key4.key[1] = (((u64) a->encap_fib_index) << 32)
| clib_host_to_net_u32 (a->vni << 8);
not_found =