19 #include <sys/ioctl.h> 32 #include <vpp/app/version.h> 40 .arc_name =
"ip4-unicast",
41 .node_name =
"ip4-gtpu-bypass",
46 .arc_name =
"ip6-unicast",
47 .node_name =
"ip6-gtpu-bypass",
59 s =
format (s,
"GTPU encap to gtpu_tunnel%d tteid %d",
67 u32 next_index = va_arg (*args,
u32);
71 case GTPU_INPUT_NEXT_DROP:
73 case GTPU_INPUT_NEXT_L2_INPUT:
75 case GTPU_INPUT_NEXT_IP4_INPUT:
77 case GTPU_INPUT_NEXT_IP6_INPUT:
80 return format (s,
"index %d", next_index);
98 s =
format (s,
"[%d] src %U dst %U teid %d tteid %d " 99 "encap-vrf-id %d sw-if-idx %d ",
117 u32 dev_instance = va_arg (*args,
u32);
118 return format (s,
"gtpu_tunnel%d", dev_instance);
143 u32 dev_instance = va_arg (*args,
u32);
144 s =
format (s,
"unimplemented dev %u", dev_instance);
228 #define foreach_copy_field \ 231 _(mcast_sw_if_index) \ 233 _(decap_next_index) \ 248 int len = is_ip6 ?
sizeof *r.h6 :
sizeof *r.h4;
276 clib_host_to_net_u32 (6 << 28);
285 udp->
src_port = clib_host_to_net_u16 (2152);
286 udp->
dst_port = clib_host_to_net_u16 (UDP_DST_PORT_GTPU);
291 gtpu->
teid = clib_host_to_net_u32 (t->
tteid);
319 static inline mcast_shared_t
325 return (mcast_shared_t)
333 mcast_shared_t new_ep = {
334 .mcast_adj_index = ai,
335 .mfib_entry_index = mfei,
359 u32 hw_if_index = ~0;
361 gtpu4_tunnel_key_t key4;
362 gtpu6_tunnel_key_t key6;
367 key4.src = a->
dst.ip4.as_u32;
368 key4.teid = clib_host_to_net_u32 (a->
teid);
373 key6.src = a->
dst.ip6;
374 key6.teid = clib_host_to_net_u32 (a->
teid);
384 return VNET_API_ERROR_TUNNEL_EXIST;
390 return VNET_API_ERROR_INVALID_DECAP_NEXT;
396 #define _(x) t->x = a->x; 445 (vnm, gtpu_device_class.index, t - gtm->
tunnels,
446 gtpu_hw_class.index, t - gtm->
tunnels);
451 u32 encap_index = !is_ip6 ?
510 .frp_sw_if_index = 0xffffffff,
518 .fp_len = (is_ip6 ? 128 : 32),
519 .fp_grp_addr = tun_dst_pfx.
fp_addr,
570 return VNET_API_ERROR_NO_SUCH_ENTRY;
578 return VNET_API_ERROR_INVALID_VALUE;
651 u32 *result = va_arg (*args,
u32 *);
652 u32 ipv4_set = va_arg (*args,
int);
659 *result = GTPU_INPUT_NEXT_L2_INPUT;
661 *result = GTPU_INPUT_NEXT_IP4_INPUT;
663 *result = GTPU_INPUT_NEXT_IP6_INPUT;
666 else if (
unformat (input,
"%d", &tmp))
687 u32 encap_fib_index = 0;
689 u32 decap_next_index = GTPU_INPUT_NEXT_L2_INPUT;
694 u32 tunnel_sw_if_index;
711 else if (
unformat (line_input,
"src %U",
717 else if (
unformat (line_input,
"dst %U",
723 else if (
unformat (line_input,
"src %U",
729 else if (
unformat (line_input,
"dst %U",
735 else if (
unformat (line_input,
"group %U %U",
740 grp_set = dst_set = 1;
743 else if (
unformat (line_input,
"group %U %U",
748 grp_set = dst_set = 1;
751 else if (
unformat (line_input,
"encap-vrf-id %d", &tmp))
754 if (encap_fib_index == ~0)
762 &decap_next_index, ipv4_set))
764 else if (
unformat (line_input,
"teid %d", &teid))
766 else if (
unformat (line_input,
"tteid %d", &tteid))
768 else if (
unformat (line_input,
"upd-tteid %d", &tteid))
808 if (grp_set && mcast_sw_if_index == ~0)
814 if (ipv4_set && ipv6_set)
826 if (decap_next_index == ~0)
836 #define _(x) a->x = x; 850 case VNET_API_ERROR_TUNNEL_EXIST:
854 case VNET_API_ERROR_NO_SUCH_ENTRY:
858 case VNET_API_ERROR_INVALID_VALUE:
864 (0,
"vnet_gtpu_add_del_tunnel returned %d", rv);
896 .path =
"create gtpu tunnel",
898 "create gtpu tunnel src <local-tep-addr>" 899 " {dst <remote-tep-addr>|group <mcast-addr> <intf-name>}" 900 " teid <nn> [tteid <nn>] [encap-vrf-id <nn>]" 901 " [decap-next [l2|ip4|ip6|node <name>]] [del | upd-tteid <nn>]",
919 vlib_cli_output (vm,
"%U",
920 format_gtpu_tunnel, t);
938 .path =
"show gtpu tunnel",
939 .short_help =
"show gtpu tunnel",
949 sw_if_index, is_enable, 0, 0);
952 sw_if_index, is_enable, 0, 0);
975 else if (
unformat (line_input,
"del"))
984 if (~0 == sw_if_index)
1050 .path =
"set interface ip gtpu-bypass",
1052 .short_help =
"set interface ip gtpu-bypass <interface> [del]",
1107 .path =
"set interface ip6 gtpu-bypass",
1109 .short_help =
"set interface ip6 gtpu-bypass <interface> [del]",
1125 VNET_FLOW_ACTION_REDIRECT_TO_NODE | VNET_FLOW_ACTION_MARK |
1126 VNET_FLOW_ACTION_BUFFER_ADVANCE,
1131 .
type = VNET_FLOW_TYPE_IP4_GTPU,
1133 .protocol.prot = IP_PROTOCOL_UDP,
1134 .src_addr.addr = t->
dst.ip4,
1135 .src_addr.mask.as_u32 = ~0,
1136 .dst_addr.addr = t->
src.ip4,
1137 .dst_addr.mask.as_u32 = ~0,
1173 u32 rx_sw_if_index = ~0;
1174 u32 hw_if_index = ~0;
1194 if (rx_sw_if_index == ~0)
1196 if (hw_if_index == ~0)
1216 "currently only inner IPv4/IPv6 protocol is supported");
1228 is_add ?
"enabling" :
"disabling");
1236 .path =
"set flow-offload gtpu",
1238 "set flow-offload gtpu hw <inerface-name> rx <tunnel-name> [del]",
1256 sizeof (gtpu6_tunnel_key_t),
1260 sizeof (ip46_address_t),
1261 sizeof (mcast_shared_t));
1272 .version = VPP_BUILD_VER,
1273 .description =
"GPRS Tunnelling Protocol, User Data (GTPv1-U)",
unformat_function_t unformat_vnet_hw_interface
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
vlib_node_registration_t gtpu4_encap_node
(constructor) VLIB_REGISTER_NODE (gtpu4_encap_node)
void vnet_set_interface_output_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Set interface output node - for interface registered without its output/tx nodes created because its ...
void dpo_stack_from_node(u32 child_node_index, dpo_id_t *dpo, const dpo_id_t *parent)
Stack one DPO object on another, and thus establish a child parent relationship.
clib_error_t * gtpu_init(vlib_main_t *vm)
fib_node_index_t fib_entry_track(u32 fib_index, const fib_prefix_t *prefix, fib_node_type_t child_type, index_t child_index, u32 *sibling)
Trackers are used on FIB entries by objects that which to track the changing state of the entry...
Contribute an object that is to be used to forward IP6 packets.
#define hash_set(h, key, value)
l2_input_config_t * configs
uword vtep_addr_ref(vtep_table_t *t, u32 fib_index, ip46_address_t *ip)
static uword ip46_address_is_multicast(const ip46_address_t *a)
int vnet_flow_get_range(vnet_main_t *vnm, char *owner, u32 count, u32 *start)
#define hash_unset(h, key)
vl_api_wireguard_peer_flags_t flags
static uword get_decap_next_for_node(u32 node_index, u32 ipv4_set)
A representation of a path as described by a route producer.
vnet_main_t * vnet_get_main(void)
vnet_interface_main_t interface_main
void fib_node_init(fib_node_t *node, fib_node_type_t type)
fib_node_index_t mfib_table_entry_path_update(u32 fib_index, const mfib_prefix_t *prefix, mfib_source_t source, const fib_route_path_t *rpath)
Add n paths to an entry (aka route) in the FIB.
u32 frp_mitf_flags
MFIB interface flags.
static mcast_shared_t mcast_shared_get(ip46_address_t *ip)
u32 * tunnel_index_by_sw_if_index
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
fib_node_type_t fib_node_type
Node type for registering to fib changes.
enum fib_node_back_walk_rc_t_ fib_node_back_walk_rc_t
Return code from a back walk function.
#define foreach_copy_field
void fib_entry_contribute_forwarding(fib_node_index_t fib_entry_index, fib_forward_chain_type_t fct, dpo_id_t *dpo)
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
vlib_node_registration_t gtpu4_flow_input_node
(constructor) VLIB_REGISTER_NODE (gtpu4_flow_input_node)
Contribute an object that is to be used to forward IP4 packets.
VNET_FEATURE_INIT(ip4_gtpu_bypass, static)
static void gtpu_tunnel_restack_dpo(gtpu_tunnel_t *t)
#define STRUCT_OFFSET_OF(t, f)
void fib_node_deinit(fib_node_t *node)
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
unformat_function_t unformat_vnet_sw_interface
u32 vnet_gtpu_get_tunnel_index(u32 sw_if_index)
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
typedef CLIB_PACKED(union { struct { fib_node_index_t mfib_entry_index;adj_index_t mcast_adj_index;};u64 as_u64;})
static u8 ip46_address_is_ip4(const ip46_address_t *ip46)
int vnet_flow_disable(vnet_main_t *vnm, u32 flow_index, u32 hw_if_index)
format_function_t format_vnet_sw_if_index_name
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
fib_node_type_t fib_node_register_new_type(const fib_node_vft_t *vft)
Create a new FIB node type and Register the function table for it.
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
static u8 * format_decap_next(u8 *s, va_list *args)
static fib_node_t * gtpu_tunnel_fib_node_get(fib_node_index_t index)
Function definition to get a FIB node from its index.
u8 * format_gtpu_encap_trace(u8 *s, va_list *args)
VNET_DEVICE_CLASS(gtpu_device_class, static)
static u8 * format_gtpu_name(u8 *s, va_list *args)
vnet_flood_class_t flood_class
VNET_HW_INTERFACE_CLASS(gtpu_hw_class)
static gtpu_tunnel_t * gtpu_tunnel_from_fib_node(fib_node_t *node)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
u32 frp_sw_if_index
The interface.
#define VLIB_INIT_FUNCTION(x)
void mfib_table_entry_delete_index(fib_node_index_t mfib_entry_index, mfib_source_t source)
Delete a FIB entry.
vlib_combined_counter_main_t * combined_sw_if_counters
static int ip46_address_cmp(const ip46_address_t *ip46_1, const ip46_address_t *ip46_2)
vl_api_interface_index_t mcast_sw_if_index
Aggregate type for a prefix.
static clib_error_t * show_gtpu_tunnel_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define clib_error_return(e, args...)
void adj_unlock(adj_index_t adj_index)
Release a reference counting lock on the adjacency.
#define ALWAYS_ASSERT(truth)
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
u32 vnet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u32 hw_class_index, u32 hw_instance)
static u8 * format_gtpu_header_with_length(u8 *s, va_list *args)
u8 * format_gtpu_tunnel(u8 *s, va_list *args)
vl_api_fib_path_type_t type
int vnet_flow_del(vnet_main_t *vnm, u32 flow_index)
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
#define hash_create_mem(elts, key_bytes, value_bytes)
#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 counters.
uword vtep_addr_unref(vtep_table_t *t, u32 fib_index, ip46_address_t *ip)
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
#define pool_put(P, E)
Free an object E in pool P.
int vnet_gtpu_add_mod_del_tunnel(vnet_gtpu_add_mod_del_tunnel_args_t *a, u32 *sw_if_indexp)
vnet_sw_interface_flags_t flags
vlib_simple_counter_main_t * sw_if_counters
static fib_node_back_walk_rc_t gtpu_tunnel_back_walk(fib_node_t *node, fib_node_back_walk_ctx_t *ctx)
Function definition to backwalk a FIB node - Here we will restack the new dpo of GTPU DIP to encap no...
An node in the FIB graph.
static clib_error_t * gtpu_add_del_tunnel_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
format_function_t format_ip46_address
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
static void ip_udp_gtpu_rewrite(gtpu_tunnel_t *t, bool is_ip6)
u32 ft_table_id
Table ID (hash key) for this FIB.
#define vec_free(V)
Free vector's memory (no header).
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
static void vnet_interface_counter_unlock(vnet_interface_main_t *im)
static void mcast_shared_remove(ip46_address_t *dst)
u32 fib_node_index_t
A typedef of a node index.
u32 adj_index_t
An index for adjacencies.
void fib_prefix_from_ip46_addr(const ip46_address_t *addr, fib_prefix_t *pfx)
Host prefix from ip.
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.
u32 sibling_index
The tunnel is a child of the FIB entry for its destination.
Aggregate type for a prefix.
static bool gtpu_decap_next_is_valid(gtpu_main_t *gtm, u32 is_ip6, u32 decap_next_index)
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 placeholder) rewrite.
vlib_main_t vlib_node_runtime_t * node
Context passed between object during a back walk.
#define VLIB_CLI_COMMAND(x,...)
u32 * free_gtpu_tunnel_hw_if_indices
static void vnet_interface_counter_lock(vnet_interface_main_t *im)
static clib_error_t * set_ip4_gtpu_bypass(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
fib_node_index_t fib_entry_index
void fib_entry_untrack(fib_node_index_t fei, u32 sibling)
Stop tracking a FIB entry.
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
fib_node_t node
Linkage into the FIB object graph.
static void gtpu_tunnel_last_lock_gone(fib_node_t *node)
Function definition to inform the FIB node that its last lock has gone.
enum fib_forward_chain_type_t_ fib_forward_chain_type_t
FIB output chain type.
fib_route_path_flags_t frp_flags
flags on the path
static void hash_unset_mem_free(uword **h, const void *key)
static void vlib_zero_simple_counter(vlib_simple_counter_main_t *cm, u32 index)
Clear a simple counter Clears the set of per-thread u16 counters, and the u64 counter.
void vnet_int_gtpu_bypass_mode(u32 sw_if_index, u8 is_ip6, u8 is_enable)
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
int vnet_flow_add(vnet_main_t *vnm, vnet_flow_t *flow, u32 *flow_index)
#define VNET_FEATURES(...)
static vtep_table_t vtep_table_create()
uword * gtpu4_tunnel_by_key
#define vec_elt(v, i)
Get vector value at index i.
vlib_node_registration_t gtpu6_input_node
(constructor) VLIB_REGISTER_NODE (gtpu6_input_node)
static void mcast_shared_add(ip46_address_t *dst, fib_node_index_t mfei, adj_index_t ai)
fib_protocol_t fp_proto
protocol type
index_t dpoi_index
the index of objects of that type
bool udp_is_valid_dst_port(udp_dst_port_t dst_port, u8 is_ip4)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static fib_protocol_t fib_ip_proto(bool is_ip6)
Convert from boolean is_ip6 to FIB protocol.
uword * gtpu6_tunnel_by_key
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, vnet_hw_interface_flags_t flags)
static clib_error_t * set_ip6_gtpu_bypass(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
vlib_node_registration_t gtpu6_encap_node
(constructor) VLIB_REGISTER_NODE (gtpu6_encap_node)
a point 2 point interface
int vnet_flow_enable(vnet_main_t *vnm, u32 flow_index, u32 hw_if_index)
unformat_function_t unformat_vlib_node
#define hash_get_mem(h, key)
static clib_error_t * set_ip_gtpu_bypass(u32 is_ip6, unformat_input_t *input, vlib_cli_command_t *cmd)
A FIB graph nodes virtual function table.
ip4_main_t ip4_main
Global ip4 main structure.
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, vnet_sw_interface_flags_t flags)
struct fib_table_t_ * fibs
Vector of FIBs.
adj_index_t adj_mcast_add_or_lock(fib_protocol_t proto, vnet_link_t link_type, u32 sw_if_index)
Mcast Adjacency.
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
vnet_link_t fib_proto_to_link(fib_protocol_t proto)
Convert from a protocol to a link type.
static void hash_set_mem_alloc(uword **h, const void *key, uword v)
int vnet_gtpu_add_del_rx_flow(u32 hw_if_index, u32 t_index, int is_add)
void udp_register_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u32 node_index, u8 is_ip4)
static clib_error_t * gtpu_offload_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static clib_error_t * gtpu_interface_admin_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
#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
vlib_node_registration_t gtpu4_input_node
(constructor) VLIB_REGISTER_NODE (gtpu4_input_node)
struct fib_table_t_ * fibs
static uword unformat_decap_next(unformat_input_t *input, va_list *args)
static u16 ip4_header_checksum(ip4_header_t *i)
const ip46_address_t zero_addr
vl_api_interface_index_t sw_if_index
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
static uword pool_elts(void *v)
Number of active elements in a pool.