55 memset (adj, 0xfe, n_adj *
sizeof (adj[0]));
58 adj->
n_adj = save_n_adj;
103 if (this_ai == adj_index)
121 while (this_adj != adj)
170 u32 * adj_index_return)
176 if (copy_adj && n_adj == 1)
213 *adj_index_return = p[0];
232 for (i = 0; i < n_adj; i++)
235 adj[
i].rewrite_header.sw_if_index = ~0;
243 adj[
i] = copy_adj[
i];
255 if (copy_adj && n_adj == 1)
258 *adj_index_return = ai;
276 clib_memcpy (&adj->rewrite_header, ©_adj->rewrite_header,
306 if (delete_multipath_adjacency)
324 : (cmp > 0 ? +1 : -1));
335 uword n_nhs, n_adj, n_adj_left,
i;
336 f64 sum_weight, norm, error;
338 n_nhs =
vec_len (raw_next_hops);
344 nhs = *normalized_next_hops;
351 nhs[0] = raw_next_hops[0];
362 nhs[0] = raw_next_hops[cmp];
363 nhs[1] = raw_next_hops[cmp ^ 1];
366 if (nhs[0].weight == nhs[1].weight)
375 clib_memcpy (nhs, raw_next_hops, n_nhs *
sizeof (raw_next_hops[0]));
381 for (i = 0; i < n_nhs; i++)
382 sum_weight += nhs[i].weight;
387 for (i = 0; i < n_nhs; i++)
393 for (i = 0; i < n_nhs; i++)
394 nhs[n_nhs + i].weight = nhs[i].weight;
398 for (n_adj =
max_pow2 (n_nhs); ; n_adj *= 2)
402 norm = n_adj / sum_weight;
404 for (i = 0; i < n_nhs; i++)
409 n = n > n_adj_left ? n_adj_left : n;
411 error +=
fabs (nf - n);
415 nhs[0].
weight += n_adj_left;
418 if (error <= lm->multipath_next_hop_error_tolerance*n_adj)
428 *normalized_next_hops = nhs;
434 {
return 1 + 2*handle; }
450 uword create_if_non_existent)
453 u32 i, j, n_adj, adj_index, adj_heap_handle;
469 if (! create_if_non_existent)
480 for (j = 0; j < nh->
weight; j++)
482 adj[
i] = copy_adj[0];
515 raw_next_hops,
vec_bytes (raw_next_hops));
519 return adj_heap_handle;
526 u32 old_mp_adj_index,
527 u32 next_hop_adj_index,
529 u32 * new_mp_adj_index)
561 for (i_nh = 0; i_nh < n_nhs; i_nh++)
562 if (nhs[i_nh].next_hop_adj_index == next_hop_adj_index)
566 if (i_nh >= n_nhs && is_del)
572 _vec_len (hash_nhs) = 0;
580 vec_add (hash_nhs, nhs + 0, i_nh);
581 if (i_nh + 1 < n_nhs)
582 vec_add (hash_nhs, nhs + i_nh + 1, n_nhs - (i_nh + 1));
588 if (i_nh < n_nhs && nhs[i_nh].weight == next_hop_weight)
590 new_mp_adj_index[0] = ~0;
596 vec_add (hash_nhs, nhs, n_nhs);
611 nh->
weight = next_hop_weight;
628 if (mp_new != mp_old)
655 u32 i, n_nhs, madj_index, new_madj_index;
670 for (i = 0; i < n_nhs; i++)
671 if (nhs[i].next_hop_adj_index == del_adj_index)
683 _vec_len (hash_nhs) = 0;
685 vec_add (hash_nhs, nhs + 0, i);
687 vec_add (hash_nhs, nhs + i + 1, n_nhs - (i + 1));
693 if (new_madj_index == madj_index)
715 memset (a, 0,
sizeof (a[0]));
735 *n_next_hops = n_nhs;
760 return n0 == n1 && ! memcmp (k0, k1, n0 *
sizeof (k0[0]));
769 u32 * result_if_address_index)
779 if ((a && (address_length != a->
address_length)) || (address_length == 0))
781 vnm->
api_errno = VNET_API_ERROR_ADDRESS_LENGTH_MISMATCH;
783 (
"%U wrong length (expected %d) for interface %U",
794 vnm->
api_errno = VNET_API_ERROR_ADDRESS_NOT_FOUND_FOR_INTERFACE;
797 addr_fib, address_length,
822 if (result_if_address_index)
823 *result_if_address_index = ~0;
833 memset (a, ~0,
sizeof (a[0]));
838 while (pi != (
u32)~0)
856 (hi != ~0) ? hi : ai;
857 if (result_if_address_index)
858 *result_if_address_index = ai;
862 if (result_if_address_index)
880 memset (&template_adj, 0,
sizeof (template_adj));
923 sizeof (ip6_address_fib_t));
936 for (i = 0; i < 256; i++)
953 u32 flow_hash_config = va_arg (*args,
u32);
955 #define _(n,v) if (flow_hash_config & v) s = format (s, "%s ", #n); 1002 u32 if_address_index = va_arg (*args,
u32);
1043 u32 adj_index = va_arg (*args,
u32);
1053 s =
format(s,
" %U", reg->
fn, lm, adj);
1064 sizeof (adj->rewrite_data));
1071 if (adj->
arp.next_hop.ip6.as_u64[0] || adj->
arp.next_hop.ip6.as_u64[1])
1109 u32 adj_index = va_arg (*args,
u32);
1110 u8 * packet_data = va_arg (*args,
u8 *);
1111 u32 n_packet_data_bytes = va_arg (*args,
u32);
1119 vnm->
vlib_main, &adj->rewrite_header, packet_data, n_packet_data_bytes);
1140 else if (
unformat (input,
"local"))
1146 else if (
unformat (input,
"classify"))
1160 u32 node_index = va_arg (*args,
u32);
1162 u32 sw_if_index, is_ip6;
1167 adj->rewrite_header.node_index = node_index;
1185 if (a_adj->rewrite_header.sw_if_index != sw_if_index)
1204 clib_warning (
"classify adj must specify table index");
1210 adj->rewrite_header.node_index = 0;
1216 vm, &adj->rewrite_header, sizeof (adj->rewrite_data)))
1230 u32 table_id, is_del;
1231 u32 weight, * weights = 0;
1232 u32 * table_ids = 0;
1233 u32 sw_if_index, * sw_if_indices = 0;
1234 ip4_address_t ip4_addr, * ip4_dst_addresses = 0, * ip4_via_next_hops = 0;
1235 ip6_address_t ip6_addr, * ip6_dst_addresses = 0, * ip6_via_next_hops = 0;
1236 u32 dst_address_length, * dst_address_lengths = 0;
1250 memset(&parse_adj, 0,
sizeof (parse_adj));
1254 if (
unformat (line_input,
"table %d", &table_id))
1256 else if (
unformat (line_input,
"del"))
1258 else if (
unformat (line_input,
"add"))
1260 else if (
unformat (line_input,
"count %f", &count))
1263 else if (
unformat (line_input,
"%U/%d",
1265 &dst_address_length))
1267 vec_add1 (ip4_dst_addresses, ip4_addr);
1268 vec_add1 (dst_address_lengths, dst_address_length);
1271 else if (
unformat (line_input,
"%U/%d",
1273 &dst_address_length))
1275 vec_add1 (ip6_dst_addresses, ip6_addr);
1276 vec_add1 (dst_address_lengths, dst_address_length);
1279 else if (
unformat (line_input,
"via %U %U weight %u",
1284 vec_add1 (ip4_via_next_hops, ip4_addr);
1285 vec_add1 (sw_if_indices, sw_if_index);
1290 else if (
unformat (line_input,
"via %U %U weight %u",
1295 vec_add1 (ip6_via_next_hops, ip6_addr);
1296 vec_add1 (sw_if_indices, sw_if_index);
1301 else if (
unformat (line_input,
"via %U %U",
1305 vec_add1 (ip4_via_next_hops, ip4_addr);
1306 vec_add1 (sw_if_indices, sw_if_index);
1311 else if (
unformat (line_input,
"via %U %U",
1315 vec_add1 (ip6_via_next_hops, ip6_addr);
1316 vec_add1 (sw_if_indices, sw_if_index);
1320 else if (
unformat (line_input,
"via %U",
1323 vec_add1 (ip4_via_next_hops, ip4_addr);
1328 else if (
unformat (line_input,
"via %U",
1331 vec_add1 (ip6_via_next_hops, ip6_addr);
1337 else if (
vec_len (ip4_dst_addresses) > 0
1342 else if (
vec_len (ip6_dst_addresses) > 0
1346 else if (
unformat (line_input,
"lookup in table %d", &outer_table_id))
1350 if (
vec_len (ip4_dst_addresses) > 0)
1375 if (
vec_len (ip4_dst_addresses) +
vec_len (ip6_dst_addresses) == 0)
1381 if (
vec_len (ip4_dst_addresses) > 0 &&
vec_len (ip6_dst_addresses) > 0)
1387 if (
vec_len (ip4_dst_addresses) > 0 &&
vec_len (ip6_via_next_hops) > 0)
1393 if (
vec_len (ip6_dst_addresses) > 0 &&
vec_len (ip4_via_next_hops) > 0)
1410 for (i = 0; i <
vec_len (ip4_dst_addresses); i++)
1414 memset (&a, 0,
sizeof (a));
1423 if (vec_len (ip4_via_next_hops) == 0)
1425 uword * dst_hash, * dst_result;
1426 u32 dst_address_u32;
1438 dst_result =
hash_get (dst_hash, dst_address_u32);
1455 u32 i, j, n, f, incr;
1461 for (i = 0; i < n; i++)
1465 for (j = 0; j <
vec_len (ip4_via_next_hops); j++)
1467 if (table_ids[j] != (
u32)~0)
1477 table_ids[j] = p[0];
1484 &ip4_via_next_hops[j],
1486 weights[j], (
u32)~0,
1489 dst.
as_u32 = clib_host_to_net_u32 (incr + clib_net_to_host_u32 (dst.
as_u32));
1498 if (vec_len (add_adj) > 0)
1506 else if (vec_len (ip4_via_next_hops) > 0)
1508 u32 i, j, n, f, incr;
1514 for (i = 0; i < n; i++)
1518 for (j = 0; j <
vec_len (ip4_via_next_hops); j++)
1520 if (table_ids[j] != (
u32)~0)
1530 table_ids[j] = p[0];
1536 &ip4_via_next_hops[j],
1538 weights[j], (
u32)~0,
1541 dst.
as_u32 = clib_host_to_net_u32 (incr + clib_net_to_host_u32 (dst.
as_u32));
1550 for (i = 0; i <
vec_len (ip6_dst_addresses); i++)
1555 memset (&a, 0,
sizeof (a));
1564 if (vec_len (ip6_via_next_hops) == 0)
1566 BVT(clib_bihash_kv) kv, value;
1575 dst_address = ip6_dst_addresses[
i];
1580 kv.key[0] = dst_address.
as_u64[0];
1581 kv.key[1] = dst_address.
as_u64[1];
1582 kv.key[2] = ((
u64)(fib - im6->
fibs)<<32)
1604 for (i = 0; i <
vec_len (ip6_via_next_hops); i++)
1610 &ip6_via_next_hops[i],
1612 weights[i], (
u32)~0,
1619 if (vec_len (add_adj) > 0)
1627 else if (vec_len (ip6_via_next_hops) > 0)
1630 for (i = 0; i <
vec_len (ip6_via_next_hops); i++)
1636 &ip6_via_next_hops[i],
1638 weights[i], (
u32)~0,
1659 .short_help =
"Internet protocol (IP) commands",
1664 .short_help =
"Internet protocol (IP) show commands",
1669 .short_help =
"Internet protocol version 4 (IP4) show commands",
1674 .short_help =
"Internet protocol version 6 (IP6) show commands",
1706 .short_help =
"Add/delete IP routes",
1725 uword *event_data = 0;
1729 if (retry_count > 0)
1734 for (i = 0; i < retry_count; i++)
1778 uword *event_data = 0;
1782 if (retry_count > 0)
1787 for (i = 0; i < retry_count; i++)
1834 u32 sw_if_index = ~0;
1835 int retry_count = 3;
1837 int address_set = 0;
1848 else if (
unformat (line_input,
"retry %d", &retry_count))
1865 if (sw_if_index == ~0)
1867 if (address_set == 0)
1869 if (address_set > 1)
1881 .path =
"ip probe-neighbor",
1883 .short_help =
"ip probe-neighbor <intfc> <ip4-addr> | <ip6-addr> [retry nn]",
1890 u32 address_length : 6;
1896 ip4_route_cmp (
void * a1,
void * a2)
1898 ip4_route_t * r1 = a1;
1899 ip4_route_t * r2 = a2;
1902 return cmp ? cmp : ((int) r1->address_length - (
int) r2->address_length);
1910 ip4_route_t * routes, * r;
1914 int verbose, matching, mtrie, include_empty_fibs;
1922 include_empty_fibs = 0;
1931 else if (
unformat (input,
"mtrie"))
1934 else if (
unformat (input,
"include-empty"))
1935 include_empty_fibs = 1;
1940 else if (
unformat (input,
"clear"))
1943 else if (
unformat (input,
"table %d", &table_id))
1965 if (fib_not_empty == 0 && include_empty_fibs == 0)
1968 if (table_id >= 0 && table_id != (
int)fib->
table_id)
1971 if (include_empty_fibs)
1979 if (include_empty_fibs == 0)
1995 _vec_len (routes) = 0;
1997 _vec_len (results) = 0;
2005 x.address_length =
i;
2019 x.index = p->
value[0];
2026 x.address.data_u32 = p->
key;
2029 x.index = vec_len (results);
2030 vec_add (results, p->value, lm->fib_result_n_words);
2033 x.index = p->
value[0];
2042 if (include_empty_fibs == 0)
2049 "Destination",
"Packets",
"Bytes",
"Adjacency");
2054 uword i, j, n_left, n_nhs, adj_index, * result = 0;
2058 adj_index = r->index;
2062 adj_index = result[0];
2066 if (adj->
n_adj == 1)
2083 for (i = j = 0; i < adj->
n_adj; i++)
2098 msg =
format (msg,
"%-20U",
2100 r->address.data, r->address_length);
2107 msg =
format (msg,
"weight %d, index %d",
2108 nhs[j].weight, adj_index + i);
2111 msg =
format (msg,
", multipath");
2113 msg =
format (msg,
"\n%U%U",
2116 vnm, lm, adj_index + i);
2169 .path =
"show ip fib",
2170 .short_help =
"show ip fib [mtrie] [summary] [table <n>] [<ip4-addr>] [clear] [include-empty]",
2199 r->
index = kvp->value;
2205 u64 count_by_prefix_length[129];
2209 (
BVT(clib_bihash_kv) * kvp,
void *arg)
2217 mask_width = kvp->key[2] & 0xFF;
2242 BVT(clib_bihash) * h = &im6->ip6_lookup_table;
2243 __attribute__((unused))
u8 clear = 0;
2274 memset (ca, 0,
sizeof(*ca));
2280 for (len = 128; len >= 0; len--)
2290 _vec_len (routes) = 0;
2292 _vec_len (results) = 0;
2302 "Destination",
"Packets",
"Bytes",
"Adjacency");
2306 uword i, j, n_left, n_nhs, adj_index, * result = 0;
2310 adj_index = r->
index;
2314 adj_index = result[0];
2318 if (adj->
n_adj == 1)
2335 for (i = j = 0; i < adj->
n_adj; i++)
2350 msg =
format (msg,
"%-45U",
2359 msg =
format (msg,
"weight %d, index %d",
2360 nhs[j].weight, adj_index + i);
2363 msg =
format (msg,
", multipath");
2365 msg =
format (msg,
"\n%U%U",
2368 vnm, lm, adj_index + i);
2405 .path =
"show ip6 fib",
2406 .short_help =
"show ip6 fib [summary] [clear]",
struct ip_adjacency_t::@143::@147 indirect
IP_LOOKUP_NEXT_INDIRECT only.
static clib_error_t * ip6_probe_neighbor_wait(vlib_main_t *vm, ip6_address_t *a, u32 sw_if_index, int retry_count)
uword * multipath_adjacency_by_next_hops
Hash table mapping normalized next hops and weights to multipath adjacency index. ...
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static void ip6_address_mask(ip6_address_t *a, ip6_address_t *mask)
static void ip_call_add_del_adjacency_callbacks(ip_lookup_main_t *lm, u32 adj_index, u32 is_del)
format_function_t * format_fib_result
ip_lookup_next_t
Common (IP4/IP6) next index stored in adjacency.
ip4_fib_t * find_ip4_fib_by_table_index_or_id(ip4_main_t *im, u32 table_index_or_id, u32 flags)
Get or create an IPv4 fib.
char * node_name
Name of the node for this registered adjacency.
u64 packets
packet counter
#define hash_set(h, key, value)
sll srl srl sll sra u16x4 i
static uword ip_next_hop_hash_key_is_heap_handle(uword k)
void vlib_validate_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
validate a combined counter
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
ip_adjacency_t * adjacency_heap
Adjacency heap.
#define hash_unset(h, key)
u16 saved_lookup_next_index
Highest possible perf subgraph arc interposition, e.g.
void ip4_add_del_route_next_hop(ip4_main_t *im, u32 flags, ip4_address_t *dst_address, u32 dst_address_length, ip4_address_t *next_hop, u32 next_hop_sw_if_index, u32 next_hop_weight, u32 adj_index, u32 explicit_fib_index)
static u32 ip_multipath_normalize_next_hops(ip_lookup_main_t *lm, ip_multipath_next_hop_t *raw_next_hops, ip_multipath_next_hop_t **normalized_next_hops)
static vlib_main_t * vlib_get_main(void)
ip_interface_address_t * if_address_pool
Pool of addresses that are assigned to interfaces.
static clib_error_t * ip4_probe_neighbor_wait(vlib_main_t *vm, ip4_address_t *a, u32 sw_if_index, int retry_count)
u16 n_adj
Number of adjecencies in block.
format_function_t * fn
Formatting function for the adjacency.
static int ip6_route_cmp(void *a1, void *a2)
ip_lookup_next_t lookup_next_index
ip_adjacency_t * aa_bootstrap(ip_adjacency_t *adjs, u32 n)
static int ip_adjacency_is_multipath(ip_lookup_main_t *lm, u32 adj_index)
u32 miss_adj_index
Adjacency index for routing table misses, local punts, and drops.
uword mhash_unset(mhash_t *h, void *key, uword *old_value)
ip_adjacency_t * aa_alloc(ip_adjacency_t *adjs, ip_adjacency_t **blockp, u32 n)
static f64 vlib_time_now(vlib_main_t *vm)
void aa_free(ip_adjacency_t *adjs, ip_adjacency_t *adj)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
vlib_node_registration_t ip6_rewrite_node
(constructor) VLIB_REGISTER_NODE (ip6_rewrite_node)
u32 share_count
Number of FIB entries sharing this adjacency.
u32 special_adjacency_format_function_index
Special format function for this adjacency.
#define heap_elt_at_index(v, index)
ip_adjacency_t * ip_add_adjacency(ip_lookup_main_t *lm, ip_adjacency_t *copy_adj, u32 n_adj, u32 *adj_index_return)
Combined counter to hold both packets and byte differences.
static uword unformat_ip_adjacency(unformat_input_t *input, va_list *args)
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
u32 * next_index
When the adjacency is registered, the ip-lookup next index will be written where this pointer points...
#define STRUCT_OFFSET_OF(t, f)
ip_lookup_main_t lookup_main
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
unformat_function_t unformat_vnet_sw_interface
static int vnet_ip_adjacency_share_compare(ip_adjacency_t *a1, ip_adjacency_t *a2)
static void vlib_counter_zero(vlib_counter_t *a)
Clear a combined counter.
static uword ip_next_hop_hash_key_sum(hash_t *h, uword key0)
void ip4_maybe_remap_adjacencies(ip4_main_t *im, u32 table_index_or_table_id, u32 flags)
#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).
mhash_t address_to_if_address_index
Hash table mapping address to index in interface address pool.
format_function_t format_vnet_sw_if_index_name
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
u8 * format_mheap(u8 *s, va_list *va)
clib_error_t * vnet_ip_route_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
This structure is used to dynamically register a custom adjacency for ip lookup.
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
Adjacency to drop this packet.
static uword ip_next_hop_hash_key_get_heap_handle(uword k)
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
static ip_multipath_next_hop_t * ip_next_hop_hash_key_get_next_hops(ip_lookup_main_t *lm, uword k, uword *n_next_hops)
u8 * format_ip_lookup_next(u8 *s, va_list *args)
vnet_main_t * vnet_get_main(void)
static u32 ip_multipath_adjacency_get(ip_lookup_main_t *lm, ip_multipath_next_hop_t *raw_next_hops, uword create_if_non_existent)
u32 next_adj_with_signature
Use this adjacency instead.
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
static clib_error_t * ip6_show_fib(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
void ip6_adjacency_set_interface_route(vnet_main_t *vnm, ip_adjacency_t *adj, u32 sw_if_index, u32 if_address_index)
u32 * adjacency_remap_table
uword * adj_index_by_signature
Adjacency by signature hash.
ip6_fib_t * find_ip6_fib_by_table_index_or_id(ip6_main_t *im, u32 table_index_or_id, u32 flags)
Get or create an IPv6 fib.
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
u32 ip_multipath_adjacency_add_del_next_hop(ip_lookup_main_t *lm, u32 is_del, u32 old_mp_adj_index, u32 next_hop_adj_index, u32 next_hop_weight, u32 *new_mp_adj_index)
Adjacency to punt this packet.
static u8 * format_ip_interface_address(u8 *s, va_list *args)
#define clib_warning(format, args...)
u32 table_index_or_table_id
#define hash_get_pair(h, key)
static uword unformat_ip_lookup_next(unformat_input_t *input, va_list *args)
This packet is for one of our own IP addresses.
format_function_t format_vnet_rewrite
static void vlib_counter_add(vlib_counter_t *a, vlib_counter_t *b)
Add two combined counters, results in the first counter.
void ip6_add_del_route(ip6_main_t *im, ip6_add_del_route_args_t *args)
void ip_del_adjacency(ip_lookup_main_t *lm, u32 adj_index)
static uword pointer_to_uword(const void *p)
void ip4_adjacency_set_interface_route(vnet_main_t *vnm, ip_adjacency_t *adj, u32 sw_if_index, u32 if_address_index)
clib_error_t * ip6_probe_neighbor(vlib_main_t *vm, ip6_address_t *dst, u32 sw_if_index)
u32 lookup_table_nbuckets
void ip_multipath_adjacency_free(ip_lookup_main_t *lm, ip_multipath_adjacency_t *a)
clib_error_t * ip4_probe_neighbor(vlib_main_t *vm, ip4_address_t *dst, u32 sw_if_index)
vnet_api_error_t api_errno
#define VLIB_BUFFER_PRE_DATA_SIZE
ip6_address_t dst_address
static int next_hop_sort_by_weight(ip_multipath_next_hop_t *n1, ip_multipath_next_hop_t *n2)
static uword vnet_ip_adjacency_signature(ip_adjacency_t *adj)
format_function_t format_vnet_sw_interface_name
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
static void vlib_zero_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
Clear a combined counter Clears the set of per-thread u16 counters, and the shared vlib_counter_t...
void ip6_maybe_remap_adjacencies(ip6_main_t *im, u32 table_index_or_table_id, u32 flags)
uword * fib_index_by_table_id
Hash table mapping table id to fib index.
This packet needs to go to MAP - RFC7596, RFC7597.
#define pool_put(P, E)
Free an object E in pool P.
int ip6_address_compare(ip6_address_t *a1, ip6_address_t *a2)
static void vlib_get_combined_counter(vlib_combined_counter_main_t *cm, u32 index, vlib_counter_t *result)
Get the value of a combined counter, never called in the speed path Scrapes the entire set of mini co...
struct ip_adj_register_struct * next
u8 local_next_by_ip_protocol[256]
Table mapping ip protocol to ip[46]-local node next index.
#define clib_error_create(args...)
static void ip_share_adjacency(ip_lookup_main_t *lm, u32 adj_index)
u8 * format_ip_adjacency(u8 *s, va_list *args)
Pretty print helper function for formatting specific adjacencies.
static uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
unformat_function_t unformat_vnet_rewrite
#define IP_LOOKUP_MISS_ADJ_INDEX
Miss adjacency is always first in adjacency table.
#define uword_to_pointer(u, type)
typedef CLIB_PACKED(struct{ip4_address_t address;u32 address_length:6;u32 index:26;})
uword * fib_index_by_table_id
This packet needs to be classified.
struct ip_multipath_adjacency_t::@148 normalized_next_hops
ip6_address_t fib_masks[129]
void clib_bihash_foreach_key_value_pair(clib_bihash *h, void *callback, void *arg)
Visit active (key,value) pairs in a bi-hash table.
void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
vlib_node_registration_t ip4_rewrite_node
(constructor) VLIB_REGISTER_NODE (ip4_rewrite_node)
static void ip_del_adjacency2(ip_lookup_main_t *lm, u32 adj_index, u32 delete_multipath_adjacency)
static vlib_process_t * vlib_get_current_process(vlib_main_t *vm)
ip_adj_register_t * registered_adjacencies
Registered adjacencies.
int ip4_address_compare(ip4_address_t *a1, ip4_address_t *a2)
static void add_routes_in_fib(BVT(clib_bihash_kv)*kvp, void *arg)
static void ip_multipath_del_adjacency(ip_lookup_main_t *lm, u32 del_adj_index)
#define vec_free(V)
Free vector's memory (no header).
#define clib_memcpy(a, b, c)
static u32 ip4_fib_lookup(ip4_main_t *im, u32 sw_if_index, ip4_address_t *dst)
#define IP6_ROUTE_FLAG_DEL
static uword max_pow2(uword x)
static uword * mhash_get(mhash_t *h, void *key)
void ip_lookup_init(ip_lookup_main_t *lm, u32 is_ip6)
format_function_t format_vnet_rewrite_header
This packet matches an "interface route" and packets need to be passed to ARP to find rewrite string ...
void vnet_register_ip4_arp_resolution_event(vnet_main_t *vnm, void *address_arg, uword node_index, uword type_opaque, uword data)
struct ip_adjacency_t::@143::@146 classify
IP_LOOKUP_NEXT_CLASSIFY only.
void ip6_add_del_route_next_hop(ip6_main_t *im, u32 flags, ip6_address_t *dst_address, u32 dst_address_length, ip6_address_t *next_hop, u32 next_hop_sw_if_index, u32 next_hop_weight, u32 adj_index, u32 explicit_fib_index)
struct ip_multipath_adjacency_t::@148 unnormalized_next_hops
#define IP4_ROUTE_FLAG_DEL
vlib_combined_counter_main_t adjacency_counters
Adjacency packet/byte counters indexed by adjacency index.
u8 builtin_protocol_by_ip_protocol[256]
IP_BUILTIN_PROTOCOL_{TCP,UDP,ICMP,OTHER} by protocol in IP header.
#define hash_create2(_elts, _user, _value_bytes,_key_sum, _key_equal,_format_pair, _format_pair_arg)
static void count_routes_in_fib_at_prefix_length(BVT(clib_bihash_kv)*kvp, void *arg)
#define foreach_flow_hash_bit
u32 * if_address_pool_index_by_sw_if_index
Head of doubly linked list of interface addresses for each software interface.
#define hash_create(elts, value_bytes)
static uword hash_elts(void *v)
ip_multipath_next_hop_t * next_hop_hash_lookup_key
Temporary vectors for looking up next hops in hash.
static uword ip_next_hop_hash_key_from_handle(uword handle)
ip4_fib_t * fibs
Vector of FIBs.
ip4_address_t dst_address
#define IP4_ROUTE_FLAG_ADD
#define heap_elt_with_handle(v, handle)
ip_lookup_main_t lookup_main
int clib_bihash_search(clib_bihash *h, clib_bihash_kv *search_v, clib_bihash_kv *return_v)
Search a bi-hash table.
void heap_dealloc(void *v, uword handle)
uword hash_memory(void *p, word n_bytes, uword state)
int ip_init_registered_adjacencies(u8 is_ip4)
static clib_error_t * ip4_show_fib(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define heap_alloc(v, size, handle)
void ip_update_adjacency(ip_lookup_main_t *lm, u32 adj_index, ip_adjacency_t *copy_adj)
uword heap_len(void *v, word handle)
static void ip_poison_adjacencies(ip_adjacency_t *adj, uword n_adj)
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
void vnet_register_ip6_neighbor_resolution_event(vnet_main_t *vnm, void *address_arg, uword node_index, uword type_opaque, uword data)
VLIB_CLI_COMMAND(set_interface_ip_source_and_port_range_check_command, static)
static word flt_round_nearest(f64 x)
format_function_t format_ip4_fib_mtrie
void qsort(void *base, uword n, uword size, int(*compar)(const void *, const void *))
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
format_function_t ** special_adjacency_format_functions
Special adjacency format functions.
static uword ip_next_hop_hash_key_equal(hash_t *h, uword key0, uword key1)
#define hash_foreach_pair(p, v, body)
u32 heap_handle
Handle for this adjacency in adjacency heap.
int ip_register_adjacency(vlib_main_t *vm, u8 is_ip4, ip_adj_register_t *reg)
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
u32 is_ip6
1 for ip6; 0 for ip4.
Packet does not match any route in table.
u32 table_index_or_table_id
clib_error_t * ip_interface_address_add_del(ip_lookup_main_t *lm, u32 sw_if_index, void *addr_fib, u32 address_length, u32 is_del, u32 *result_if_address_index)
static void ip_unshare_adjacency(ip_lookup_main_t *lm, u32 adj_index)
#define hash_get_mem(h, key)
#define IP4_ROUTE_FLAG_NOT_LAST_IN_GROUP
static uword vlib_in_process_context(vlib_main_t *vm)
ip_multipath_next_hop_t * next_hop_heap
Heap of (next hop, weight) blocks.
ip_multipath_adjacency_t * multipath_adjacencies
Indexed by heap_handle from ip_adjacency_t.
ip4_main_t ip4_main
Global ip4 main structure.
This packets needs to go to indirect next hop.
#define IP4_ROUTE_FLAG_TABLE_ID
This packet is to be rewritten and forwarded to the next processing node.
#define IP6_ROUTE_FLAG_ADD
u32 if_address_index
Interface address index for this local/arp adjacency.
u64 count_by_prefix_length[129]
#define vec_foreach(var, vec)
Vector iterator.
struct ip_adjacency_t::@143::@145 arp
IP_LOOKUP_NEXT_ARP only.
i16 explicit_fib_index
Force re-lookup in a different FIB.
u32 vnet_register_special_adjacency_format_function(ip_lookup_main_t *lm, format_function_t *fp)
#define CLIB_MEMORY_BARRIER()
ip_multipath_next_hop_t * next_hop_hash_lookup_key_normalized
uword * adj_index_by_dst_address[33]
#define clib_error_return(e, args...)
#define IP6_ROUTE_FLAG_TABLE_ID
u8 * format_ip_flow_hash_config(u8 *s, va_list *args)
static void * ip_interface_address_get_address(ip_lookup_main_t *lm, ip_interface_address_t *a)
void ip4_add_del_route(ip4_main_t *im, ip4_add_del_route_args_t *args)
This packet needs to go to MAP with Translation - RFC7599.
static clib_error_t * probe_neighbor_address(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u8 * format_ip_adjacency_packet_data(u8 *s, va_list *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
f64 multipath_next_hop_error_tolerance
If average error per adjacency is less than this threshold adjacency block size is accepted...
u32 fib_result_n_bytes
Number of bytes in a fib result.
u32 ip6_fib_lookup(ip6_main_t *im, u32 sw_if_index, ip6_address_t *dst)
static ip_adjacency_t * ip_get_adjacency(ip_lookup_main_t *lm, u32 adj_index)
u32 next_this_sw_interface
format_function_t * format_address_and_length
Either format_ip4_address_and_length or format_ip6_address_and_length.
u32 prev_this_sw_interface