21 u32 dst_address_u32,
u32 dst_address_length,
39 hash = _hash_set3 (hash, dst_address_u32,
77 u32 dst_address, dst_address_length, adj_index, old_adj_index;
106 dst_address_length, adj_index);
111 if (old_adj_index == adj_index
120 is_del ? old_adj_index : adj_index, is_del);
124 && old_adj_index != ~0 && old_adj_index != adj_index)
143 u32 address_length : 6;
151 ip4_route_t *routes = 0, *r;
162 x.address_length =
i;
168 x.address.data_u32 = p->
key;
178 memset (&a, 0,
sizeof (a));
211 ip_prefix_t * src_prefix,
u32 table_id,
218 u32 dst_address_length =
ip_prefix_len (dst_prefix), src_address_length = 0;
227 memset (&src, 0,
sizeof (src));
242 memset (&dst_adj, 0,
sizeof (dst_adj));
245 dst_adj.rewrite_header.sw_if_index = src_fib - lgm->
ip4_src_fibs;
258 dst_adj.
indirect.next_hop.ip4 = dst;
260 memset (&a, 0,
sizeof (a));
281 ASSERT (dst_adjp->rewrite_header.sw_if_index
282 == dst_adj.rewrite_header.sw_if_index);
291 (
"Trying to delete inexistent dst route for %U. Aborting",
300 memset (&a, 0,
sizeof (a));
313 if (CLIB_DEBUG && is_add)
318 &src, src_address_length);
328 dst_adjp->rewrite_header.sw_if_index);
339 memset (&a, 0,
sizeof (a));
356 ip_prefix_t * src_prefix,
u32 table_id)
360 u32 dst_address_length =
ip_prefix_len (dst_prefix), src_address_length = 0;
369 memset (&src, 0,
sizeof (src));
386 BVT (clib_bihash_kv) kv, value;
391 ASSERT (address_length <= 128);
397 kv.key[2] = address_length;
399 rv = BV (clib_bihash_search_inline_2) (&fib->ip6_lookup_table, &kv, &value);
415 int dst_address_length = 128 - i;
416 vec_add1 (fib->prefix_lengths_in_search_order, dst_address_length);
429 u32 dst_address_length, adj_index;
431 u32 old_adj_index = ~0;
432 BVT (clib_bihash_kv) kv, value;
461 128 - dst_address_length, 0);
471 128 - dst_address_length, 1);
475 kv.key[0] = dst_address.
as_u64[0];
476 kv.key[1] = dst_address.
as_u64[1];
477 kv.key[2] = dst_address_length;
480 old_adj_index = value.value;
490 kv.value = adj_index;
496 if (old_adj_index == adj_index
507 && old_adj_index != ~0 && old_adj_index != adj_index)
524 for (j = 0; j < i0; j++)
529 clib_host_to_net_u32 (
pow2_mask (i1) << (32 - i1));
547 ip_prefix_t * src_prefix,
u32 table_id,
554 u32 dst_address_length =
ip_prefix_len (dst_prefix), src_address_length = 0;
563 memset (&src, 0,
sizeof (src));
566 adj_index =
ip6_get_route (lgm->
im6, table_id, 0, &dst, dst_address_length);
575 memset (src_fib, 0,
sizeof (src_fib[0]));
578 memset (&dst_adj, 0,
sizeof (dst_adj));
581 dst_adj.rewrite_header.sw_if_index = src_fib - lgm->
ip6_src_fibs;
594 dst_adj.
indirect.next_hop.ip6 = dst;
596 memset (&a, 0,
sizeof (a));
617 ASSERT (dst_adjp->rewrite_header.sw_if_index
618 == dst_adj.rewrite_header.sw_if_index);
627 (
"Trying to delete inexistent dst route for %U. Aborting",
636 memset (&a, 0,
sizeof (a));
649 if (CLIB_DEBUG && is_add)
654 &src, src_address_length);
664 dst_adjp->rewrite_header.sw_if_index);
676 memset (&a, 0,
sizeof (a));
693 ip_prefix_t * src_prefix,
u32 table_id)
697 u32 dst_address_length =
ip_prefix_len (dst_prefix), src_address_length = 0;
706 memset (&src, 0,
sizeof (src));
709 adj_index =
ip6_get_route (lgm->
im6, table_id, 0, &dst, dst_address_length);
720 ip_prefix_t * src_prefix,
u32 table_id,
734 ip_prefix_t * src_prefix,
u32 table_id)
740 return (adj_index == 0) ? 0 : adj_index[0];
770 src_adj_index0[0] = ~0;
777 u32 * src_adj_index1)
784 (src_fib_index0 != (
u32) ~ 0 && src_fib_index1 != (
u32) ~ 0))
822 u32 n_left_from, next_index, *from, *to_next;
830 while (n_left_from > 0)
836 while (n_left_from >= 4 && n_left_to_next >= 2)
841 u32 dst_adj_index0, src_adj_index0, src_fib_index0;
842 u32 dst_adj_index1, src_adj_index1, src_fib_index1;
846 next0 = next1 = LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP;
884 src_fib_index0 = dst_adj0->rewrite_header.sw_if_index;
885 src_fib_index1 = dst_adj1->rewrite_header.sw_if_index;
889 &src_adj_index0, &src_adj_index1);
893 && (
u32) ~ 0 != src_adj_index1))
906 src_adj0->rewrite_header.sw_if_index;
908 src_adj1->rewrite_header.sw_if_index;
923 if ((
u32) ~ 0 != src_adj_index0)
929 src_adj0->rewrite_header.sw_if_index;
937 next0 = LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP;
940 if ((
u32) ~ 0 != src_adj_index1)
946 src_adj1->rewrite_header.sw_if_index;
953 next1 = LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP;
958 if (
PREDICT_FALSE (LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP == next0))
960 if (
PREDICT_FALSE (LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP == next1))
964 n_left_to_next, bi0, bi1, next0,
968 while (n_left_from > 0 && n_left_to_next > 0)
972 u32 bi0, dst_adj_index0, src_adj_index0, src_fib_index0;
973 u32 next0 = LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP;
989 src_fib_index0 = dst_adj0->rewrite_header.sw_if_index;
1004 src_adj0->rewrite_header.sw_if_index;
1014 next0 = LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP;
1017 if (
PREDICT_FALSE (LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP == next0))
1021 n_left_to_next, bi0, next0);
1031 .name =
"lgpe-ip4-lookup",
1032 .vector_size =
sizeof (
u32),
1038 #define _(sym,str) [LGPE_IP4_LOOKUP_NEXT_##sym] = str, 1051 BVT (clib_bihash_kv) kv, value;
1056 for (i = 0; i < len; i++)
1061 ASSERT (dst_address_length >= 0 && dst_address_length <= 128);
1063 mask = &fib->
fib_masks[dst_address_length];
1067 kv.key[2] = dst_address_length;
1070 BV (clib_bihash_search_inline_2) (&fib->ip6_lookup_table, &kv,
1087 src_adj_index0[0] = ~0;
1094 u32 * src_adj_index1)
1098 (src_fib_index0 != (
u32) ~ 0 && src_fib_index1 != (
u32) ~ 0))
1114 u32 n_left_from, next_index, *from, *to_next;
1122 while (n_left_from > 0)
1128 while (n_left_from >= 4 && n_left_to_next >= 2)
1133 u32 dst_adj_index0, src_adj_index0, src_fib_index0, dst_adj_index1,
1134 src_adj_index1, src_fib_index1;
1138 next0 = next1 = LGPE_IP6_LOOKUP_NEXT_LISP_CP_LOOKUP;
1160 n_left_to_next -= 2;
1176 src_fib_index0 = dst_adj0->rewrite_header.sw_if_index;
1177 src_fib_index1 = dst_adj1->rewrite_header.sw_if_index;
1181 &src_adj_index0, &src_adj_index1);
1185 && (
u32) ~ 0 != src_adj_index1))
1198 src_adj0->rewrite_header.sw_if_index;
1200 src_adj1->rewrite_header.sw_if_index;
1215 if (src_adj_index0 != (
u32) ~ 0)
1221 src_adj0->rewrite_header.sw_if_index;
1229 next0 = LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP;
1232 if (src_adj_index1 != (
u32) ~ 0)
1238 src_adj1->rewrite_header.sw_if_index;
1246 next1 = LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP;
1251 if (
PREDICT_FALSE (LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP == next0))
1253 if (
PREDICT_FALSE (LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP == next1))
1257 n_left_to_next, bi0, bi1, next0,
1261 while (n_left_from > 0 && n_left_to_next > 0)
1265 u32 bi0, dst_adj_index0, src_adj_index0, src_fib_index0;
1266 u32 next0 = LGPE_IP6_LOOKUP_NEXT_LISP_CP_LOOKUP;
1274 n_left_to_next -= 1;
1282 src_fib_index0 = dst_adj0->rewrite_header.sw_if_index;
1297 src_adj0->rewrite_header.sw_if_index;
1307 next0 = LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP;
1311 if (
PREDICT_FALSE (LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP == next0))
1315 n_left_to_next, bi0, next0);
1325 .name =
"lgpe-ip6-lookup",
1326 .vector_size =
sizeof (
u32),
1332 #define _(sym,str) [LGPE_IP6_LOOKUP_NEXT_##sym] = str,
struct ip_adjacency_t::@143::@147 indirect
IP_LOOKUP_NEXT_INDIRECT only.
static void ip6_address_mask(ip6_address_t *a, ip6_address_t *mask)
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
sll srl srl sll sra u16x4 i
u32 ip4_lookup_next_lgpe_ip4_lookup
u16 saved_lookup_next_index
Highest possible perf subgraph arc interposition, e.g.
static uword lgpe_ip6_lookup(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
u16 n_adj
Number of adjecencies in block.
ip_lookup_next_t lookup_next_index
#define ip_prefix_len(_a)
i32 dst_address_length_refcounts[129]
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
u32 share_count
Number of FIB entries sharing this adjacency.
ip_adjacency_t * ip_add_adjacency(ip_lookup_main_t *lm, ip_adjacency_t *copy_adj, u32 n_adj, u32 *adj_index_return)
static uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
ip6_address_t fib_masks[129]
#define vec_bytes(v)
Number of data bytes in vector.
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
static void ip6_src_fib_lookup_one(lisp_gpe_main_t *lgm, u32 src_fib_index0, ip6_address_t *addr0, u32 *src_adj_index0)
#define ip_prefix_version(_a)
static void vlib_smp_unsafe_warning(void)
#define IP4_FIB_MTRIE_LEAF_EMPTY
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static u8 ip4_fib_is_empty(ip4_fib_t *fib)
int clib_bihash_add_del(clib_bihash *h, clib_bihash_kv *add_v, int is_add)
Add or delete a (key,value) pair from a bi-hash table.
static uword pow2_mask(uword x)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define IP6_FIB_DEFAULT_HASH_NUM_BUCKETS
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)
static int ip6_sd_fib_add_del_route(lisp_gpe_main_t *lgm, ip_prefix_t *dst_prefix, ip_prefix_t *src_prefix, u32 table_id, ip_adjacency_t *add_adj, u8 is_add)
static int ip4_sd_fib_add_del_route(lisp_gpe_main_t *lgm, ip_prefix_t *dst_prefix, ip_prefix_t *src_prefix, u32 table_id, ip_adjacency_t *add_adj, u8 is_add)
static void ip4_src_fib_lookup_two(lisp_gpe_main_t *lgm, u32 src_fib_index0, u32 src_fib_index1, ip4_address_t *addr0, ip4_address_t *addr1, u32 *src_adj_index0, u32 *src_adj_index1)
#define clib_warning(format, args...)
u32 table_index_or_table_id
static uword lgpe_ip4_lookup(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
static void hash_set_flags(void *v, uword flags)
void ip6_add_del_route(ip6_main_t *im, ip6_add_del_route_args_t *args)
static uword hash_value_bytes(hash_t *h)
void ip_del_adjacency(ip_lookup_main_t *lm, u32 adj_index)
static u32 ip4_fib_mtrie_leaf_get_adj_index(ip4_fib_mtrie_leaf_t n)
ip6_src_fib_t * ip6_src_fibs
ip4_src_fib_t * ip4_src_fibs
static hash_t * hash_header(void *v)
ip6_address_t dst_address
#define clib_bitmap_foreach(i, ai, body)
Macro to iterate across set bits in a bitmap.
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
static void ip4_src_fib_lookup_one(lisp_gpe_main_t *lgm, u32 src_fib_index0, ip4_address_t *addr0, u32 *src_adj_index0)
u8 * prefix_lengths_in_search_order
typedef CLIB_PACKED(struct ip4_route{ip4_address_t address;u32 address_length:6;u32 index:26;})
void * ip4_get_route(ip4_main_t *im, u32 fib_index_or_table_id, u32 flags, u8 *address, u32 address_length)
#define IP6_FIB_DEFAULT_HASH_MEMORY_SIZE
#define pool_put(P, E)
Free an object E in pool P.
static u32 ip6_compute_flow_hash(ip6_header_t *ip, u32 flow_hash_config)
u32 ip6_lookup_next_lgpe_ip6_lookup
u32 ip6_get_route(ip6_main_t *im, u32 fib_index_or_table_id, u32 flags, ip6_address_t *address, u32 address_length)
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Finish enqueueing two buffers forward in the graph.
static ip4_fib_mtrie_leaf_t ip4_fib_mtrie_lookup_step(ip4_fib_mtrie_t *m, ip4_fib_mtrie_leaf_t current_leaf, ip4_address_t *dst_address, u32 dst_address_byte_index)
static void * ip4_sd_fib_get_route(lisp_gpe_main_t *lgm, ip_prefix_t *dst_prefix, ip_prefix_t *src_prefix, u32 table_id)
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
void clib_bihash_init(clib_bihash *h, char *name, u32 nbuckets, uword memory_size)
initialize a bounded index extensible hash table
static void ip6_src_fib_init(ip6_src_fib_t *fib)
static void * ip4_sd_get_src_route(lisp_gpe_main_t *lgm, u32 src_fib_index, ip4_address_t *src, u32 address_length)
#define IP6_ROUTE_FLAG_KEEP_OLD_ADJACENCY
void ip4_mtrie_init(ip4_fib_mtrie_t *m)
#define CLIB_PREFETCH(addr, size, type)
int ip_sd_fib_add_del_route(lisp_gpe_main_t *lgm, ip_prefix_t *dst_prefix, ip_prefix_t *src_prefix, u32 table_id, ip_adjacency_t *add_adj, u8 is_add)
u32 ip_sd_fib_get_route(lisp_gpe_main_t *lgm, ip_prefix_t *dst_prefix, ip_prefix_t *src_prefix, u32 table_id)
static void ip4_fib_init_adj_index_by_dst_address(ip_lookup_main_t *lm, ip4_fib_t *fib, u32 address_length)
static u32 ip6_src_fib_lookup(lisp_gpe_main_t *lgm, u32 src_fib_index, ip6_address_t *src)
#define IP6_ROUTE_FLAG_DEL
static uword round_pow2(uword x, uword pow2)
lisp_gpe_main_t lisp_gpe_main
#define IP4_ROUTE_FLAG_DEL
#define foreach_lgpe_ip4_lookup_next
#define hash_create(elts, value_bytes)
uword * non_empty_dst_address_length_bitmap
static uword hash_elts(void *v)
#define IP4_FIB_MTRIE_LEAF_ROOT
ip4_address_t dst_address
#define IP4_ROUTE_FLAG_ADD
int clib_bihash_search(clib_bihash *h, clib_bihash_kv *search_v, clib_bihash_kv *return_v)
Search a bi-hash table.
static void ip4_sd_fib_add_del_src_route(lisp_gpe_main_t *lgm, ip4_add_del_route_args_t *a)
#define foreach_lgpe_ip6_lookup_next
#define IP_FLOW_HASH_DEFAULT
Default: 5-tuple without the "reverse" bit.
u8 * format_ip_prefix(u8 *s, va_list *args)
static uword clib_bitmap_count_set_bits(uword *ai)
Return the number of set bits in a bitmap.
static void compute_prefix_lengths_in_search_order(ip6_src_fib_t *fib)
static void ip6_sd_fib_add_del_src_route(lisp_gpe_main_t *lgm, ip6_add_del_route_args_t *a)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define hash_foreach_pair(p, v, body)
static uword max_log2(uword x)
static void ip6_src_fib_lookup_two(lisp_gpe_main_t *lgm, u32 src_fib_index0, u32 src_fib_index1, ip6_address_t *addr0, ip6_address_t *addr1, u32 *src_adj_index0, u32 *src_adj_index1)
#define IP4_ROUTE_FLAG_FIB_INDEX
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
u32 table_index_or_table_id
#define IP4_ROUTE_FLAG_KEEP_OLD_ADJACENCY
static u32 ip4_compute_flow_hash(ip4_header_t *ip, u32 flow_hash_config)
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
#define VLIB_REGISTER_NODE(x,...)
#define IP4_ROUTE_FLAG_TABLE_ID
#define IP6_ROUTE_FLAG_ADD
u32 if_address_index
Interface address index for this local/arp adjacency.
#define vec_foreach(var, vec)
Vector iterator.
i16 explicit_fib_index
Force re-lookup in a different FIB.
u32 lookup_table_nbuckets
uword * adj_index_by_dst_address[33]
#define IP6_ROUTE_FLAG_TABLE_ID
void ip4_add_del_route(ip4_main_t *im, ip4_add_del_route_args_t *args)
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
#define CLIB_CACHE_LINE_BYTES
#define HASH_FLAG_NO_AUTO_SHRINK
static u32 ip6_sd_get_src_route(lisp_gpe_main_t *lgm, u32 src_fib_index, ip6_address_t *src, u32 address_length)
static void ip4_sd_fib_set_adj_index(lisp_gpe_main_t *lgm, ip4_fib_t *fib, u32 flags, u32 dst_address_u32, u32 dst_address_length, u32 adj_index)
static u32 ip6_sd_fib_get_route(lisp_gpe_main_t *lgm, ip_prefix_t *dst_prefix, ip_prefix_t *src_prefix, u32 table_id)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
u32 fib_result_n_bytes
Number of bytes in a fib result.
static ip_adjacency_t * ip_get_adjacency(ip_lookup_main_t *lm, u32 adj_index)
ip4_fib_mtrie_leaf_t default_leaf