49 #ifdef CLIB_HAVE_VEC128 66 for (l = p->leaves_as_u32x4; l < p->leaves_as_u32x4 +
ARRAY_LEN (p->leaves_as_u32x4); l += 4)
172 uword new_leaf_dst_address_bits)
194 __sync_val_compare_and_swap (&ply->
leaves[i], old_leaf, new_leaf);
206 u32 dst_address_byte_index)
209 i32 n_dst_bits_next_plies;
220 if (n_dst_bits_next_plies <= 0)
222 uword i, n_dst_bits_this_ply, old_leaf_is_terminal;
224 n_dst_bits_this_ply = -n_dst_bits_next_plies;
227 for (i = dst_byte; i < dst_byte + (1 << n_dst_bits_this_ply); i++)
241 if (old_leaf_is_terminal)
244 __sync_val_compare_and_swap (&old_ply->
leaves[i], old_leaf,
259 else if (! old_leaf_is_terminal)
271 old_leaf = old_ply->
leaves[dst_byte];
280 __sync_val_compare_and_swap (&old_ply->
leaves[dst_byte], old_leaf,
302 u32 dst_address_byte_index)
305 i32 n_dst_bits_next_plies;
306 uword i, n_dst_bits_this_ply, old_leaf_is_terminal;
315 if (n_dst_bits_next_plies < 0)
316 dst_byte &= ~
pow2_mask (-n_dst_bits_next_plies);
318 n_dst_bits_this_ply = n_dst_bits_next_plies <= 0 ? -n_dst_bits_next_plies : 0;
319 n_dst_bits_this_ply =
clib_min (8, n_dst_bits_this_ply);
323 for (i = dst_byte; i < dst_byte + (1 << n_dst_bits_this_ply); i++)
328 if (old_leaf == del_leaf
329 || (! old_leaf_is_terminal
356 memset (m, 0,
sizeof (m[0]));
365 u32 dst_address_length,
386 if (dst_address_length == 0)
393 if (dst_address_length == 0)
431 uword was_remapped_to_empty_leaf = 0;
438 was_remapped_to_empty_leaf = m == ~0;
439 if (was_remapped_to_empty_leaf)
440 p[0] = (was_remapped_to_empty_leaf
445 return was_remapped_to_empty_leaf;
450 u32 n_remapped_to_empty = 0;
454 if (n_remapped_to_empty > 0)
456 ASSERT (n_remapped_to_empty <= ply->n_non_empty_leafs);
482 bytes =
sizeof (p[0]);
509 u32 base_address = va_arg (*va,
u32);
510 u32 ply_index = va_arg (*va,
u32);
511 u32 dst_address_byte_index = va_arg (*va,
u32);
527 a = base_address + (i << (24 - 8*dst_address_byte_index));
528 ia.
as_u32 = clib_host_to_net_u32 (a);
532 ia_length = 8*(1 + dst_address_byte_index);
533 s =
format (s,
"\n%U%20U %U",
543 dst_address_byte_index + 1);
554 s =
format (s,
"%d plies, memory usage %U",
u8 dst_address_bits_of_leaves[256]
always_inline u32 ip4_fib_mtrie_leaf_is_terminal(ip4_fib_mtrie_leaf_t n)
sll srl srl sll sra u16x4 i
always_inline u32 ip4_fib_mtrie_leaf_get_next_ply_index(ip4_fib_mtrie_leaf_t n)
always_inline u32 ip4_fib_mtrie_leaf_get_adj_index(ip4_fib_mtrie_leaf_t n)
static void ply_free(ip4_fib_mtrie_t *m, ip4_fib_mtrie_ply_t *p)
add_epi add_epi sub_epi sub_epi adds_epu subs_epu i16x8 y
#define IP4_FIB_MTRIE_LEAF_EMPTY
void ip4_fib_free(ip4_fib_mtrie_t *m)
ip4_fib_mtrie_ply_t * ply_pool
#define pool_foreach(VAR, POOL, BODY)
always_inline ip4_fib_mtrie_leaf_t ip4_fib_mtrie_leaf_set_next_ply_index(u32 i)
u32 * adjacency_remap_table
always_inline u32x4 u32x4_splat(u32 a)
void ip4_fib_mtrie_add_del_route(ip4_fib_t *fib, ip4_address_t dst_address, u32 dst_address_length, u32 adj_index, u32 is_del)
always_inline uword maybe_remap_leaf(ip_lookup_main_t *lm, ip4_fib_mtrie_leaf_t *p)
always_inline uword pool_elts(void *v)
always_inline ip4_fib_mtrie_ply_t * get_next_ply_for_leaf(ip4_fib_mtrie_t *m, ip4_fib_mtrie_leaf_t l)
void ip4_mtrie_init(ip4_fib_mtrie_t *m)
static u8 * format_ip4_fib_mtrie_leaf(u8 *s, va_list *va)
#define pool_elt_at_index(p, i)
static void ply_init(ip4_fib_mtrie_ply_t *p, ip4_fib_mtrie_leaf_t init, uword prefix_len)
static uword unset_leaf(ip4_fib_mtrie_t *m, ip4_fib_mtrie_set_unset_leaf_args_t *a, ip4_fib_mtrie_ply_t *old_ply, u32 dst_address_byte_index)
u8 * format_ip4_fib_mtrie(u8 *s, va_list *va)
static void set_leaf(ip4_fib_mtrie_t *m, ip4_fib_mtrie_set_unset_leaf_args_t *a, u32 old_ply_index, u32 dst_address_byte_index)
ip4_address_t dst_address
#define pool_get_aligned(P, E, A)
static void set_ply_with_more_specific_leaf(ip4_fib_mtrie_t *m, ip4_fib_mtrie_ply_t *ply, ip4_fib_mtrie_leaf_t new_leaf, uword new_leaf_dst_address_bits)
#define pool_is_free_index(P, I)
always_inline u32 ip4_fib_mtrie_leaf_is_next_ply(ip4_fib_mtrie_leaf_t n)
static uword mtrie_memory_usage(ip4_fib_mtrie_t *m, ip4_fib_mtrie_ply_t *p)
always_inline u32 ip4_fib_mtrie_leaf_is_empty(ip4_fib_mtrie_leaf_t n)
ip4_fib_mtrie_leaf_t leaves[256]
static ip4_fib_mtrie_leaf_t ply_create(ip4_fib_mtrie_t *m, ip4_fib_mtrie_leaf_t init_leaf, uword prefix_len)
#define vec_elt(v, i)
Get vector value at index i.
always_inline u32 ip4_fib_mtrie_leaf_is_non_empty(ip4_fib_mtrie_leaf_t n)
static void maybe_remap_ply(ip_lookup_main_t *lm, ip4_fib_mtrie_ply_t *ply)
always_inline ip4_fib_mtrie_leaf_t ip4_fib_mtrie_leaf_set_adj_index(u32 adj_index)
u32 ip4_mtrie_lookup_address(ip4_fib_mtrie_t *m, ip4_address_t dst)
uword * adj_index_by_dst_address[33]
always_inline uword pow2_mask(uword x)
void ip4_mtrie_maybe_remap_adjacencies(ip_lookup_main_t *lm, ip4_fib_mtrie_t *m)
static u8 * format_ip4_fib_mtrie_ply(u8 *s, va_list *va)
ip4_fib_mtrie_leaf_t default_leaf