classify hash used to be stored as u64 in buffer metadata, use 32 bits
instead:
- on almost all our supported arch (x86 and arm64) we use crc32c
intrinsics to compute the final hash: we really get a 32-bits hash
- the hash itself is used to compute a 32-bits bucket index by masking
upper bits: we always discard the higher 32-bits
- this allows to increase the l2 classify buffer metadata padding such
as it does not overlap with the ip fib_index metadata anymore. This
overlap is an issue when using the 'set metadata' action in the ip
ACL node which updates both fields
Type: fix
Change-Id: I5d35bdae97b96c3cae534e859b63950fb500ff50
Signed-off-by: Benoît Ganne <bganne@cisco.com>
/* L2 classify */
struct
{
/* L2 classify */
struct
{
+ u32 pad[4]; /* do not overlay w/ ip.fib_index nor l2 */
union
{
u32 table_index;
u32 opaque_index;
};
union
{
u32 table_index;
u32 opaque_index;
};
} l2_classify;
/* vnet policer */
} l2_classify;
/* vnet policer */
u32 table_index0;
vnet_classify_table_t *t0;
vnet_classify_entry_t *e0;
u32 table_index0;
vnet_classify_table_t *t0;
vnet_classify_entry_t *e0;
u8 *h0;
/* Stride 3 seems to work best */
u8 *h0;
/* Stride 3 seems to work best */
vlib_buffer_t *p1 = vlib_get_buffer (vm, from[3]);
vnet_classify_table_t *tp1;
u32 table_index1;
vlib_buffer_t *p1 = vlib_get_buffer (vm, from[3]);
vnet_classify_table_t *tp1;
u32 table_index1;
table_index1 = vnet_buffer (p1)->l2_classify.table_index;
table_index1 = vnet_buffer (p1)->l2_classify.table_index;
u32 table_index0;
vnet_classify_table_t *t0;
vnet_classify_entry_t *e0;
u32 table_index0;
vnet_classify_table_t *t0;
vnet_classify_entry_t *e0;
u8 *h0;
/* Stride 3 seems to work best */
u8 *h0;
/* Stride 3 seems to work best */
vlib_buffer_t *p1 = vlib_get_buffer (vm, from[3]);
vnet_classify_table_t *tp1;
u32 table_index1;
vlib_buffer_t *p1 = vlib_get_buffer (vm, from[3]);
vnet_classify_table_t *tp1;
u32 table_index1;
table_index1 = vnet_buffer (p1)->l2_classify.table_index;
table_index1 = vnet_buffer (p1)->l2_classify.table_index;
u32 value_index;
int rv = 0;
int i;
u32 value_index;
int rv = 0;
int i;
u32 limit;
u32 old_log2_pages, new_log2_pages;
u32 thread_index = vlib_get_thread_index ();
u32 limit;
u32 old_log2_pages, new_log2_pages;
u32 thread_index = vlib_get_thread_index ();
}) classify_data_or_mask_t;
/* *INDENT-ON* */
}) classify_data_or_mask_t;
/* *INDENT-ON* */
-u64
-vnet_classify_hash_packet (vnet_classify_table_t * t, u8 * h)
+u32
+vnet_classify_hash_packet (const vnet_classify_table_t *t, u8 *h)
{
return vnet_classify_hash_packet_inline (t, h);
}
vnet_classify_entry_t *
{
return vnet_classify_hash_packet_inline (t, h);
}
vnet_classify_entry_t *
-vnet_classify_find_entry (vnet_classify_table_t * t,
- u8 * h, u64 hash, f64 now)
+vnet_classify_find_entry (const vnet_classify_table_t *t, u8 *h, u32 hash,
+ f64 now)
{
return vnet_classify_find_entry_inline (t, h, hash, now);
}
{
return vnet_classify_find_entry_inline (t, h, hash, now);
}
for (i = 0; i < tm->sessions; i++)
{
u8 *key_minus_skip;
for (i = 0; i < tm->sessions; i++)
{
u8 *key_minus_skip;
vnet_classify_entry_t *e;
ep = tm->entries + i;
vnet_classify_entry_t *e;
ep = tm->entries + i;
u8 *format_classify_table (u8 * s, va_list * args);
u8 *format_vnet_classify_table (u8 *s, va_list *args);
u8 *format_classify_table (u8 * s, va_list * args);
u8 *format_vnet_classify_table (u8 *s, va_list *args);
-u64 vnet_classify_hash_packet (vnet_classify_table_t * t, u8 * h);
+u32 vnet_classify_hash_packet (const vnet_classify_table_t *t, u8 *h);
static_always_inline vnet_classify_table_t *
vnet_classify_table_get (u32 table_index)
static_always_inline vnet_classify_table_t *
vnet_classify_table_get (u32 table_index)
return (pool_elt_at_index (vcm->tables, table_index));
}
return (pool_elt_at_index (vcm->tables, table_index));
}
-static inline u64
-vnet_classify_hash_packet_inline (vnet_classify_table_t *t, const u8 *h)
+static inline u32
+vnet_classify_hash_packet_inline (const vnet_classify_table_t *t, const u8 *h)
{
u64 xor_sum;
ASSERT (t);
{
u64 xor_sum;
ASSERT (t);
}
static inline vnet_classify_entry_t *
}
static inline vnet_classify_entry_t *
-vnet_classify_get_entry (vnet_classify_table_t * t, uword offset)
+vnet_classify_get_entry (const vnet_classify_table_t *t, uword offset)
{
u8 *hp = clib_mem_get_heap_base (t->mheap);
u8 *vp = hp + offset;
{
u8 *hp = clib_mem_get_heap_base (t->mheap);
u8 *vp = hp + offset;
}
static inline vnet_classify_entry_t *
}
static inline vnet_classify_entry_t *
-vnet_classify_entry_at_index (vnet_classify_table_t * t,
- vnet_classify_entry_t * e, u32 index)
+vnet_classify_entry_at_index (const vnet_classify_table_t *t,
+ vnet_classify_entry_t *e, u32 index)
clib_prefetch_load (e);
}
clib_prefetch_load (e);
}
-vnet_classify_entry_t *vnet_classify_find_entry (vnet_classify_table_t * t,
- u8 * h, u64 hash, f64 now);
+vnet_classify_entry_t *
+vnet_classify_find_entry (const vnet_classify_table_t *t, u8 *h, u32 hash,
+ f64 now);
static_always_inline int
vnet_classify_entry_is_equal (vnet_classify_entry_t *v, const u8 *d, u8 *m,
static_always_inline int
vnet_classify_entry_is_equal (vnet_classify_entry_t *v, const u8 *d, u8 *m,
}
static inline vnet_classify_entry_t *
}
static inline vnet_classify_entry_t *
-vnet_classify_find_entry_inline (vnet_classify_table_t *t, const u8 *h,
- u64 hash, f64 now)
+vnet_classify_find_entry_inline (const vnet_classify_table_t *t, const u8 *h,
+ u32 hash, f64 now)
{
vnet_classify_entry_t *v;
vnet_classify_bucket_t *b;
{
vnet_classify_entry_t *v;
vnet_classify_bucket_t *b;
s = format (s,
"l2_classify.table_index: %d, l2_classify.opaque_index: %d, "
s = format (s,
"l2_classify.table_index: %d, l2_classify.opaque_index: %d, "
- "l2_classify.hash: 0x%llx",
- o->l2_classify.table_index,
- o->l2_classify.opaque_index, o->l2_classify.hash);
+ "l2_classify.hash: 0x%lx",
+ o->l2_classify.table_index, o->l2_classify.opaque_index,
+ o->l2_classify.hash);
vec_add1 (s, '\n');
s = format (s, "policer.index: %d", o->policer.index);
vec_add1 (s, '\n');
s = format (s, "policer.index: %d", o->policer.index);
u32 sw_if_index[4];
u32 table_index[4];
vnet_classify_table_t *t[4] = { 0, 0 };
u32 sw_if_index[4];
u32 table_index[4];
vnet_classify_table_t *t[4] = { 0, 0 };
/* calculate hashes for b[0] & b[1] */
if (n_left >= 2)
/* calculate hashes for b[0] & b[1] */
if (n_left >= 2)
if (is_output)
{
/* Save the rewrite length, since we are using the l2_classify struct */
if (is_output)
{
/* Save the rewrite length, since we are using the l2_classify struct */
- vnet_buffer (b[0])->l2_classify.pad.l2_len =
+ vnet_buffer (b[0])->l2.l2_len =
vnet_buffer (b[0])->ip.save_rewrite_length;
/* advance the match pointer so the matching happens on IP header */
vnet_buffer (b[0])->ip.save_rewrite_length;
/* advance the match pointer so the matching happens on IP header */
- h[2] += vnet_buffer (b[0])->l2_classify.pad.l2_len;
+ h[2] += vnet_buffer (b[0])->l2.l2_len;
/* Save the rewrite length, since we are using the l2_classify struct */
/* Save the rewrite length, since we are using the l2_classify struct */
- vnet_buffer (b[1])->l2_classify.pad.l2_len =
+ vnet_buffer (b[1])->l2.l2_len =
vnet_buffer (b[1])->ip.save_rewrite_length;
/* advance the match pointer so the matching happens on IP header */
vnet_buffer (b[1])->ip.save_rewrite_length;
/* advance the match pointer so the matching happens on IP header */
- h[3] += vnet_buffer (b[1])->l2_classify.pad.l2_len;
+ h[3] += vnet_buffer (b[1])->l2.l2_len;
}
hash[2] = vnet_classify_hash_packet_inline (t[2], (u8 *) h[2]);
}
hash[2] = vnet_classify_hash_packet_inline (t[2], (u8 *) h[2]);
if (is_output)
{
/* Save the rewrite length, since we are using the l2_classify struct */
if (is_output)
{
/* Save the rewrite length, since we are using the l2_classify struct */
- vnet_buffer (b[2])->l2_classify.pad.l2_len =
+ vnet_buffer (b[2])->l2.l2_len =
vnet_buffer (b[2])->ip.save_rewrite_length;
/* advance the match pointer so the matching happens on IP header */
vnet_buffer (b[2])->ip.save_rewrite_length;
/* advance the match pointer so the matching happens on IP header */
- h[2] += vnet_buffer (b[2])->l2_classify.pad.l2_len;
+ h[2] += vnet_buffer (b[2])->l2.l2_len;
/* Save the rewrite length, since we are using the l2_classify struct */
/* Save the rewrite length, since we are using the l2_classify struct */
- vnet_buffer (b[3])->l2_classify.pad.l2_len =
+ vnet_buffer (b[3])->l2.l2_len =
vnet_buffer (b[3])->ip.save_rewrite_length;
/* advance the match pointer so the matching happens on IP header */
vnet_buffer (b[3])->ip.save_rewrite_length;
/* advance the match pointer so the matching happens on IP header */
- h[3] += vnet_buffer (b[3])->l2_classify.pad.l2_len;
+ h[3] += vnet_buffer (b[3])->l2.l2_len;
}
hash[2] = vnet_classify_hash_packet_inline (t[2], (u8 *) h[2]);
}
hash[2] = vnet_classify_hash_packet_inline (t[2], (u8 *) h[2]);
/* advance the match pointer so the matching happens on IP header */
if (is_output)
/* advance the match pointer so the matching happens on IP header */
if (is_output)
- h[0] += vnet_buffer (b[0])->l2_classify.pad.l2_len;
+ h[0] += vnet_buffer (b[0])->l2.l2_len;
hash[0] =
vnet_classify_hash_packet_inline (t[0], (u8 *) h[0]);
hash[0] =
vnet_classify_hash_packet_inline (t[0], (u8 *) h[0]);
/* advance the match pointer so the matching happens on IP header */
if (is_output)
/* advance the match pointer so the matching happens on IP header */
if (is_output)
- h[1] += vnet_buffer (b[1])->l2_classify.pad.l2_len;
+ h[1] += vnet_buffer (b[1])->l2.l2_len;
hash[1] =
vnet_classify_hash_packet_inline (t[1], (u8 *) h[1]);
hash[1] =
vnet_classify_hash_packet_inline (t[1], (u8 *) h[1]);
vnet_classify_table_t *t0 = 0;
vnet_classify_entry_t *e0 = 0;
u32 next0 = ACL_NEXT_INDEX_DENY;
vnet_classify_table_t *t0 = 0;
vnet_classify_entry_t *e0 = 0;
u32 next0 = ACL_NEXT_INDEX_DENY;
sw_if_index0 = ~0 == way ? 0 : vnet_buffer (b[0])->sw_if_index[way];
table_index0 = table_index_by_sw_if_index[sw_if_index0];
sw_if_index0 = ~0 == way ? 0 : vnet_buffer (b[0])->sw_if_index[way];
table_index0 = table_index_by_sw_if_index[sw_if_index0];
if (is_output)
{
/* Save the rewrite length, since we are using the l2_classify struct */
if (is_output)
{
/* Save the rewrite length, since we are using the l2_classify struct */
- vnet_buffer (b[0])->l2_classify.pad.l2_len =
+ vnet_buffer (b[0])->l2.l2_len =
vnet_buffer (b[0])->ip.save_rewrite_length;
/* advance the match pointer so the matching happens on IP header */
vnet_buffer (b[0])->ip.save_rewrite_length;
/* advance the match pointer so the matching happens on IP header */
- h0 += vnet_buffer (b[0])->l2_classify.pad.l2_len;
+ h0 += vnet_buffer (b[0])->l2.l2_len;
}
vnet_buffer (b[0])->l2_classify.hash =
}
vnet_buffer (b[0])->l2_classify.hash =
/* advance the match pointer so the matching happens on IP header */
if (is_output)
/* advance the match pointer so the matching happens on IP header */
if (is_output)
- h0 += vnet_buffer (b[0])->l2_classify.pad.l2_len;
+ h0 += vnet_buffer (b[0])->l2.l2_len;
e0 = vnet_classify_find_entry_inline (t0, (u8 *) h0, hash0, now);
if (e0)
e0 = vnet_classify_find_entry_inline (t0, (u8 *) h0, hash0, now);
if (e0)
/* advance the match pointer so the matching happens on IP header */
if (is_output)
/* advance the match pointer so the matching happens on IP header */
if (is_output)
- h0 += vnet_buffer (b[0])->l2_classify.pad.l2_len;
+ h0 += vnet_buffer (b[0])->l2.l2_len;
hash0 = vnet_classify_hash_packet_inline (t0, (u8 *) h0);
e0 = vnet_classify_find_entry_inline
hash0 = vnet_classify_hash_packet_inline (t0, (u8 *) h0);
e0 = vnet_classify_find_entry_inline
u32 table_index0;
vnet_classify_table_t *t0;
vnet_classify_entry_t *e0;
u32 table_index0;
vnet_classify_table_t *t0;
vnet_classify_entry_t *e0;
vlib_buffer_t *p1 = vlib_get_buffer (vm, from[3]);
vnet_classify_table_t *tp1;
u32 table_index1;
vlib_buffer_t *p1 = vlib_get_buffer (vm, from[3]);
vnet_classify_table_t *tp1;
u32 table_index1;
table_index1 = vnet_buffer (p1)->l2_classify.table_index;
table_index1 = vnet_buffer (p1)->l2_classify.table_index;
int type_index0, type_index1;
vnet_classify_table_t *t0, *t1;
u32 table_index0, table_index1;
int type_index0, type_index1;
vnet_classify_table_t *t0, *t1;
u32 table_index0, table_index1;
/* prefetch next iteration */
{
/* prefetch next iteration */
{
u32 type_index0;
vnet_classify_table_t *t0;
u32 table_index0;
u32 type_index0;
vnet_classify_table_t *t0;
u32 table_index0;
bi0 = from[0];
b0 = vlib_get_buffer (vm, bi0);
bi0 = from[0];
b0 = vlib_get_buffer (vm, bi0);
u32 next0 = ~0; /* next l2 input feature, please... */
ethernet_header_t *h0;
u32 table_index0;
u32 next0 = ~0; /* next l2 input feature, please... */
ethernet_header_t *h0;
u32 table_index0;
vnet_classify_table_t *t0;
vnet_classify_entry_t *e0;
if (PREDICT_TRUE (n_left_from > 2))
{
vlib_buffer_t *p2 = vlib_get_buffer (vm, from[2]);
vnet_classify_table_t *t0;
vnet_classify_entry_t *e0;
if (PREDICT_TRUE (n_left_from > 2))
{
vlib_buffer_t *p2 = vlib_get_buffer (vm, from[2]);
u32 table_index2;
vnet_classify_table_t *tp2;
u32 table_index2;
vnet_classify_table_t *tp2;
int type_index0, type_index1;
vnet_classify_table_t *t0, *t1;
u32 table_index0, table_index1;
int type_index0, type_index1;
vnet_classify_table_t *t0, *t1;
u32 table_index0, table_index1;
/* prefetch next iteration */
{
/* prefetch next iteration */
{
u32 type_index0;
vnet_classify_table_t *t0;
u32 table_index0;
u32 type_index0;
vnet_classify_table_t *t0;
u32 table_index0;
bi0 = from[0];
b0 = vlib_get_buffer (vm, bi0);
bi0 = from[0];
b0 = vlib_get_buffer (vm, bi0);
u32 next0 = ~0;
ethernet_header_t *h0;
u32 table_index0;
u32 next0 = ~0;
ethernet_header_t *h0;
u32 table_index0;
vnet_classify_table_t *t0;
vnet_classify_entry_t *e0;
if (PREDICT_TRUE (n_left_from > 2))
{
vlib_buffer_t *p2 = vlib_get_buffer (vm, from[2]);
vnet_classify_table_t *t0;
vnet_classify_entry_t *e0;
if (PREDICT_TRUE (n_left_from > 2))
{
vlib_buffer_t *p2 = vlib_get_buffer (vm, from[2]);
u32 table_index2;
vnet_classify_table_t *tp2;
u32 table_index2;
vnet_classify_table_t *tp2;
u32 table_index0;
vnet_classify_table_t *t0;
vnet_classify_entry_t *e0;
u32 table_index0;
vnet_classify_table_t *t0;
vnet_classify_entry_t *e0;
vlib_buffer_t *p1 = vlib_get_buffer (vm, from[3]);
vnet_classify_table_t *tp1;
u32 table_index1;
vlib_buffer_t *p1 = vlib_get_buffer (vm, from[3]);
vnet_classify_table_t *tp1;
u32 table_index1;
table_index1 = vnet_buffer (p1)->l2_classify.table_index;
table_index1 = vnet_buffer (p1)->l2_classify.table_index;