|
FD.io VPP
v21.06-3-gbb25fbf28
Vector Packet Processing
|
Go to the documentation of this file.
34 #include <sys/ioctl.h>
35 #include <sys/socket.h>
37 #include <sys/types.h>
39 #include <netinet/in.h>
41 #include <linux/if_arp.h>
42 #include <linux/if_tun.h>
129 .mtu_bytes = 4096 + 256,
158 for (
i = 0;
i < n_packets;
i++)
194 while (
b->
flags & VLIB_BUFFER_NEXT_PRESENT);
272 word i, n_bytes_left, n_bytes_in_packet;
291 n_bytes_in_packet = n_bytes_left;
292 if (n_bytes_left <= 0)
307 n_bytes_left < buffer_size ? n_bytes_left : buffer_size;
309 n_bytes_left -= buffer_size;
311 if (n_bytes_left <= 0)
317 b->
flags |= VLIB_BUFFER_NEXT_PRESENT;
346 switch (
b->
data[0] & 0xf0)
385 "unknown packet type",
393 .sibling_of =
"device-input",
395 .state = VLIB_NODE_STATE_INTERRUPT,
436 sfd = socket (AF_INET, SOCK_STREAM, 0);
441 strncpy (ifr.ifr_name, tm->
tun_name, sizeof (ifr.ifr_name) - 1);
444 if (ioctl (sfd, SIOCGIFFLAGS, &ifr) < 0)
447 ifr.ifr_flags &= ~(IFF_UP | IFF_RUNNING);
449 if (ioctl (sfd, SIOCSIFFLAGS, &ifr) < 0)
482 int flags = IFF_TUN | IFF_NO_PI;
483 int is_enabled = 0, is_ether = 0, have_normal_interface = 0;
490 else if (
unformat (input,
"enable"))
492 else if (
unformat (input,
"disable"))
496 else if (
unformat (input,
"have-normal-interface") ||
498 have_normal_interface = 1;
522 flags = IFF_TAP | IFF_NO_PI;
531 strncpy (ifr.ifr_name, tm->
tun_name, sizeof (ifr.ifr_name) - 1);
532 ifr.ifr_flags =
flags;
547 if ((tm->
dev_tap_fd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0)
556 struct sockaddr_ll sll;
559 strncpy (ifr.ifr_name, tm->
tun_name, sizeof (ifr.ifr_name) - 1);
560 if (ioctl (tm->
dev_tap_fd, SIOCGIFINDEX, &ifr) < 0)
568 sll.sll_family = AF_PACKET;
569 sll.sll_ifindex = ifr.ifr_ifindex;
570 sll.sll_protocol = htons (ETH_P_ALL);
572 if (bind (tm->
dev_tap_fd, (
struct sockaddr *) &sll, sizeof (sll)) < 0)
592 if (ioctl (tm->
dev_tap_fd, SIOCSIFMTU, &ifr) < 0)
599 if (ioctl (tm->
dev_tap_fd, SIOCGIFFLAGS, &ifr) < 0)
605 ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
607 if (ioctl (tm->
dev_tap_fd, SIOCSIFFLAGS, &ifr) < 0)
615 if (ioctl (tm->
dev_tap_fd, SIOCGIFHWADDR, &ifr) < 0)
624 if (have_normal_interface)
660 template.description =
format (0,
"vnet tuntap");
694 u32 if_address_index,
u32 is_delete)
732 snprintf (ifr.ifr_name, sizeof (ifr.ifr_name),
743 struct sockaddr_in *sin;
745 sin = (
struct sockaddr_in *) &ifr.ifr_addr;
748 sin->sin_family = AF_INET;
750 if (ioctl (tm->
dev_tap_fd, SIOCSIFADDR, &ifr) < 0)
753 sin->sin_addr.s_addr =
im->fib_masks[address_length];
754 if (ioctl (tm->
dev_tap_fd, SIOCSIFNETMASK, &ifr) < 0)
764 if (ioctl (tm->
dev_tap_fd, SIOCGIFFLAGS, &ifr) < 0)
768 ifr.ifr_flags &= ~(IFF_UP | IFF_RUNNING);
770 ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
772 if (ioctl (tm->
dev_tap_fd, SIOCSIFFLAGS, &ifr) < 0)
783 struct in6_addr ifr6_addr;
809 u32 if_address_index,
u32 is_delete)
833 subif_addr.
is_v6 = 1;
850 snprintf (ifr.ifr_name, sizeof (ifr.ifr_name),
861 int sockfd = socket (AF_INET6, SOCK_STREAM, 0);
865 if (ioctl (sockfd, SIOGIFINDEX, &ifr) < 0)
872 if (ioctl (sockfd, SIOCSIFADDR, &ifr6) < 0)
880 int sockfd = socket (AF_INET6, SOCK_STREAM, 0);
884 if (ioctl (sockfd, SIOGIFINDEX, &ifr) < 0)
891 if (ioctl (sockfd, SIOCDIFADDR, &ifr6) < 0)
957 s =
format (s,
"tuntap-%d",
i);
u32 next_buffer
Next buffer for this linked-list of buffers.
vnet_interface_main_t * im
static void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
clib_file_main_t file_main
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, vnet_sw_interface_flags_t flags)
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
struct _vnet_device_class vnet_device_class_t
struct in6_addr ifr6_addr
@ VNET_INTERFACE_COUNTER_TX
nat44_ei_hairpin_src_next_t next_index
ip4_main_t ip4_main
Global ip4 main structure.
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
void ip4_sw_interface_enable_disable(u32 sw_if_index, u32 is_enable)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
u8 ether_dst_mac[6]
tap device destination MAC address.
static clib_error_t * tuntap_exit(vlib_main_t *vm)
Clean up the tun/tap device.
@ VNET_DEVICE_INPUT_NEXT_DROP
@ VLIB_NODE_TYPE_INTERNAL
u32 mtu_bytes
Interface MTU in bytes and # of default sized buffers.
vlib_main_t vlib_node_runtime_t * node
#define clib_error_return(e, args...)
static vlib_node_registration_t tuntap_tx_node
(constructor) VLIB_REGISTER_NODE (tuntap_tx_node)
static char * tuntap_rx_error_strings[]
TUNTAP_RX error strings.
clib_file_function_t * read_function
#define vec_alloc(V, N)
Allocate space for N more elements (no header, unspecified alignment)
VNET_HW_INTERFACE_CLASS(tuntap_interface_class, static)
int is_ether
Create a "tap" [ethernet] encaps device.
@ VNET_SW_INTERFACE_FLAG_ADMIN_UP
#define pool_put(P, E)
Free an object E in pool P.
static uword * mhash_get(mhash_t *h, const void *key)
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
static clib_error_t * tuntap_config(vlib_main_t *vm, unformat_input_t *input)
CLI function for tun/tap config.
@ VNET_HW_INTERFACE_FLAG_LINK_UP
u32 clib_file_index
Unix file index.
static u32 vlib_get_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt)
#define clib_error_report(e)
int have_normal_interface
1 if a "normal" routed intfc, 0 if a punt/inject interface
static tuntap_main_t tuntap_main
__clib_export void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
@ VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
TUNTAP per thread struct.
#define clib_unix_warning(format, args...)
vnet_sw_interface_flags_t flags
#define VLIB_CONFIG_FUNCTION(x, n,...)
workaround for a known include file bug.
static uword tuntap_tx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
tuntap_tx
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
void tuntap_ip6_add_del_interface_address(ip6_main_t *im, uword opaque, u32 sw_if_index, ip6_address_t *address, u32 address_length, u32 if_address_index, u32 is_delete)
Add or Del tun/tap interface address.
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
vlib_error_t error
Error code for buffers to be enqueued to error handler.
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
static __clib_warn_unused_result u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
static uword tuntap_rx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
TUNTAP receive node.
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
vnet_main_t * vnet_get_main(void)
@ VNET_DEVICE_INPUT_NEXT_IP6_INPUT
@ VNET_DEVICE_INPUT_NEXT_IP4_INPUT
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
ip6_add_del_interface_address_callback_t * add_del_interface_address_callbacks
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
static vlib_node_registration_t tuntap_rx_node
(constructor) VLIB_REGISTER_NODE (tuntap_rx_node)
static u8 * format_tuntap_interface_name(u8 *s, va_list *args)
Format tun/tap interface name.
static void tuntap_nopunt_frame(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Free the tun/tap frame.
void(* os_punt_frame)(struct vlib_main_t *vm, struct vlib_node_runtime_t *node, vlib_frame_t *frame)
static void tuntap_punt_frame(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
TX the tun/tap frame.
sll srl srl sll sra u16x4 i
#define VLIB_NODE_FLAG_TRACE_SUPPORTED
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
manual_print typedef address
@ VNET_INTERFACE_COUNTER_RX
static clib_error_t * tuntap_init(vlib_main_t *vm)
tun/tap node init
#define CLIB_CACHE_LINE_BYTES
static void vlib_set_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt, u32 count)
static vnet_device_class_t tuntap_dev_class
struct _vlib_node_registration vlib_node_registration_t
vlib_combined_counter_main_t * combined_sw_if_counters
u16 current_length
Nbytes between current data and the end of this buffer.
void vlib_frame_free(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_frame_t *f)
static clib_error_t * tuntap_read_ready(clib_file_t *uf)
Gets called when file descriptor is ready from epoll.
ip4_add_del_interface_address_callback_t * add_del_interface_address_callbacks
Functions to call when interface address changes.
ip4_add_del_interface_address_function_t * function
ip6_add_del_interface_address_function_t * function
description fragment has unexpected format
u32 fib_table_get_index_for_sw_if_index(fib_protocol_t proto, u32 sw_if_index)
Get the index of the FIB bound to the interface.
static void vlib_set_next_frame_buffer(vlib_main_t *vm, vlib_node_runtime_t *node, u32 next_index, u32 buffer_index)
static_always_inline u32 vlib_buffer_get_default_data_size(vlib_main_t *vm)
#define VLIB_INIT_FUNCTION(x)
static void vlib_node_set_interrupt_pending(vlib_main_t *vm, u32 node_index)
char * tun_name
Linux interface name for tun device.
mhash_t subif_mhash
Hash for subif addresses.
static void vlib_buffer_free_no_next(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers, does not free the buffer chain for each buffer.
u32 * rx_buffers
Vector of VLIB rx buffers to use.
void ip6_sw_interface_enable_disable(u32 sw_if_index, u32 is_enable)
#define clib_error_return_unix(e, args...)
struct iovec * iovecs
Vector of iovecs for readv/writev calls.
static uword clib_file_add(clib_file_main_t *um, clib_file_t *template)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
int dev_net_tun_fd
File descriptors for /dev/net/tun and provisioning socket.
static vlib_main_t * vlib_get_main(void)
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, vnet_hw_interface_flags_t flags)
void tuntap_ip4_add_del_interface_address(ip4_main_t *im, uword opaque, u32 sw_if_index, ip4_address_t *address, u32 address_length, u32 if_address_index, u32 is_delete)
Add or Del IP4 address to tun/tap interface.
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
static_always_inline void vnet_feature_start_device_input_x1(u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)
u32 hw_if_index
For the "normal" interface, if configured.
@ VNET_HW_INTERFACE_CLASS_FLAG_P2P
a point 2 point interface
#define clib_warning(format, args...)
static uword tuntap_intfc_tx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
TX packet out tun/tap.
subif_address_t * subifs
Pool of subinterface addresses.
#define VLIB_MAIN_LOOP_EXIT_FUNCTION(x)
VNET_DEVICE_CLASS(tuntap_dev_class, static)
static vnet_hw_interface_class_t tuntap_interface_class
tuntap_per_thread_t * threads
per thread variables
static __clib_warn_unused_result int vlib_trace_buffer(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, vlib_buffer_t *b, int follow_chain)
static void vlib_buffer_reset(vlib_buffer_t *b)
Reset current header & length to state they were in when packet was received.
static vlib_thread_main_t * vlib_get_thread_main()
vl_api_interface_index_t sw_if_index
struct _vnet_hw_interface_class vnet_hw_interface_class_t
__clib_export uword mhash_unset(mhash_t *h, void *key, uword *old_value)
u32 vnet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u32 hw_class_index, u32 hw_instance)
clib_error_t * ethernet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, const u8 *address, u32 *hw_if_index_return, ethernet_flag_change_function_t flag_change)
vnet_interface_main_t interface_main
vlib_increment_combined_counter(ccm, ti, sw_if_index, n_buffers, n_bytes)
static uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
VLIB buffer representation.
#define VLIB_REGISTER_NODE(x,...)
vl_api_wireguard_peer_flags_t flags