26 #define MPLS_ETH_OUTPUT_NEXT_OUTPUT 1 36 u32 * from, * to_next, n_left_from, n_left_to_next;
47 while (n_left_from > 0)
56 while (n_left_from >= 4 && n_left_to_next >= 2)
59 u32 bi0, next0, bi1, next1;
61 u32 sw_if_index0, sw_if_index1;
155 to_next, n_left_to_next,
156 bi0, bi1, next0, next1);
158 while (n_left_from > 0 && n_left_to_next > 0)
209 to_next, n_left_to_next,
217 MPLS_ERROR_PKTS_ENCAP, frame->
n_vectors);
224 u32 dev_instance = va_arg (*args,
u32);
225 return format (s,
"mpls-eth%d", dev_instance);
230 u32 dev_instance = va_arg (*args,
u32);
233 s =
format (s,
"MPLS-ETH tunnel: id %d\n", dev_instance);
238 .name =
"MPLS-ETH tunnel device",
243 .no_flatten_output_chains = 1,
246 .admin_up_down_function = 0;
257 .unformat_header = unformat_mpls_eth_header,
282 u32 lookup_feature_index;
319 lookup_feature_index,
324 lookup_feature_index,
334 u32 entry_index = va_arg (*args,
u32);
353 s =
format (s,
"[%d]: dst %U, adj %U/%d, labels %U\n",
361 s =
format (s,
" tx on %U, rx fib index %d",
381 vlib_cli_output (vm,
"%U", format_mpls_ethernet_tunnel, et);
391 .path =
"show mpls tunnel",
392 .short_help =
"show mpls tunnel",
412 u8 * rewrite_data = 0;
423 clib_warning (
"no label for inner fib index %d, dst %U",
438 return (rewrite_data);
446 u32 * tunnel_sw_if_index,
455 u32 inner_fib_index = 0;
459 int found_tunnel = 0;
461 u32 hw_if_index = ~0;
466 if (tunnel_sw_if_index == 0)
467 tunnel_sw_if_index = &dummy;
469 *tunnel_sw_if_index = ~0;
471 if (inner_fib_id != (
u32)~0)
477 return VNET_API_ERROR_NO_SUCH_FIB;
478 inner_fib_index = p[0];
488 if (!memcmp (&tp->tunnel_dst, dst, sizeof (*dst))
489 && !memcmp (&tp->intfc_address, intfc, sizeof (*intfc))
490 && tp->inner_fib_index == inner_fib_index
491 && FIB_NODE_INDEX_INVALID != tp->fei)
501 e = mpls_encap_by_fib_and_dest (mm, inner_fib_index,
504 return VNET_API_ERROR_NO_SUCH_LABEL;
519 if (is_add == 0 && found_tunnel == 0)
520 return VNET_API_ERROR_NO_SUCH_ENTRY;
524 return VNET_API_ERROR_NO_SUCH_LABEL;
527 memset (tp, 0,
sizeof (*tp));
529 if (
vec_len (mm->free_eth_sw_if_indices) > 0)
532 mm->free_eth_sw_if_indices[
vec_len(mm->free_eth_sw_if_indices)-1];
533 _vec_len (mm->free_eth_sw_if_indices) -= 1;
535 hi->dev_instance = tp - mm->eth_tunnels;
536 hi->hw_instance = tp - mm->eth_tunnels;
541 (vnm, mpls_eth_device_class.index, tp - mm->eth_tunnels,
542 mpls_eth_hw_interface_class.index,
543 tp - mm->eth_tunnels);
548 (vnm->vlib_main,
hi->tx_node_index,
554 *tunnel_sw_if_index =
hi->sw_if_index;
558 tp->hw_if_index = hw_if_index;
561 clib_memcpy(tp->tunnel_dst, dst, sizeof (tp->tunnel_dst));
562 tp->intfc_address.as_u32 = intfc->as_u32;
563 tp->mask_width = mask_width;
564 tp->inner_fib_index = inner_fib_index;
565 tp->encap_index = e - mm->encaps;
566 tp->tx_sw_if_index = tx_sw_if_index;
567 tp->l2_only = l2_only;
570 memset(&adj, 0,
sizeof (adj));
574 if (rewrite_data == 0)
576 if (*tunnel_sw_if_index != ~0)
581 vec_add1 (mm->free_eth_sw_if_indices, tp->hw_if_index);
585 return VNET_API_ERROR_NO_SUCH_LABEL;
595 sizeof (adj.rewrite_data));
601 vec_insert (rewrite_data, adj.rewrite_header.data_bytes, 0);
604 sizeof (adj.rewrite_data)),
605 adj.rewrite_header.data_bytes);
608 sizeof(adj.rewrite_data),
614 tp->rewrite_data = rewrite_data;
626 .ip4 = tp->intfc_address,
628 .fp_len = tp->mask_width,
643 if (is_add == 0 && found_tunnel)
648 vec_add1 (mm->free_eth_sw_if_indices, tp->hw_if_index);
666 int dst_set = 0, intfc_set = 0;
668 u32 inner_fib_id = (
u32)~0;
673 u32 sw_if_index = ~0;
684 else if (
unformat (line_input,
"adj %U/%d",
687 else if (
unformat (line_input,
"tx-intfc %U",
690 else if (
unformat (line_input,
"fib-id %d", &inner_fib_id))
692 else if (
unformat (line_input,
"l2-only"))
694 else if (
unformat (line_input,
"del"))
712 inner_fib_id, tx_sw_if_index,
722 case VNET_API_ERROR_NO_SUCH_FIB:
726 case VNET_API_ERROR_NO_SUCH_ENTRY:
729 case VNET_API_ERROR_NO_SUCH_LABEL:
739 return clib_error_return (0,
"vnet_mpls_ethernet_add_del_tunnel returned %d", rv);
747 .path =
"create mpls ethernet tunnel",
749 "create mpls ethernet tunnel [del] dst <mac-addr> intfc <addr>/<mw>",
756 u32 policy_tunnel_index)
760 u8 * rewrite_data = 0;
766 return VNET_API_ERROR_NO_SUCH_ENTRY;
770 memset (&adj, 0,
sizeof (adj));
780 sizeof (adj.rewrite_data));
782 vec_validate (rewrite_data, adj.rewrite_header.data_bytes -1);
786 sizeof (adj.rewrite_data)),
787 adj.rewrite_header.data_bytes);
810 u32 * tunnel_sw_if_index,
811 u32 classify_table_index,
812 u32 * new_tunnel_index,
820 u32 inner_fib_index = 0;
821 int found_tunnel = 0;
823 u32 hw_if_index = ~0;
828 if (tunnel_sw_if_index == 0)
829 tunnel_sw_if_index = &dummy;
831 *tunnel_sw_if_index = ~0;
833 if (inner_fib_id != (
u32)~0)
839 return VNET_API_ERROR_NO_SUCH_FIB;
840 inner_fib_index = p[0];
850 if (!memcmp (&tp->tunnel_dst, dst, sizeof (*dst))
851 && !memcmp (&tp->intfc_address, intfc, sizeof (*intfc))
852 && tp->inner_fib_index == inner_fib_index
853 && FIB_NODE_INDEX_INVALID != tp->fei)
876 if (is_add == 0 && found_tunnel == 0)
877 return VNET_API_ERROR_NO_SUCH_ENTRY;
880 memset (tp, 0,
sizeof (*tp));
882 if (
vec_len (mm->free_eth_sw_if_indices) > 0)
885 mm->free_eth_sw_if_indices[
vec_len(mm->free_eth_sw_if_indices)-1];
886 _vec_len (mm->free_eth_sw_if_indices) -= 1;
888 hi->dev_instance = tp - mm->eth_tunnels;
889 hi->hw_instance = tp - mm->eth_tunnels;
894 (vnm, mpls_eth_device_class.index, tp - mm->eth_tunnels,
895 mpls_eth_hw_interface_class.index,
896 tp - mm->eth_tunnels);
901 (vnm->vlib_main,
hi->tx_node_index,
907 *tunnel_sw_if_index =
hi->sw_if_index;
911 tp->hw_if_index = hw_if_index;
914 clib_memcpy(tp->tunnel_dst, dst, sizeof (tp->tunnel_dst));
915 tp->intfc_address.as_u32 = intfc->as_u32;
916 tp->mask_width = mask_width;
917 tp->inner_fib_index = inner_fib_index;
918 tp->encap_index = e - mm->encaps;
919 tp->tx_sw_if_index = tx_sw_if_index;
920 tp->l2_only = l2_only;
923 if (new_tunnel_index)
924 *new_tunnel_index = tp - mm->eth_tunnels;
932 .ip4 = tp->intfc_address,
934 .fp_len = tp->mask_width,
945 classify_table_index));
960 if (is_add == 0 && found_tunnel)
965 vec_add1 (mm->free_eth_sw_if_indices, tp->hw_if_index);
982 int dst_set = 0, intfc_set = 0;
984 u32 inner_fib_id = (
u32)~0;
985 u32 classify_table_index = (
u32)~0;
986 u32 new_tunnel_index;
1001 else if (
unformat (line_input,
"adj %U/%d",
1004 else if (
unformat (line_input,
"tx-intfc %U",
1007 else if (
unformat (line_input,
"classify-table-index %d",
1008 &classify_table_index))
1010 else if (
unformat (line_input,
"fib-id %d", &inner_fib_id))
1012 else if (
unformat (line_input,
"l2-only"))
1014 else if (
unformat (line_input,
"del"))
1021 if (classify_table_index == ~0)
1035 inner_fib_id, tx_sw_if_index,
1037 classify_table_index,
1046 case VNET_API_ERROR_NO_SUCH_FIB:
1050 case VNET_API_ERROR_NO_SUCH_ENTRY:
1053 case VNET_API_ERROR_NO_SUCH_LABEL:
1063 return clib_error_return (0,
"vnet_mpls_ethernet_add_del_policy_tunnel returned %d", rv);
1071 .path =
"create mpls ethernet policy tunnel",
1073 "create mpls ethernet policy tunnel [del] dst <mac-addr> intfc <addr>/<mw>\n" 1074 " classify-table-index <nn>",
1085 u32 sw_if_index, enable;
1098 else if (
unformat (input,
"disable"))
1114 .path =
"set interface mpls",
1116 .short_help =
"Enable/Disable an interface for MPLS forwarding",
vnet_config_main_t config_main
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
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.
static uword mpls_eth_interface_tx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
void mpls_sw_interface_enable_disable(mpls_main_t *mm, u32 sw_if_index, u8 is_enable)
sll srl srl sll sra u16x4 i
static clib_error_t * mpls_interface_enable_disable(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static vlib_main_t * vlib_get_main(void)
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
format_function_t format_mpls_eth_header_with_length
u32 * fib_index_by_sw_if_index
u32 vnet_config_del_feature(vlib_main_t *vm, vnet_config_main_t *cm, u32 config_string_heap_index, u32 feature_index, void *feature_config, u32 n_feature_config_bytes)
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
u32 * config_index_by_sw_if_index
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
static clib_error_t * mpls_policy_encap_init(vlib_main_t *vm)
void vnet_rewrite_for_sw_interface(vnet_main_t *vnm, vnet_link_t link_type, u32 sw_if_index, u32 node_index, void *dst_address, vnet_rewrite_header_t *rw, u32 max_rewrite_bytes)
Deprecated.
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
u8 mpls_sw_interface_is_enabled(u32 sw_if_index)
ip_lookup_main_t lookup_main
unformat_function_t unformat_vnet_sw_interface
ip_adjacency_t * ip_add_adjacency(ip_lookup_main_t *lm, ip_adjacency_t *copy_adj, u32 n_adj, u32 *adj_index_return)
int vnet_mpls_ethernet_add_del_policy_tunnel(u8 *dst, ip4_address_t *intfc, u32 mask_width, u32 inner_fib_id, u32 tx_sw_if_index, u32 *tunnel_sw_if_index, u32 classify_table_index, u32 *new_tunnel_index, u8 l2_only, u8 is_add)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
format_function_t format_vnet_sw_if_index_name
vnet_feature_config_main_t feature_config_mains[VNET_N_IP_FEAT]
static clib_error_t * create_mpls_ethernet_policy_tunnel_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static clib_error_t * show_mpls_tunnel_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u8 * mpls_enabled_by_sw_if_index
vnet_main_t * vnet_get_main(void)
u8 * format_mpls_eth_tx_trace(u8 *s, va_list *args)
u8 * format_ethernet_address(u8 *s, va_list *args)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
#define VLIB_INIT_FUNCTION(x)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Aggregrate type for a prefix.
#define clib_warning(format, args...)
int vnet_mpls_policy_tunnel_add_rewrite(mpls_main_t *mm, mpls_encap_t *e, u32 policy_tunnel_index)
#define vlib_call_init_function(vm, x)
u32 vnet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u32 hw_class_index, u32 hw_instance)
static clib_error_t * create_mpls_ethernet_tunnel_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
void fib_table_unlock(u32 fib_index, fib_protocol_t proto)
Take a reference counting lock on the table.
ip4_address_t intfc_address
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
#define vec_insert(V, N, M)
Insert N vector elements starting at element M, initialize new elements to zero (no header...
fib_node_index_t fib_table_entry_special_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, adj_index_t adj_index)
Add a 'special' entry to the FIB that links to the adj passed A special entry is an entry that the FI...
uword * fib_index_by_table_id
Hash table mapping table id to fib index.
u16 current_length
Nbytes between current data and the end of this buffer.
vlib_node_registration_t mpls_policy_encap_node
(constructor) VLIB_REGISTER_NODE (mpls_policy_encap_node)
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
#define MPLS_ETH_OUTPUT_NEXT_OUTPUT
index_t classify_dpo_create(dpo_proto_t proto, u32 classify_table_index)
#define pool_put(P, E)
Free an object E in pool P.
vlib_node_registration_t mpls_input_node
(constructor) VLIB_REGISTER_NODE (mpls_input_node)
int vnet_mpls_ethernet_add_del_tunnel(u8 *dst, ip4_address_t *intfc, u32 mask_width, u32 inner_fib_id, u32 tx_sw_if_index, u32 *tunnel_sw_if_index, u8 l2_only, u8 is_add)
static void * vnet_rewrite_get_data_internal(vnet_rewrite_header_t *rw, int max_size)
static u32 vnet_mpls_uc_get_label(mpls_label_t label_exp_s_ttl)
static u8 * format_mpls_eth_device(u8 *s, va_list *args)
#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.
#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 vlib_cli_output(vlib_main_t *vm, char *fmt,...)
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
VNET_HW_INTERFACE_CLASS(ethernet_hw_interface_class)
vlib_node_registration_t ip4_rewrite_node
(constructor) VLIB_REGISTER_NODE (ip4_rewrite_node)
static u8 * format_mpls_eth_tunnel_name(u8 *s, va_list *args)
#define CLIB_PREFETCH(addr, size, type)
#define vec_free(V)
Free vector's memory (no header).
void fib_table_entry_delete(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Delete a FIB entry.
#define MPLS_FIB_DEFAULT_TABLE_ID
static void vnet_rewrite_set_data_internal(vnet_rewrite_header_t *rw, int max_size, void *data, int data_bytes)
#define clib_memcpy(a, b, c)
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
u32 fib_node_index_t
A typedef of a node index.
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
mpls_eth_tunnel_t * eth_tunnels
void dpo_set(dpo_id_t *dpo, dpo_type_t type, dpo_proto_t proto, index_t index)
Set/create a DPO ID The DPO will be locked.
u8 * default_build_rewrite(vnet_main_t *vnm, u32 sw_if_index, vnet_link_t link_type, const void *dst_address)
Return a complete, zero-length (aka dummy) rewrite.
#define VLIB_CLI_COMMAND(x,...)
fib_node_index_t fib_table_entry_special_dpo_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Add a 'special' entry to the FIB that links to the DPO passed A special entry is an entry that the FI...
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
uword unformat_ethernet_address(unformat_input_t *input, va_list *args)
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
u32 vnet_config_add_feature(vlib_main_t *vm, vnet_config_main_t *cm, u32 config_string_heap_index, u32 feature_index, void *feature_config, u32 n_feature_config_bytes)
From the control plane API.
u8 * format_mpls_encap_index(u8 *s, va_list *args)
mpls_encap_t * mpls_encap_by_fib_and_dest(mpls_main_t *mm, u32 rx_fib, u32 dst_address)
#define VLIB_BUFFER_IS_TRACED
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
#define FIB_NODE_INDEX_INVALID
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static u8 * mpls_ethernet_rewrite(mpls_main_t *mm, mpls_eth_tunnel_t *t)
VLIB_DEVICE_TX_FUNCTION_MULTIARCH(mpls_eth_device_class, mpls_eth_interface_tx)
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
#define DPO_INVALID
An initialiser for DPos declared on the stack.
a point 2 point interface
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
ip4_main_t ip4_main
Global ip4 main structure.
This packet is to be rewritten and forwarded to the next processing node.
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
#define clib_error_return(e, args...)
VNET_DEVICE_CLASS(ethernet_simulated_device_class)
uword vlib_node_add_named_next_with_slot(vlib_main_t *vm, uword node, char *name, uword slot)
#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
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
u8 * format_mpls_ethernet_tunnel(u8 *s, va_list *args)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
u32 mpls_rx_feature_lookup
mpls_unicast_header_t * labels
clib_error_t * mpls_interface_init(vlib_main_t *vm)
static uword pool_elts(void *v)
Number of active elements in a pool.