32 ip4_udp_lisp_gpe_header_t *h0;
37 h0 = (ip4_udp_lisp_gpe_header_t *) rw;
51 h0->udp.src_port = clib_host_to_net_u16 (4341);
52 h0->udp.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_lisp_gpe);
60 ip6_udp_lisp_gpe_header_t *h0;
65 h0 = (ip6_udp_lisp_gpe_header_t *) rw;
70 clib_host_to_net_u32 (0x6 << 28);
79 h0->udp.src_port = clib_host_to_net_u16 (4341);
80 h0->udp.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_lisp_gpe);
90 lisp0->
iid = clib_host_to_net_u32 (t->
vni);
112 uword n_sts,
i, n_nsts, n_nsts_left;
113 f64 sum_weight, norm, error, tolerance;
125 for (i = 0; i < n_sts; i++)
147 for (i = 0; i < n_nsts; i++)
148 nsts[n_nsts + i].weight = nsts[i].weight;
152 for (n_nsts =
max_pow2 (n_sts);; n_nsts *= 2)
156 norm = n_nsts / sum_weight;
157 n_nsts_left = n_nsts;
158 for (i = 0; i < n_sts; i++)
163 n = n > n_nsts_left ? n_nsts_left : n;
165 error +=
fabs (nf - n);
169 nsts[0].
weight += n_nsts_left;
172 if (error <= tolerance * n_nsts)
185 for (i = 0; i < stp[0].weight; i++)
186 vec_add1 (st_lbv, stp[0].sub_tunnel_index);
218 #define foreach_copy_field \ 221 _(decap_next_index) \ 236 memset (&key, 0,
sizeof (key));
244 key.
vni = clib_host_to_net_u32 (a->
vni);
252 return VNET_API_ERROR_INVALID_VALUE;
255 return VNET_API_ERROR_INVALID_DECAP_NEXT;
258 memset (t, 0,
sizeof (*t));
261 #define _(x) t->x = a->x; 269 t->
flags = LISP_GPE_FLAGS_I;
272 t->
flags |= LISP_GPE_FLAGS_P;
289 tun_index_res[0] = t - lgm->
tunnels;
298 return VNET_API_ERROR_NO_SUCH_ENTRY;
320 u32 vni,
u32 tun_index,
u32 n_sub_tun,
u8 is_negative,
321 u8 action,
u8 ip_ver)
323 uword *lookup_next_index, *lgpe_sw_if_index, *lnip;
325 memset (adj, 0,
sizeof (adj[0]));
337 lnip = (ip_ver ==
IP4) ?
340 lookup_next_index =
hash_get (lnip, table_id);
345 ASSERT (lookup_next_index != 0 && lgpe_sw_if_index != 0);
352 adj->rewrite_header.sw_if_index = lgpe_sw_if_index[0];
358 adj->rewrite_header.sw_if_index = ~0;
359 adj->rewrite_header.next_index = ~0;
372 LGPE_IP4_LOOKUP_NEXT_LISP_CP_LOOKUP :
373 LGPE_IP6_LOOKUP_NEXT_LISP_CP_LOOKUP;
378 LGPE_IP4_LOOKUP_NEXT_DROP :
379 LGPE_IP6_LOOKUP_NEXT_DROP);
394 u32 rv, tun_index = ~0, n_sub_tuns = 0;
395 ip_prefix_t *rmt_pref, *lcl_pref;
433 if (CLIB_DEBUG && a->
is_add)
452 kv->key[0] = (((
u64) bd_index) << 48) |
mac_to_u64 (dst_mac);
462 BVT (clib_bihash_kv) kv, value;
465 rv = BV (clib_bihash_search_inline_2) (&lgm->l2_fib, &kv, &value);
471 rv = BV (clib_bihash_search_inline_2) (&lgm->l2_fib, &kv, &value);
481 u8 dst_mac[6],
u32 val,
u8 is_add)
483 BVT (clib_bihash_kv) kv, value;
489 old_val = value.value;
548 return VNET_API_ERROR_LISP_DISABLED;
559 clib_warning (
"Forwarding entries for type %d not supported!", type);
571 ip_address_t lloc, rloc;
574 u8 reid_set = 0, leid_set = 0, is_negative = 0, vrf_set = 0, vni_set = 0;
575 u32 vni, vrf, action = ~0, p, w;
587 else if (
unformat (line_input,
"add"))
597 else if (
unformat (line_input,
"vni %u", &vni))
603 else if (
unformat (line_input,
"vrf %u", &vrf))
607 else if (
unformat (line_input,
"negative action %U",
612 else if (
unformat (line_input,
"loc-pair %U %U p %d w %d",
630 if (!vni_set || !vrf_set)
669 memset (a, 0,
sizeof (a[0]));
682 is_add ?
"add" :
"delete");
692 .path =
"lisp gpe tunnel",
693 .short_help =
"lisp gpe tunnel add/del vni <vni> vrf <vrf> [leid <leid>]" 694 "reid <reid> [lloc <sloc> rloc <rloc>] [negative action <action>]",
702 u32 next_index = va_arg (*args,
u32);
706 case LISP_GPE_INPUT_NEXT_DROP:
707 return format (s,
"drop");
708 case LISP_GPE_INPUT_NEXT_IP4_INPUT:
710 case LISP_GPE_INPUT_NEXT_IP6_INPUT:
713 return format (s,
"unknown %d", next_index);
729 format (s,
" fibs: encap %d, decap %d decap next %U\n",
734 #define _(n,v) if (t->flags & v) s = format (s, "%s-bit ", #n); 738 s =
format (s,
"next_protocol %d ver_res %x res %x\n",
741 s =
format (s,
" locator-pairs:\n");
744 s =
format (s,
" local: %U remote: %U weight %d\n",
749 s =
format (s,
" active sub-tunnels:\n");
773 vlib_cli_output (vm,
"%U", format_lisp_gpe_tunnel, t);
783 .path =
"show lisp gpe tunnel",
829 u32 *dp_tables = 0, *dp_table;
838 vec_add1(tunnels, tunnel[0]);
844 memset (at, 0,
sizeof (at[0]));
850 &tunnel->rmt.ippref);
865 vec_add1(dp_tables, p->key);
880 _vec_len (dp_tables) = 0;
884 vec_add1(dp_tables, p->key);
891 ai->
bd_id = dp_table[0];
920 if (
unformat (line_input,
"enable"))
922 else if (
unformat (line_input,
"disable"))
937 .short_help =
"lisp gpe [enable|disable]",
954 vlib_cli_output (vm,
"%=10d%=10d", p->key, p->value[0]);
963 vlib_cli_output (vm,
"%=10d%=10d", p->key, p->value[0]);
972 .path =
"show lisp gpe interface",
973 .short_help =
"show lisp gpe interface",
982 return format (s,
"%s", lgm->
is_en ?
"enabled" :
"disabled");
static int add_del_ip_tunnel(vnet_lisp_gpe_add_del_fwd_entry_args_t *a, u8 is_l2, u32 *tun_index_res)
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static int build_ip_adjacency(lisp_gpe_main_t *lgm, ip_adjacency_t *adj, u32 table_id, u32 vni, u32 tun_index, u32 n_sub_tun, u8 is_negative, u8 action, u8 ip_ver)
#define gid_address_ip_version(_a)
vlib_node_registration_t lisp_gpe_ip4_input_node
(constructor) VLIB_REGISTER_NODE (lisp_gpe_ip4_input_node)
sll srl srl sll sra u16x4 i
#define gid_address_type(_a)
u32 ip4_lookup_next_lgpe_ip4_lookup
u16 saved_lookup_next_index
Highest possible perf subgraph arc interposition, e.g.
u8 vnet_lisp_gpe_enable_disable_status(void)
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
int vnet_lisp_gpe_add_del_fwd_entry(vnet_lisp_gpe_add_del_fwd_entry_args_t *a, u32 *hw_if_indexp)
clib_error_t * vnet_lisp_gpe_enable_disable(vnet_lisp_gpe_enable_disable_args_t *a)
uword mhash_unset(mhash_t *h, void *key, uword *old_value)
lisp_gpe_tunnel_t * tunnels
#define L2_FIB_DEFAULT_HASH_NUM_BUCKETS
#define mhash_foreach(k, v, mh, body)
uword unformat_ip_address(unformat_input_t *input, va_list *args)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
static clib_error_t * show_lisp_gpe_tunnel_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
ip_lookup_main_t lookup_main
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
uword * lgpe_ip6_lookup_next_index_by_table_id
#define ip_prefix_version(_a)
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
vlib_node_registration_t ip4_lookup_node
(constructor) VLIB_REGISTER_NODE (ip4_lookup_node)
uword unformat_negative_mapping_action(unformat_input_t *input, va_list *args)
static lisp_gpe_main_t * vnet_lisp_gpe_get_main()
vnet_main_t * vnet_get_main(void)
#define foreach_copy_field
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
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.
#define VLIB_INIT_FUNCTION(x)
#define L2_FIB_DEFAULT_HASH_MEMORY_SIZE
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
static foreach_gid_address_type_fcns u64 mac_to_u64(u8 *m)
#define clib_warning(format, args...)
void ip_address_copy_addr(void *dst, ip_address_t *src)
#define vlib_call_init_function(vm, x)
static void compute_sub_tunnels_balancing_vector(lisp_gpe_tunnel_t *t)
Computes sub tunnel load balancing vector.
uword * bd_index_by_bd_id
#define ip_addr_version(_a)
vlib_node_registration_t lisp_gpe_ip6_input_node
(constructor) VLIB_REGISTER_NODE (lisp_gpe_ip6_input_node)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
mhash_t lisp_gpe_tunnel_by_key
static void make_mac_fib_key(BVT(clib_bihash_kv)*kv, u16 bd_index, u8 src_mac[6], u8 dst_mac[6])
u32 lisp_l2_fib_lookup(lisp_gpe_main_t *lgm, u16 bd_index, u8 src_mac[6], u8 dst_mac[6])
static int add_del_l2_fwd_entry(lisp_gpe_main_t *lgm, vnet_lisp_gpe_add_del_fwd_entry_args_t *a)
#define gid_address_mac(_a)
#define pool_put(P, E)
Free an object E in pool P.
#define vec_dup(V)
Return copy of vector (no header, no alignment)
u32 ip6_lookup_next_lgpe_ip6_lookup
uword unformat_gid_address(unformat_input_t *input, va_list *args)
u8 * format_gid_address(u8 *s, va_list *args)
static uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
static void l2_fib_init(lisp_gpe_main_t *lgm)
void clib_bihash_init(clib_bihash *h, char *name, u32 nbuckets, uword memory_size)
initialize a bounded index extensible hash table
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
#define gid_address_ippref(_a)
uword * sw_if_index_by_vni
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P (general version).
u32 sub_tunnels_lbv_count
clib_error_t * ip_main_init(vlib_main_t *vm)
void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
vlib_node_registration_t lgpe_ip4_lookup_node
(constructor) VLIB_REGISTER_NODE (lgpe_ip4_lookup_node)
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)
#define vec_free(V)
Free vector's memory (no header).
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 clib_error_t * lisp_show_iface_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
tunnel_lookup_t l2_ifaces
static int add_del_ip_fwd_entry(lisp_gpe_main_t *lgm, vnet_lisp_gpe_add_del_fwd_entry_args_t *a)
static uword max_pow2(uword x)
static uword * mhash_get(mhash_t *h, void *key)
int vnet_lisp_gpe_add_del_iface(vnet_lisp_gpe_add_del_iface_args_t *a, u32 *hw_if_indexp)
lisp_gpe_main_t lisp_gpe_main
vlib_node_registration_t ip6_lookup_node
(constructor) VLIB_REGISTER_NODE (ip6_lookup_node)
struct _gid_address_t gid_address_t
u8 * format_vnet_lisp_gpe_status(u8 *s, va_list *args)
u8 * format_ip_address(u8 *s, va_list *args)
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.
locator_pair_t * locator_pairs
clib_error_t * lisp_gpe_init(vlib_main_t *vm)
uword * hw_if_index_by_dp_table
static int lisp_gpe_rewrite(lisp_gpe_tunnel_t *t, lisp_gpe_sub_tunnel_t *st, locator_pair_t *lp)
vlib_node_registration_t lgpe_ip6_lookup_node
(constructor) VLIB_REGISTER_NODE (lgpe_ip6_lookup_node)
clib_error_t * ip4_lookup_init(vlib_main_t *vm)
normalized_sub_tunnel_weights_t * norm_sub_tunnel_weights
#define gid_address_vni(_a)
VLIB_CLI_COMMAND(set_interface_ip_source_and_port_range_check_command, static)
static word flt_round_nearest(f64 x)
void qsort(void *base, uword n, uword size, int(*compar)(const void *, const void *))
static clib_error_t * lisp_gpe_enable_disable_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
tunnel_lookup_t l3_ifaces
#define hash_foreach_pair(p, v, body)
static uword max_log2(uword x)
u32 lisp_l2_fib_add_del_entry(lisp_gpe_main_t *lgm, u16 bd_index, u8 src_mac[6], u8 dst_mac[6], u32 val, u8 is_add)
locator_pair_t * locator_pairs
void gid_address_copy(gid_address_t *dst, gid_address_t *src)
void mac_copy(void *dst, void *src)
static u8 * format_decap_next(u8 *s, va_list *args)
ip4_main_t ip4_main
Global ip4 main structure.
u32 if_address_index
Interface address index for this local/arp adjacency.
#define vec_foreach(var, vec)
Vector iterator.
static int weight_cmp(normalized_sub_tunnel_weights_t *a, normalized_sub_tunnel_weights_t *b)
i16 explicit_fib_index
Force re-lookup in a different FIB.
u8 * format_lisp_gpe_tunnel(u8 *s, va_list *args)
void udp_register_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u32 node_index, u8 is_ip4)
#define clib_error_return(e, args...)
static void create_sub_tunnels(lisp_gpe_main_t *lgm, lisp_gpe_tunnel_t *t)
#define CLIB_CACHE_LINE_BYTES
void ip_prefix_copy(void *dst, void *src)
uword * lgpe_ip4_lookup_next_index_by_table_id
static u16 ip4_header_checksum(ip4_header_t *i)
static ip_adjacency_t * ip_get_adjacency(ip_lookup_main_t *lm, u32 adj_index)
static clib_error_t * lisp_gpe_add_del_fwd_entry_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
lisp_gpe_sub_tunnel_t * sub_tunnels
static uword pool_elts(void *v)
Number of active elements in a pool.