25 #include <sys/ioctl.h> 26 #include <sys/socket.h> 28 #include <sys/types.h> 30 #include <netinet/in.h> 32 #include <linux/if_arp.h> 33 #include <linux/if_tun.h> 180 for (i = 0; i < n_packets; i++)
192 if (tx_sw_if_index == (
u32) ~ 0)
205 clib_warning (
"sw_if_index %d unknown", tx_sw_if_index);
233 while (b->
flags & VLIB_BUFFER_NEXT_PRESENT);
279 u32 n_left_to_next, next_index;
288 while (n_left_to_next)
292 word n_bytes_in_packet;
307 TAPCLI_ERROR_BUFFER_ALLOC,
332 n_bytes_in_packet = n_bytes_left;
333 if (n_bytes_left <= 0)
338 TAPCLI_ERROR_READ, 1);
352 n_bytes_left < buffer_size ? n_bytes_left : buffer_size;
353 n_bytes_left -= buffer_size;
358 prev->
flags |= VLIB_BUFFER_NEXT_PRESENT;
363 if (n_bytes_left <= 0)
375 buffer_size) ? n_bytes_in_packet - buffer_size : 0;
376 b_first->
flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
389 to_next[0] = bi_first;
397 to_next, n_left_to_next,
398 bi_first, next_index);
404 combined_sw_if_counters +
444 static u32 *ready_interface_indices;
453 vec_add1 (ready_interface_indices, i);
457 if (
vec_len (ready_interface_indices) == 0)
460 for (i = 0; i <
vec_len (ready_interface_indices); i++)
464 ready_interface_indices[i], 0);
475 #define _(sym,string) string, 484 .sibling_of =
"device-input",
486 .state = VLIB_NODE_STATE_INTERRUPT,
544 else if (
unformat (input,
"disable"))
629 u32 show_dev_instance = ~0;
635 if (show_dev_instance != ~0)
636 i = show_dev_instance;
638 s =
format (s,
"tapcli-%d", i);
671 memcpy (&ifr, &ti->
ifr, sizeof (ifr));
686 ifr.ifr_flags |= IFF_PROMISC;
688 ifr.ifr_flags &= ~(IFF_PROMISC);
713 u32 hw_if_index,
u32 node_index)
722 if (node_index == ~0)
759 s =
format (s,
"tapcli tx trace is not supported");
798 strncpy ((
char *) tapid->
dev_name, ti->
ifr.ifr_name,
799 sizeof (ti->
ifr.ifr_name) - 1);
802 *out_tapids = r_tapids;
821 if (inactive_cnt > 0)
872 return VNET_API_ERROR_FEATURE_DISABLED;
875 flags = IFF_TAP | IFF_NO_PI;
877 if ((dev_net_tun_fd = open (
"/dev/net/tun", O_RDWR)) < 0)
878 return VNET_API_ERROR_SYSCALL_ERROR_1;
881 strncpy (ifr.ifr_name, (
char *) ap->
intfc_name, sizeof (ifr.ifr_name) - 1);
882 ifr.ifr_flags =
flags;
883 if (ioctl (dev_net_tun_fd, TUNSETIFF, (
void *) &ifr) < 0)
885 rv = VNET_API_ERROR_SYSCALL_ERROR_2;
890 if ((dev_tap_fd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0)
892 rv = VNET_API_ERROR_SYSCALL_ERROR_3;
899 struct sockaddr_ll sll;
902 strncpy (ifr.ifr_name, (
char *) ap->
intfc_name,
903 sizeof (ifr.ifr_name) - 1);
904 if (ioctl (dev_tap_fd, SIOCGIFINDEX, &ifr) < 0)
906 rv = VNET_API_ERROR_SYSCALL_ERROR_4;
912 sll.sll_family = AF_PACKET;
913 sll.sll_ifindex = ifr.ifr_ifindex;
914 sll.sll_protocol = htons (ETH_P_ALL);
916 if (bind (dev_tap_fd, (
struct sockaddr *) &sll,
sizeof (sll)) < 0)
918 rv = VNET_API_ERROR_SYSCALL_ERROR_5;
926 if (ioctl (dev_net_tun_fd, FIONBIO, &one) < 0)
928 rv = VNET_API_ERROR_SYSCALL_ERROR_6;
933 if (ioctl (dev_tap_fd, SIOCSIFMTU, &ifr) < 0)
935 rv = VNET_API_ERROR_SYSCALL_ERROR_7;
940 if (ioctl (dev_tap_fd, SIOCGIFFLAGS, &ifr) < 0)
942 rv = VNET_API_ERROR_SYSCALL_ERROR_8;
946 ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
948 if (ioctl (dev_tap_fd, SIOCSIFFLAGS, &ifr) < 0)
950 rv = VNET_API_ERROR_SYSCALL_ERROR_9;
956 struct sockaddr_in sin;
958 u32 mask = clib_host_to_net_u32 (0xFFFFFF00);
961 sin.sin_family = AF_INET;
964 memcpy (&ifr.ifr_ifru.ifru_addr, &sin, sizeof (sin));
966 if (ioctl (dev_tap_fd, SIOCSIFADDR, &ifr) < 0)
968 rv = VNET_API_ERROR_SYSCALL_ERROR_10;
978 mask = clib_host_to_net_u32 (mask);
979 sin.sin_family = AF_INET;
981 sin.sin_addr.s_addr = mask;
982 memcpy (&ifr.ifr_ifru.ifru_addr, &sin, sizeof (sin));
984 if (ioctl (dev_tap_fd, SIOCSIFNETMASK, &ifr) < 0)
986 rv = VNET_API_ERROR_SYSCALL_ERROR_10;
997 sockfd6 = socket (AF_INET6, SOCK_DGRAM, IPPROTO_IP);
1000 rv = VNET_API_ERROR_SYSCALL_ERROR_10;
1005 strncpy (ifr2.ifr_name, (
char *) ap->
intfc_name,
1006 sizeof (ifr2.ifr_name) - 1);
1007 if (ioctl (sockfd6, SIOCGIFINDEX, &ifr2) < 0)
1010 rv = VNET_API_ERROR_SYSCALL_ERROR_4;
1016 ifr6.ifindex = ifr2.ifr_ifindex;
1018 if (ioctl (sockfd6, SIOCSIFADDR, &ifr6) < 0)
1022 rv = VNET_API_ERROR_SYSCALL_ERROR_10;
1037 rnd = (
u32) (now * 1e6);
1040 memcpy (hwaddr + 2, &rnd,
sizeof (rnd));
1055 rv = VNET_API_ERROR_INVALID_REGISTRATION;
1062 template.file_descriptor = dev_net_tun_fd;
1091 close (dev_net_tun_fd);
1092 if (dev_tap_fd >= 0)
1180 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
1236 vlib_cli_output (vm,
"Error during deletion of tap interface. (rc: %d)",
1245 .path =
"tap delete",
1246 .short_help =
"tap delete <vpp-tap-intfc-name>",
1295 u32 new_sw_if_index = ~0;
1296 int user_hwaddr = 0;
1312 if (
unformat (input,
"%s", &intfc_name))
1340 "Error during modification of tap interface. (rc: %d)",
1349 .path =
"tap modify",
1350 .short_help =
"tap modify <vpp-tap-intfc-name> <linux-intfc-name> [hwaddr <addr>]",
1377 int ip4_address_set = 0;
1379 int ip6_address_set = 0;
1380 u32 ip4_mask_width = 0;
1381 u32 ip6_mask_width = 0;
1394 hwaddr_arg = hwaddr;
1397 else if (
unformat (line_input,
"hwaddr random"))
1400 else if (
unformat (line_input,
"address %U/%d",
1402 ip4_address_set = 1;
1404 else if (
unformat (line_input,
"address %U/%d",
1406 ip6_address_set = 1;
1408 else if (
unformat (line_input,
"%s", &intfc_name))
1418 if (intfc_name == 0)
1428 if (ip4_address_set)
1434 if (ip6_address_set)
1447 case VNET_API_ERROR_SYSCALL_ERROR_1:
1451 case VNET_API_ERROR_SYSCALL_ERROR_2:
1456 case VNET_API_ERROR_SYSCALL_ERROR_3:
1460 case VNET_API_ERROR_SYSCALL_ERROR_4:
1464 case VNET_API_ERROR_SYSCALL_ERROR_5:
1468 case VNET_API_ERROR_SYSCALL_ERROR_6:
1472 case VNET_API_ERROR_SYSCALL_ERROR_7:
1476 case VNET_API_ERROR_SYSCALL_ERROR_8:
1480 case VNET_API_ERROR_SYSCALL_ERROR_9:
1484 case VNET_API_ERROR_SYSCALL_ERROR_10:
1488 case VNET_API_ERROR_INVALID_REGISTRATION:
1511 .path =
"tap connect",
1513 "tap connect <intfc-name> [address <ip-addr>/mw] [hwaddr <addr>]",
u32 per_interface_next_index
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
vlib_main_t * vlib_main
convenience - vlib_main_t
static int tap_name_renumber(vnet_hw_interface_t *hi, u32 new_dev_instance)
Renumber TAPCLI interface.
static void clib_file_del(clib_file_main_t *um, clib_file_t *f)
u32 * show_dev_instance_by_real_dev_instance
renumbering table
#define hash_set(h, key, value)
uword * tapcli_interface_index_by_unix_fd
Hash table to find tapcli interface given unix fd.
static vlib_node_registration_t tapcli_tx_node
(constructor) VLIB_REGISTER_NODE (tapcli_tx_node)
static u32 vlib_get_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt)
#define hash_unset(h, key)
static void vlib_increment_combined_counter(vlib_combined_counter_main_t *cm, u32 thread_index, u32 index, u64 n_packets, u64 n_bytes)
Increment a combined counter.
static void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
u8 * intfc_name
Interface name.
vnet_main_t * vnet_get_main(void)
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
int vnet_tap_connect_renumber(vlib_main_t *vm, vnet_tap_connect_args_t *ap)
Renumber a TAP interface.
vnet_interface_main_t interface_main
static clib_error_t * tap_delete_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
CLI function to delete TAP interface.
static void vlib_node_set_interrupt_pending(vlib_main_t *vm, u32 node_index)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static f64 vlib_time_now(vlib_main_t *vm)
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
u32 * sw_if_indexp
Output parameter: result sw_if_index.
static clib_error_t * tapcli_read_ready(clib_file_t *uf)
Gets called when file descriptor is ready from epoll.
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
int vnet_interface_name_renumber(u32 sw_if_index, u32 new_show_dev_instance)
u32 custom_dev_instance
Custom device instance.
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
static uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
unformat_function_t unformat_vnet_sw_interface
VNET_DEVICE_CLASS(tapcli_dev_class, static)
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
struct _vnet_device_class vnet_device_class_t
vlib_error_t * errors
Vector of errors for this node.
arguments structure for vnet_tap_connect, vnet_tap_connect_renumber, etc.
TAP CLI interface details struct.
int vnet_tap_modify(vlib_main_t *vm, vnet_tap_connect_args_t *ap)
Modifies tap interface - can result in new interface being created.
#define vec_alloc(V, N)
Allocate space for N more elements (no header, unspecified alignment)
format_function_t format_vnet_sw_if_index_name
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
clib_file_function_t * read_function
#define clib_memcpy(d, s, n)
static void vlib_trace_buffer(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, vlib_buffer_t *b, int follow_chain)
int vnet_tap_connect(vlib_main_t *vm, vnet_tap_connect_args_t *ap)
Connect a TAP interface.
#define foreach_tapcli_error
TAP CLI errors.
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
static clib_error_t * tap_modify_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
CLI function to modify TAP interface.
static vnet_device_class_t tapcli_dev_class
u8 ip6_address_set
Please set the indicated ip4 address/mask on the interface.
#define VLIB_INIT_FUNCTION(x)
u32 ip4_mask_width
(optional) ip4 mask width to set
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
tapcli_per_thread_t * threads
per thread variables
static tapcli_main_t tapcli_main
#define clib_error_return(e, args...)
clib_file_main_t file_main
static clib_error_t * tapcli_config(vlib_main_t *vm, unformat_input_t *input)
CLI function for TAPCLI configuration.
pthread_t thread[MAX_CONNS]
static tapcli_interface_t * tapcli_get_new_tapif()
Get tap interface from inactive interfaces or create new.
struct iovec * iovecs
Vector of iovecs for readv/writev calls.
u32 max_supported_packet_bytes
#define clib_bitmap_foreach(i, ai, body)
Macro to iterate across set bits in a bitmap.
u16 current_length
Nbytes between current data and the end of this buffer.
static vnet_hw_interface_class_t tapcli_interface_class
u32 * rx_buffers
Vector of VLIB rx buffers to use.
uword * tapcli_interface_index_by_sw_if_index
Hash table to find tapcli interface given hw_if_index.
static uword tapcli_tx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
tapcli TX node function
void vlib_frame_free(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_frame_t *f)
static char * tapcli_rx_error_strings[]
TAPCLI error strings.
#define VLIB_CONFIG_FUNCTION(x, n,...)
vnet_sw_interface_flags_t flags
static u32 tapcli_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hw, u32 flags)
Modify interface flags for TAPCLI interface.
#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).
u32 mtu_bytes
Interface MTU in bytes and # of default sized buffers.
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Call from VLIB_INIT_FUNCTION to set the Linux kernel inject node name.
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
#define VLIB_REGISTER_NODE(x,...)
u8 renumber
Renumber the (existing) interface.
static uword tapcli_rx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
tapcli RX node function
static int tapcli_tap_disconnect(tapcli_interface_t *ti)
Disconnect TAP CLI interface.
static void tapcli_nopunt_frame(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Free "no punt" frame.
u8 * format_tapcli_tx_trace(u8 *s, va_list *va)
#define clib_warning(format, args...)
tapcli_interface_t * tapcli_interfaces
Vector of tap interfaces.
#define ETHERNET_INTERFACE_FLAG_MTU
#define ETHERNET_INTERFACE_FLAG_ACCEPT_ALL
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.
#define VLIB_BUFFER_DATA_SIZE
static u8 * format_tapcli_interface_name(u8 *s, va_list *args)
Formatter for TAPCLI interface name.
#define VLIB_CLI_COMMAND(x,...)
#define hash_create(elts, value_bytes)
uword unformat_ethernet_address(unformat_input_t *input, va_list *args)
static uword clib_file_add(clib_file_main_t *um, clib_file_t *template)
static uword tapcli_rx_iface(vlib_main_t *vm, vlib_node_runtime_t *node, tapcli_interface_t *ti)
Dispatch tapcli RX node function for node tap_cli_rx.
u8 ip4_address_set
Please set the indicated ip4 address/mask on the interface.
u32 next_buffer
Next buffer for this linked-list of buffers.
clib_error_t * ethernet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u8 *address, u32 *hw_if_index_return, ethernet_flag_change_function_t flag_change)
u8 * format_tapcli_rx_trace(u8 *s, va_list *va)
Function to format TAP CLI trace.
#define clib_error_report(e)
int vnet_tap_delete(vlib_main_t *vm, u32 sw_if_index)
Delete TAP interface.
ip4_address_t * ip4_address
(optional) ip4 address to set
static clib_error_t * tapcli_interface_admin_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Set link_state == admin_state otherwise things like ip6 neighbor discovery breaks.
VNET_HW_INTERFACE_CLASS(tapcli_interface_class, static)
static vlib_main_t * vlib_get_main(void)
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
u32 total_length_not_including_first_buffer
Only valid for first buffer in chain.
struct _vlib_node_registration vlib_node_registration_t
struct _vnet_hw_interface_class vnet_hw_interface_class_t
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, vnet_hw_interface_flags_t flags)
#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
u32 * tapcli_inactive_interfaces
Vector of deleted tap interfaces.
int is_disabled
1 => disable CLI
vnet_main_t * vnet_main
convenience - vnet_main_t
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
#define clib_unix_warning(format, args...)
a point 2 point interface
void vnet_sw_interface_set_mtu(vnet_main_t *vnm, u32 sw_if_index, u32 mtu)
u8 * hwaddr_arg
Mac address.
static u32 random_u32(u32 *seed)
32-bit random number generator
u32 min_supported_packet_bytes
static_always_inline void vnet_feature_start_device_input_x1(u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, vnet_sw_interface_flags_t flags)
static vlib_thread_main_t * vlib_get_thread_main()
clib_error_t * tapcli_init(vlib_main_t *vm)
TAPCLI main init.
void(* os_punt_frame)(struct vlib_main_t *vm, struct vlib_node_runtime_t *node, vlib_frame_t *frame)
#define vec_foreach(var, vec)
Vector iterator.
u32 sw_if_index
For counters.
static void vlib_set_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt, u32 count)
#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_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
static u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
Struct for the tapcli interface.
int vnet_tap_dump_ifs(tapcli_interface_details_t **out_tapids)
Dump TAP interfaces.
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
uword * pending_read_bitmap
Bitmap of tap interfaces with pending reads.
u32 ip6_mask_width
(optional) ip6 mask width to set
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
u32 orig_sw_if_index
original sw_if_index (renumber)
ip6_address_t * ip6_address
(optional) ip6 address to set
TAPCLI per thread struct.
static void tapcli_set_interface_next_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Setting the TAP interface's next processing node.
TAPCLI main state struct.
static vlib_node_registration_t tapcli_rx_node
(constructor) VLIB_REGISTER_NODE (tapcli_rx_node)
static clib_error_t * tap_connect_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
CLI function to connect TAP interface.