Coding standards cleanup in vnet/vnet/devices, fixes VPP-248
Change-Id: I35cf89bf1aa54b76294876e9feb0ed0ccc316975 Signed-off-by: Damjan Marion <damarion@cisco.com>
This commit is contained in:
committed by
Dave Barach
parent
5a5f5aac91
commit
00a9dcad03
File diff suppressed because it is too large
Load Diff
@@ -17,14 +17,15 @@
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
CLIB_CACHE_LINE_ALIGN_MARK(cacheline0);
|
||||
u8 * host_if_name;
|
||||
typedef struct
|
||||
{
|
||||
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
|
||||
u8 *host_if_name;
|
||||
int fd;
|
||||
struct tpacket_req * rx_req;
|
||||
struct tpacket_req * tx_req;
|
||||
u8 * rx_ring;
|
||||
u8 * tx_ring;
|
||||
struct tpacket_req *rx_req;
|
||||
struct tpacket_req *tx_req;
|
||||
u8 *rx_ring;
|
||||
u8 *tx_ring;
|
||||
u32 hw_if_index;
|
||||
u32 sw_if_index;
|
||||
u32 unix_file_index;
|
||||
@@ -36,15 +37,16 @@ typedef struct {
|
||||
u8 is_admin_up;
|
||||
} af_packet_if_t;
|
||||
|
||||
typedef struct {
|
||||
CLIB_CACHE_LINE_ALIGN_MARK(cacheline0);
|
||||
af_packet_if_t * interfaces;
|
||||
typedef struct
|
||||
{
|
||||
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
|
||||
af_packet_if_t *interfaces;
|
||||
|
||||
/* bitmap of pending rx interfaces */
|
||||
uword * pending_input_bitmap;
|
||||
uword *pending_input_bitmap;
|
||||
|
||||
/* rx buffer cache */
|
||||
u32 * rx_buffers;
|
||||
u32 *rx_buffers;
|
||||
|
||||
/* hash of host interface names */
|
||||
mhash_t if_index_by_host_if_name;
|
||||
@@ -54,5 +56,14 @@ af_packet_main_t af_packet_main;
|
||||
extern vnet_device_class_t af_packet_device_class;
|
||||
extern vlib_node_registration_t af_packet_input_node;
|
||||
|
||||
int af_packet_create_if(vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set, u32 *sw_if_index);
|
||||
int af_packet_delete_if(vlib_main_t * vm, u8 * host_if_name);
|
||||
int af_packet_create_if (vlib_main_t * vm, u8 * host_if_name,
|
||||
u8 * hw_addr_set, u32 * sw_if_index);
|
||||
int af_packet_delete_if (vlib_main_t * vm, u8 * host_if_name);
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
@@ -36,85 +36,94 @@ static clib_error_t *
|
||||
af_packet_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
|
||||
vlib_cli_command_t * cmd)
|
||||
{
|
||||
unformat_input_t _line_input, * line_input = &_line_input;
|
||||
u8 * host_if_name = NULL;
|
||||
u8 hwaddr [6];
|
||||
u8 * hw_addr_ptr = 0;
|
||||
unformat_input_t _line_input, *line_input = &_line_input;
|
||||
u8 *host_if_name = NULL;
|
||||
u8 hwaddr[6];
|
||||
u8 *hw_addr_ptr = 0;
|
||||
u32 sw_if_index;
|
||||
int r;
|
||||
|
||||
/* Get a line of input. */
|
||||
if (! unformat_user (input, unformat_line_input, line_input))
|
||||
if (!unformat_user (input, unformat_line_input, line_input))
|
||||
return 0;
|
||||
|
||||
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
|
||||
{
|
||||
if (unformat (line_input, "name %s", &host_if_name))
|
||||
;
|
||||
else if (unformat (line_input, "hw-addr %U", unformat_ethernet_address, hwaddr))
|
||||
else
|
||||
if (unformat
|
||||
(line_input, "hw-addr %U", unformat_ethernet_address, hwaddr))
|
||||
hw_addr_ptr = hwaddr;
|
||||
else
|
||||
return clib_error_return (0, "unknown input `%U'", format_unformat_error, input);
|
||||
return clib_error_return (0, "unknown input `%U'",
|
||||
format_unformat_error, input);
|
||||
}
|
||||
unformat_free (line_input);
|
||||
|
||||
if (host_if_name == NULL)
|
||||
return clib_error_return (0, "missing host interface name");
|
||||
return clib_error_return (0, "missing host interface name");
|
||||
|
||||
r = af_packet_create_if(vm, host_if_name, hw_addr_ptr, &sw_if_index);
|
||||
r = af_packet_create_if (vm, host_if_name, hw_addr_ptr, &sw_if_index);
|
||||
|
||||
if (r == VNET_API_ERROR_SYSCALL_ERROR_1)
|
||||
return clib_error_return(0, "%s (errno %d)", strerror (errno), errno);
|
||||
return clib_error_return (0, "%s (errno %d)", strerror (errno), errno);
|
||||
|
||||
if (r == VNET_API_ERROR_INVALID_INTERFACE)
|
||||
return clib_error_return(0, "Invalid interface name");
|
||||
return clib_error_return (0, "Invalid interface name");
|
||||
|
||||
if (r == VNET_API_ERROR_SUBIF_ALREADY_EXISTS)
|
||||
return clib_error_return(0, "Interface elready exists");
|
||||
return clib_error_return (0, "Interface elready exists");
|
||||
|
||||
vlib_cli_output(vm, "%U\n", format_vnet_sw_if_index_name, vnet_get_main(), sw_if_index);
|
||||
vlib_cli_output (vm, "%U\n", format_vnet_sw_if_index_name, vnet_get_main (),
|
||||
sw_if_index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
VLIB_CLI_COMMAND (af_packet_create_command, static) = {
|
||||
.path = "create host-interface",
|
||||
.short_help = "create host-interface name <interface name> [hw-addr <mac>]",
|
||||
.function = af_packet_create_command_fn,
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
static clib_error_t *
|
||||
af_packet_delete_command_fn (vlib_main_t * vm, unformat_input_t * input,
|
||||
vlib_cli_command_t * cmd)
|
||||
vlib_cli_command_t * cmd)
|
||||
{
|
||||
unformat_input_t _line_input, * line_input = &_line_input;
|
||||
u8 * host_if_name = NULL;
|
||||
unformat_input_t _line_input, *line_input = &_line_input;
|
||||
u8 *host_if_name = NULL;
|
||||
|
||||
/* Get a line of input. */
|
||||
if (! unformat_user (input, unformat_line_input, line_input))
|
||||
if (!unformat_user (input, unformat_line_input, line_input))
|
||||
return 0;
|
||||
|
||||
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
|
||||
{
|
||||
if (unformat (line_input, "name %s", &host_if_name))
|
||||
;
|
||||
;
|
||||
else
|
||||
return clib_error_return (0, "unknown input `%U'", format_unformat_error, input);
|
||||
return clib_error_return (0, "unknown input `%U'",
|
||||
format_unformat_error, input);
|
||||
}
|
||||
unformat_free (line_input);
|
||||
|
||||
if (host_if_name == NULL)
|
||||
return clib_error_return (0, "missing host interface name");
|
||||
return clib_error_return (0, "missing host interface name");
|
||||
|
||||
af_packet_delete_if(vm, host_if_name);
|
||||
af_packet_delete_if (vm, host_if_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
VLIB_CLI_COMMAND (af_packet_delete_command, static) = {
|
||||
.path = "delete host-interface",
|
||||
.short_help = "delete host-interface name <interface name>",
|
||||
.function = af_packet_delete_command_fn,
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
clib_error_t *
|
||||
af_packet_cli_init (vlib_main_t * vm)
|
||||
@@ -123,3 +132,11 @@ af_packet_cli_init (vlib_main_t * vm)
|
||||
}
|
||||
|
||||
VLIB_INIT_FUNCTION (af_packet_cli_init);
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
@@ -32,37 +32,41 @@ _(TXRING_EAGAIN, "tx sendto temporary failure") \
|
||||
_(TXRING_FATAL, "tx sendto fatal failure") \
|
||||
_(TXRING_OVERRUN, "tx ring overrun")
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
#define _(f,s) AF_PACKET_TX_ERROR_##f,
|
||||
foreach_af_packet_tx_func_error
|
||||
#undef _
|
||||
AF_PACKET_TX_N_ERROR,
|
||||
AF_PACKET_TX_N_ERROR,
|
||||
} af_packet_tx_func_error_t;
|
||||
|
||||
static char * af_packet_tx_func_error_strings[] = {
|
||||
static char *af_packet_tx_func_error_strings[] = {
|
||||
#define _(n,s) s,
|
||||
foreach_af_packet_tx_func_error
|
||||
foreach_af_packet_tx_func_error
|
||||
#undef _
|
||||
};
|
||||
|
||||
|
||||
static u8 * format_af_packet_device_name (u8 * s, va_list * args)
|
||||
static u8 *
|
||||
format_af_packet_device_name (u8 * s, va_list * args)
|
||||
{
|
||||
u32 i = va_arg (*args, u32);
|
||||
af_packet_main_t * apm = &af_packet_main;
|
||||
af_packet_if_t * apif = pool_elt_at_index (apm->interfaces, i);
|
||||
af_packet_main_t *apm = &af_packet_main;
|
||||
af_packet_if_t *apif = pool_elt_at_index (apm->interfaces, i);
|
||||
|
||||
s = format (s, "host-%s", apif->host_if_name);
|
||||
return s;
|
||||
}
|
||||
|
||||
static u8 * format_af_packet_device (u8 * s, va_list * args)
|
||||
static u8 *
|
||||
format_af_packet_device (u8 * s, va_list * args)
|
||||
{
|
||||
s = format (s, "Linux PACKET socket interface");
|
||||
return s;
|
||||
}
|
||||
|
||||
static u8 * format_af_packet_tx_trace (u8 * s, va_list * args)
|
||||
static u8 *
|
||||
format_af_packet_tx_trace (u8 * s, va_list * args)
|
||||
{
|
||||
s = format (s, "Unimplemented...");
|
||||
return s;
|
||||
@@ -70,36 +74,37 @@ static u8 * format_af_packet_tx_trace (u8 * s, va_list * args)
|
||||
|
||||
static uword
|
||||
af_packet_interface_tx (vlib_main_t * vm,
|
||||
vlib_node_runtime_t * node,
|
||||
vlib_frame_t * frame)
|
||||
vlib_node_runtime_t * node, vlib_frame_t * frame)
|
||||
{
|
||||
af_packet_main_t * apm = &af_packet_main;
|
||||
u32 * buffers = vlib_frame_args (frame);
|
||||
af_packet_main_t *apm = &af_packet_main;
|
||||
u32 *buffers = vlib_frame_args (frame);
|
||||
u32 n_left = frame->n_vectors;
|
||||
u32 n_sent = 0;
|
||||
vnet_interface_output_runtime_t * rd = (void *) node->runtime_data;
|
||||
af_packet_if_t * apif = pool_elt_at_index (apm->interfaces, rd->dev_instance);
|
||||
vnet_interface_output_runtime_t *rd = (void *) node->runtime_data;
|
||||
af_packet_if_t *apif =
|
||||
pool_elt_at_index (apm->interfaces, rd->dev_instance);
|
||||
int block = 0;
|
||||
u32 block_size = apif->tx_req->tp_block_size;
|
||||
u32 frame_size = apif->tx_req->tp_frame_size;
|
||||
u32 frame_num = apif->tx_req->tp_frame_nr;
|
||||
u8 * block_start = apif->tx_ring + block * block_size;
|
||||
u8 *block_start = apif->tx_ring + block * block_size;
|
||||
u32 tx_frame = apif->next_tx_frame;
|
||||
struct tpacket2_hdr * tph;
|
||||
struct tpacket2_hdr *tph;
|
||||
u32 frame_not_ready = 0;
|
||||
|
||||
while(n_left > 0)
|
||||
while (n_left > 0)
|
||||
{
|
||||
u32 len;
|
||||
u32 offset = 0;
|
||||
vlib_buffer_t * b0;
|
||||
vlib_buffer_t *b0;
|
||||
n_left--;
|
||||
u32 bi = buffers[0];
|
||||
buffers++;
|
||||
|
||||
tph = (struct tpacket2_hdr *) (block_start + tx_frame * frame_size);
|
||||
|
||||
if (PREDICT_FALSE(tph->tp_status & (TP_STATUS_SEND_REQUEST | TP_STATUS_SENDING)))
|
||||
if (PREDICT_FALSE
|
||||
(tph->tp_status & (TP_STATUS_SEND_REQUEST | TP_STATUS_SENDING)))
|
||||
{
|
||||
frame_not_ready++;
|
||||
goto next;
|
||||
@@ -109,8 +114,9 @@ af_packet_interface_tx (vlib_main_t * vm,
|
||||
{
|
||||
b0 = vlib_get_buffer (vm, bi);
|
||||
len = b0->current_length;
|
||||
clib_memcpy((u8 *) tph + TPACKET_ALIGN(sizeof(struct tpacket2_hdr)) + offset,
|
||||
vlib_buffer_get_current(b0), len);
|
||||
clib_memcpy ((u8 *) tph +
|
||||
TPACKET_ALIGN (sizeof (struct tpacket2_hdr)) + offset,
|
||||
vlib_buffer_get_current (b0), len);
|
||||
offset += len;
|
||||
}
|
||||
while ((bi = b0->next_buffer));
|
||||
@@ -118,54 +124,54 @@ af_packet_interface_tx (vlib_main_t * vm,
|
||||
tph->tp_len = tph->tp_snaplen = offset;
|
||||
tph->tp_status = TP_STATUS_SEND_REQUEST;
|
||||
n_sent++;
|
||||
next:
|
||||
next:
|
||||
/* check if we've exhausted the ring */
|
||||
if (PREDICT_FALSE(frame_not_ready + n_sent == frame_num))
|
||||
break;
|
||||
if (PREDICT_FALSE (frame_not_ready + n_sent == frame_num))
|
||||
break;
|
||||
|
||||
tx_frame = (tx_frame + 1) % frame_num;
|
||||
}
|
||||
|
||||
CLIB_MEMORY_BARRIER();
|
||||
CLIB_MEMORY_BARRIER ();
|
||||
|
||||
if (PREDICT_TRUE(n_sent))
|
||||
if (PREDICT_TRUE (n_sent))
|
||||
{
|
||||
apif->next_tx_frame = tx_frame;
|
||||
|
||||
if (PREDICT_FALSE(sendto(apif->fd, NULL, 0,
|
||||
MSG_DONTWAIT, NULL, 0) == -1))
|
||||
{
|
||||
/* Uh-oh, drop & move on, but count whether it was fatal or not.
|
||||
* Note that we have no reliable way to properly determine the
|
||||
* disposition of the packets we just enqueued for delivery.
|
||||
*/
|
||||
vlib_error_count (vm, node->node_index,
|
||||
unix_error_is_fatal(errno) ?
|
||||
AF_PACKET_TX_ERROR_TXRING_FATAL :
|
||||
AF_PACKET_TX_ERROR_TXRING_EAGAIN,
|
||||
n_sent);
|
||||
}
|
||||
if (PREDICT_FALSE (sendto (apif->fd, NULL, 0,
|
||||
MSG_DONTWAIT, NULL, 0) == -1))
|
||||
{
|
||||
/* Uh-oh, drop & move on, but count whether it was fatal or not.
|
||||
* Note that we have no reliable way to properly determine the
|
||||
* disposition of the packets we just enqueued for delivery.
|
||||
*/
|
||||
vlib_error_count (vm, node->node_index,
|
||||
unix_error_is_fatal (errno) ?
|
||||
AF_PACKET_TX_ERROR_TXRING_FATAL :
|
||||
AF_PACKET_TX_ERROR_TXRING_EAGAIN, n_sent);
|
||||
}
|
||||
}
|
||||
|
||||
if (PREDICT_FALSE(frame_not_ready))
|
||||
vlib_error_count (vm, node->node_index, AF_PACKET_TX_ERROR_FRAME_NOT_READY,
|
||||
frame_not_ready);
|
||||
if (PREDICT_FALSE (frame_not_ready))
|
||||
vlib_error_count (vm, node->node_index,
|
||||
AF_PACKET_TX_ERROR_FRAME_NOT_READY, frame_not_ready);
|
||||
|
||||
if (PREDICT_FALSE(frame_not_ready + n_sent == frame_num))
|
||||
if (PREDICT_FALSE (frame_not_ready + n_sent == frame_num))
|
||||
vlib_error_count (vm, node->node_index, AF_PACKET_TX_ERROR_TXRING_OVERRUN,
|
||||
n_left);
|
||||
n_left);
|
||||
|
||||
vlib_buffer_free (vm, vlib_frame_args (frame), frame->n_vectors);
|
||||
return frame->n_vectors;
|
||||
}
|
||||
|
||||
static void
|
||||
af_packet_set_interface_next_node (vnet_main_t *vnm, u32 hw_if_index,
|
||||
u32 node_index)
|
||||
af_packet_set_interface_next_node (vnet_main_t * vnm, u32 hw_if_index,
|
||||
u32 node_index)
|
||||
{
|
||||
af_packet_main_t * apm = &af_packet_main;
|
||||
af_packet_main_t *apm = &af_packet_main;
|
||||
vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
|
||||
af_packet_if_t * apif = pool_elt_at_index (apm->interfaces, hw->dev_instance);
|
||||
af_packet_if_t *apif =
|
||||
pool_elt_at_index (apm->interfaces, hw->dev_instance);
|
||||
|
||||
/* Shut off redirection */
|
||||
if (node_index == ~0)
|
||||
@@ -175,20 +181,24 @@ af_packet_set_interface_next_node (vnet_main_t *vnm, u32 hw_if_index,
|
||||
}
|
||||
|
||||
apif->per_interface_next_index =
|
||||
vlib_node_add_next (vlib_get_main(), af_packet_input_node.index, node_index);
|
||||
vlib_node_add_next (vlib_get_main (), af_packet_input_node.index,
|
||||
node_index);
|
||||
}
|
||||
|
||||
static void af_packet_clear_hw_interface_counters (u32 instance)
|
||||
static void
|
||||
af_packet_clear_hw_interface_counters (u32 instance)
|
||||
{
|
||||
/* Nothing for now */
|
||||
}
|
||||
|
||||
static clib_error_t *
|
||||
af_packet_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
|
||||
af_packet_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index,
|
||||
u32 flags)
|
||||
{
|
||||
af_packet_main_t * apm = &af_packet_main;
|
||||
af_packet_main_t *apm = &af_packet_main;
|
||||
vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
|
||||
af_packet_if_t * apif = pool_elt_at_index (apm->interfaces, hw->dev_instance);
|
||||
af_packet_if_t *apif =
|
||||
pool_elt_at_index (apm->interfaces, hw->dev_instance);
|
||||
u32 hw_flags;
|
||||
|
||||
apif->is_admin_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;
|
||||
@@ -198,21 +208,21 @@ af_packet_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags
|
||||
else
|
||||
hw_flags = 0;
|
||||
|
||||
vnet_hw_interface_set_flags(vnm, hw_if_index, hw_flags);
|
||||
vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static clib_error_t *
|
||||
af_packet_subif_add_del_function (vnet_main_t * vnm,
|
||||
u32 hw_if_index,
|
||||
struct vnet_sw_interface_t * st,
|
||||
int is_add)
|
||||
u32 hw_if_index,
|
||||
struct vnet_sw_interface_t *st, int is_add)
|
||||
{
|
||||
/* Nothing for now */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
VNET_DEVICE_CLASS (af_packet_device_class) = {
|
||||
.name = "af-packet",
|
||||
.tx_function = af_packet_interface_tx,
|
||||
@@ -230,3 +240,12 @@ VNET_DEVICE_CLASS (af_packet_device_class) = {
|
||||
|
||||
VLIB_DEVICE_TX_FUNCTION_MULTIARCH (af_packet_device_class,
|
||||
af_packet_interface_tx)
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
@@ -28,75 +28,80 @@
|
||||
|
||||
#define foreach_af_packet_input_error
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
#define _(f,s) AF_PACKET_INPUT_ERROR_##f,
|
||||
foreach_af_packet_input_error
|
||||
#undef _
|
||||
AF_PACKET_INPUT_N_ERROR,
|
||||
AF_PACKET_INPUT_N_ERROR,
|
||||
} af_packet_input_error_t;
|
||||
|
||||
static char * af_packet_input_error_strings[] = {
|
||||
static char *af_packet_input_error_strings[] = {
|
||||
#define _(n,s) s,
|
||||
foreach_af_packet_input_error
|
||||
foreach_af_packet_input_error
|
||||
#undef _
|
||||
};
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
AF_PACKET_INPUT_NEXT_DROP,
|
||||
AF_PACKET_INPUT_NEXT_ETHERNET_INPUT,
|
||||
AF_PACKET_INPUT_N_NEXT,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
u32 next_index;
|
||||
u32 hw_if_index;
|
||||
int block;
|
||||
struct tpacket2_hdr tph;
|
||||
} af_packet_input_trace_t;
|
||||
|
||||
static u8 * format_af_packet_input_trace (u8 * s, va_list * args)
|
||||
static u8 *
|
||||
format_af_packet_input_trace (u8 * s, va_list * args)
|
||||
{
|
||||
CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
|
||||
CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
|
||||
af_packet_input_trace_t * t = va_arg (*args, af_packet_input_trace_t *);
|
||||
af_packet_input_trace_t *t = va_arg (*args, af_packet_input_trace_t *);
|
||||
uword indent = format_get_indent (s);
|
||||
|
||||
s = format (s, "af_packet: hw_if_index %d next-index %d",
|
||||
t->hw_if_index, t->next_index);
|
||||
|
||||
s = format (s, "\n%Utpacket2_hdr:\n%Ustatus 0x%x len %u snaplen %u mac %u net %u"
|
||||
"\n%Usec 0x%x nsec 0x%x vlan %U"
|
||||
s =
|
||||
format (s,
|
||||
"\n%Utpacket2_hdr:\n%Ustatus 0x%x len %u snaplen %u mac %u net %u"
|
||||
"\n%Usec 0x%x nsec 0x%x vlan %U"
|
||||
#ifdef TP_STATUS_VLAN_TPID_VALID
|
||||
" vlan_tpid %u"
|
||||
" vlan_tpid %u"
|
||||
#endif
|
||||
,
|
||||
format_white_space, indent + 2,
|
||||
format_white_space, indent + 4,
|
||||
t->tph.tp_status,
|
||||
t->tph.tp_len,
|
||||
t->tph.tp_snaplen,
|
||||
t->tph.tp_mac,
|
||||
t->tph.tp_net,
|
||||
format_white_space, indent + 4,
|
||||
t->tph.tp_sec,
|
||||
t->tph.tp_nsec,
|
||||
format_ethernet_vlan_tci, t->tph.tp_vlan_tci
|
||||
,
|
||||
format_white_space, indent + 2,
|
||||
format_white_space, indent + 4,
|
||||
t->tph.tp_status,
|
||||
t->tph.tp_len,
|
||||
t->tph.tp_snaplen,
|
||||
t->tph.tp_mac,
|
||||
t->tph.tp_net,
|
||||
format_white_space, indent + 4,
|
||||
t->tph.tp_sec,
|
||||
t->tph.tp_nsec, format_ethernet_vlan_tci, t->tph.tp_vlan_tci
|
||||
#ifdef TP_STATUS_VLAN_TPID_VALID
|
||||
, t->tph.tp_vlan_tpid
|
||||
, t->tph.tp_vlan_tpid
|
||||
#endif
|
||||
);
|
||||
);
|
||||
return s;
|
||||
}
|
||||
|
||||
always_inline void
|
||||
buffer_add_to_chain(vlib_main_t *vm, u32 bi, u32 first_bi, u32 prev_bi)
|
||||
buffer_add_to_chain (vlib_main_t * vm, u32 bi, u32 first_bi, u32 prev_bi)
|
||||
{
|
||||
vlib_buffer_t * b = vlib_get_buffer (vm, bi);
|
||||
vlib_buffer_t * first_b = vlib_get_buffer (vm, first_bi);
|
||||
vlib_buffer_t * prev_b = vlib_get_buffer (vm, prev_bi);
|
||||
vlib_buffer_t *b = vlib_get_buffer (vm, bi);
|
||||
vlib_buffer_t *first_b = vlib_get_buffer (vm, first_bi);
|
||||
vlib_buffer_t *prev_b = vlib_get_buffer (vm, prev_bi);
|
||||
|
||||
/* update first buffer */
|
||||
first_b->total_length_not_including_first_buffer += b->current_length;
|
||||
first_b->total_length_not_including_first_buffer += b->current_length;
|
||||
|
||||
/* update previous buffer */
|
||||
prev_b->next_buffer = bi;
|
||||
@@ -106,9 +111,9 @@ buffer_add_to_chain(vlib_main_t *vm, u32 bi, u32 first_bi, u32 prev_bi)
|
||||
b->next_buffer = 0;
|
||||
|
||||
#if DPDK > 0
|
||||
struct rte_mbuf * mbuf = rte_mbuf_from_vlib_buffer(b);
|
||||
struct rte_mbuf * first_mbuf = rte_mbuf_from_vlib_buffer(first_b);
|
||||
struct rte_mbuf * prev_mbuf = rte_mbuf_from_vlib_buffer(prev_b);
|
||||
struct rte_mbuf *mbuf = rte_mbuf_from_vlib_buffer (b);
|
||||
struct rte_mbuf *first_mbuf = rte_mbuf_from_vlib_buffer (first_b);
|
||||
struct rte_mbuf *prev_mbuf = rte_mbuf_from_vlib_buffer (prev_b);
|
||||
first_mbuf->nb_segs++;
|
||||
prev_mbuf->next = mbuf;
|
||||
mbuf->data_len = b->current_length;
|
||||
@@ -118,11 +123,11 @@ buffer_add_to_chain(vlib_main_t *vm, u32 bi, u32 first_bi, u32 prev_bi)
|
||||
}
|
||||
|
||||
always_inline uword
|
||||
af_packet_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
vlib_frame_t * frame, u32 device_idx)
|
||||
af_packet_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
vlib_frame_t * frame, u32 device_idx)
|
||||
{
|
||||
af_packet_main_t * apm = &af_packet_main;
|
||||
af_packet_if_t * apif = pool_elt_at_index(apm->interfaces, device_idx);
|
||||
af_packet_main_t *apm = &af_packet_main;
|
||||
af_packet_if_t *apif = pool_elt_at_index (apm->interfaces, device_idx);
|
||||
struct tpacket2_hdr *tph;
|
||||
u32 next_index = AF_PACKET_INPUT_NEXT_ETHERNET_INPUT;
|
||||
u32 block = 0;
|
||||
@@ -130,24 +135,26 @@ af_packet_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
u32 n_free_bufs;
|
||||
u32 n_rx_packets = 0;
|
||||
u32 n_rx_bytes = 0;
|
||||
u32 * to_next = 0;
|
||||
u32 *to_next = 0;
|
||||
u32 block_size = apif->rx_req->tp_block_size;
|
||||
u32 frame_size = apif->rx_req->tp_frame_size;
|
||||
u32 frame_num = apif->rx_req->tp_frame_nr;
|
||||
u8 * block_start = apif->rx_ring + block * block_size;
|
||||
u8 *block_start = apif->rx_ring + block * block_size;
|
||||
uword n_trace = vlib_get_trace_count (vm, node);
|
||||
u32 n_buffer_bytes = vlib_buffer_free_list_buffer_size (vm,
|
||||
VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
|
||||
VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
|
||||
u32 min_bufs = apif->rx_req->tp_frame_size / n_buffer_bytes;
|
||||
|
||||
if (apif->per_interface_next_index != ~0)
|
||||
next_index = apif->per_interface_next_index;
|
||||
next_index = apif->per_interface_next_index;
|
||||
|
||||
n_free_bufs = vec_len (apm->rx_buffers);
|
||||
if (PREDICT_FALSE(n_free_bufs < VLIB_FRAME_SIZE))
|
||||
if (PREDICT_FALSE (n_free_bufs < VLIB_FRAME_SIZE))
|
||||
{
|
||||
vec_validate(apm->rx_buffers, VLIB_FRAME_SIZE + n_free_bufs - 1);
|
||||
n_free_bufs += vlib_buffer_alloc(vm, &apm->rx_buffers[n_free_bufs], VLIB_FRAME_SIZE);
|
||||
vec_validate (apm->rx_buffers, VLIB_FRAME_SIZE + n_free_bufs - 1);
|
||||
n_free_bufs +=
|
||||
vlib_buffer_alloc (vm, &apm->rx_buffers[n_free_bufs],
|
||||
VLIB_FRAME_SIZE);
|
||||
_vec_len (apm->rx_buffers) = n_free_bufs;
|
||||
}
|
||||
|
||||
@@ -155,7 +162,7 @@ af_packet_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
tph = (struct tpacket2_hdr *) (block_start + rx_frame * frame_size);
|
||||
while ((tph->tp_status & TP_STATUS_USER) && (n_free_bufs > min_bufs))
|
||||
{
|
||||
vlib_buffer_t * b0, * first_b0 = 0;
|
||||
vlib_buffer_t *b0, *first_b0 = 0;
|
||||
u32 next0 = next_index;
|
||||
|
||||
u32 n_left_to_next;
|
||||
@@ -178,9 +185,11 @@ af_packet_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
n_free_bufs--;
|
||||
|
||||
/* copy data */
|
||||
u32 bytes_to_copy = data_len > n_buffer_bytes ? n_buffer_bytes : data_len;
|
||||
u32 bytes_to_copy =
|
||||
data_len > n_buffer_bytes ? n_buffer_bytes : data_len;
|
||||
b0->current_data = 0;
|
||||
clib_memcpy (vlib_buffer_get_current (b0), (u8 *) tph + tph->tp_mac + offset, bytes_to_copy);
|
||||
clib_memcpy (vlib_buffer_get_current (b0),
|
||||
(u8 *) tph + tph->tp_mac + offset, bytes_to_copy);
|
||||
|
||||
/* fill buffer header */
|
||||
b0->current_length = bytes_to_copy;
|
||||
@@ -188,19 +197,19 @@ af_packet_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
if (offset == 0)
|
||||
{
|
||||
#if DPDK > 0
|
||||
struct rte_mbuf * mb = rte_mbuf_from_vlib_buffer(b0);
|
||||
struct rte_mbuf *mb = rte_mbuf_from_vlib_buffer (b0);
|
||||
rte_pktmbuf_data_len (mb) = b0->current_length;
|
||||
rte_pktmbuf_pkt_len (mb) = b0->current_length;
|
||||
#endif
|
||||
b0->total_length_not_including_first_buffer = 0;
|
||||
b0->flags = VLIB_BUFFER_TOTAL_LENGTH_VALID;
|
||||
vnet_buffer(b0)->sw_if_index[VLIB_RX] = apif->sw_if_index;
|
||||
vnet_buffer(b0)->sw_if_index[VLIB_TX] = (u32)~0;
|
||||
vnet_buffer (b0)->sw_if_index[VLIB_RX] = apif->sw_if_index;
|
||||
vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
|
||||
first_bi0 = bi0;
|
||||
first_b0 = vlib_get_buffer(vm, first_bi0);
|
||||
first_b0 = vlib_get_buffer (vm, first_bi0);
|
||||
}
|
||||
else
|
||||
buffer_add_to_chain(vm, bi0, first_bi0, prev_bi0);
|
||||
buffer_add_to_chain (vm, bi0, first_bi0, prev_bi0);
|
||||
|
||||
offset += bytes_to_copy;
|
||||
data_len -= bytes_to_copy;
|
||||
@@ -212,22 +221,23 @@ af_packet_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
n_left_to_next--;
|
||||
|
||||
/* trace */
|
||||
VLIB_BUFFER_TRACE_TRAJECTORY_INIT(first_b0);
|
||||
if (PREDICT_FALSE(n_trace > 0))
|
||||
VLIB_BUFFER_TRACE_TRAJECTORY_INIT (first_b0);
|
||||
if (PREDICT_FALSE (n_trace > 0))
|
||||
{
|
||||
af_packet_input_trace_t *tr;
|
||||
vlib_trace_buffer (vm, node, next0, first_b0, /* follow_chain */ 0);
|
||||
vlib_trace_buffer (vm, node, next0, first_b0, /* follow_chain */
|
||||
0);
|
||||
vlib_set_trace_count (vm, node, --n_trace);
|
||||
tr = vlib_add_trace (vm, node, first_b0, sizeof (*tr));
|
||||
tr->next_index = next0;
|
||||
tr->hw_if_index = apif->hw_if_index;
|
||||
clib_memcpy(&tr->tph, tph, sizeof(struct tpacket2_hdr));
|
||||
clib_memcpy (&tr->tph, tph, sizeof (struct tpacket2_hdr));
|
||||
}
|
||||
/* enque and take next packet */
|
||||
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
|
||||
n_left_to_next, first_bi0, next0);
|
||||
|
||||
/* next packet */
|
||||
/* next packet */
|
||||
tph->tp_status = TP_STATUS_KERNEL;
|
||||
rx_frame = (rx_frame + 1) % frame_num;
|
||||
tph = (struct tpacket2_hdr *) (block_start + rx_frame * frame_size);
|
||||
@@ -239,11 +249,9 @@ af_packet_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
apif->next_rx_frame = rx_frame;
|
||||
|
||||
vlib_increment_combined_counter
|
||||
(vnet_get_main()->interface_main.combined_sw_if_counters
|
||||
(vnet_get_main ()->interface_main.combined_sw_if_counters
|
||||
+ VNET_INTERFACE_COUNTER_RX,
|
||||
os_get_cpu_number(),
|
||||
apif->hw_if_index,
|
||||
n_rx_packets, n_rx_bytes);
|
||||
os_get_cpu_number (), apif->hw_if_index, n_rx_packets, n_rx_bytes);
|
||||
|
||||
return n_rx_packets;
|
||||
}
|
||||
@@ -255,17 +263,20 @@ af_packet_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
int i;
|
||||
u32 n_rx_packets = 0;
|
||||
|
||||
af_packet_main_t * apm = &af_packet_main;
|
||||
af_packet_main_t *apm = &af_packet_main;
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
clib_bitmap_foreach (i, apm->pending_input_bitmap,
|
||||
({
|
||||
clib_bitmap_set (apm->pending_input_bitmap, i, 0);
|
||||
n_rx_packets += af_packet_device_input_fn(vm, node, frame, i);
|
||||
}));
|
||||
/* *INDENT-ON* */
|
||||
|
||||
return n_rx_packets;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
VLIB_REGISTER_NODE (af_packet_input_node) = {
|
||||
.function = af_packet_input_fn,
|
||||
.name = "af-packet-input",
|
||||
@@ -283,4 +294,13 @@ VLIB_REGISTER_NODE (af_packet_input_node) = {
|
||||
};
|
||||
|
||||
VLIB_NODE_FUNCTION_MULTIARCH (af_packet_input_node, af_packet_input_fn)
|
||||
/* *INDENT-ON* */
|
||||
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
@@ -27,26 +27,28 @@
|
||||
|
||||
static clib_error_t *
|
||||
netmap_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
|
||||
vlib_cli_command_t * cmd)
|
||||
vlib_cli_command_t * cmd)
|
||||
{
|
||||
unformat_input_t _line_input, * line_input = &_line_input;
|
||||
u8 * host_if_name = NULL;
|
||||
u8 hwaddr [6];
|
||||
u8 * hw_addr_ptr = 0;
|
||||
unformat_input_t _line_input, *line_input = &_line_input;
|
||||
u8 *host_if_name = NULL;
|
||||
u8 hwaddr[6];
|
||||
u8 *hw_addr_ptr = 0;
|
||||
int r;
|
||||
u8 is_pipe = 0;
|
||||
u8 is_master = 0;
|
||||
u32 sw_if_index = ~0;
|
||||
|
||||
/* Get a line of input. */
|
||||
if (! unformat_user (input, unformat_line_input, line_input))
|
||||
if (!unformat_user (input, unformat_line_input, line_input))
|
||||
return 0;
|
||||
|
||||
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
|
||||
{
|
||||
if (unformat (line_input, "name %s", &host_if_name))
|
||||
;
|
||||
else if (unformat (line_input, "hw-addr %U", unformat_ethernet_address, hwaddr))
|
||||
else
|
||||
if (unformat
|
||||
(line_input, "hw-addr %U", unformat_ethernet_address, hwaddr))
|
||||
hw_addr_ptr = hwaddr;
|
||||
else if (unformat (line_input, "pipe"))
|
||||
is_pipe = 1;
|
||||
@@ -55,68 +57,77 @@ netmap_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
|
||||
else if (unformat (line_input, "slave"))
|
||||
is_master = 0;
|
||||
else
|
||||
return clib_error_return (0, "unknown input `%U'", format_unformat_error, input);
|
||||
return clib_error_return (0, "unknown input `%U'",
|
||||
format_unformat_error, input);
|
||||
}
|
||||
unformat_free (line_input);
|
||||
|
||||
if (host_if_name == NULL)
|
||||
return clib_error_return (0, "missing host interface name");
|
||||
return clib_error_return (0, "missing host interface name");
|
||||
|
||||
r = netmap_create_if(vm, host_if_name, hw_addr_ptr, is_pipe, is_master, &sw_if_index);
|
||||
r =
|
||||
netmap_create_if (vm, host_if_name, hw_addr_ptr, is_pipe, is_master,
|
||||
&sw_if_index);
|
||||
|
||||
if (r == VNET_API_ERROR_SYSCALL_ERROR_1)
|
||||
return clib_error_return(0, "%s (errno %d)", strerror (errno), errno);
|
||||
return clib_error_return (0, "%s (errno %d)", strerror (errno), errno);
|
||||
|
||||
if (r == VNET_API_ERROR_INVALID_INTERFACE)
|
||||
return clib_error_return(0, "Invalid interface name");
|
||||
return clib_error_return (0, "Invalid interface name");
|
||||
|
||||
if (r == VNET_API_ERROR_SUBIF_ALREADY_EXISTS)
|
||||
return clib_error_return(0, "Interface already exists");
|
||||
return clib_error_return (0, "Interface already exists");
|
||||
|
||||
vlib_cli_output(vm, "%U\n", format_vnet_sw_if_index_name, vnet_get_main(), sw_if_index);
|
||||
vlib_cli_output (vm, "%U\n", format_vnet_sw_if_index_name, vnet_get_main (),
|
||||
sw_if_index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
VLIB_CLI_COMMAND (netmap_create_command, static) = {
|
||||
.path = "create netmap",
|
||||
.short_help = "create netmap name [<intf name>|valeXXX:YYY] "
|
||||
"[hw-addr <mac>] [pipe] [master|slave]",
|
||||
.function = netmap_create_command_fn,
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
static clib_error_t *
|
||||
netmap_delete_command_fn (vlib_main_t * vm, unformat_input_t * input,
|
||||
vlib_cli_command_t * cmd)
|
||||
vlib_cli_command_t * cmd)
|
||||
{
|
||||
unformat_input_t _line_input, * line_input = &_line_input;
|
||||
u8 * host_if_name = NULL;
|
||||
unformat_input_t _line_input, *line_input = &_line_input;
|
||||
u8 *host_if_name = NULL;
|
||||
|
||||
/* Get a line of input. */
|
||||
if (! unformat_user (input, unformat_line_input, line_input))
|
||||
if (!unformat_user (input, unformat_line_input, line_input))
|
||||
return 0;
|
||||
|
||||
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
|
||||
{
|
||||
if (unformat (line_input, "name %s", &host_if_name))
|
||||
;
|
||||
;
|
||||
else
|
||||
return clib_error_return (0, "unknown input `%U'", format_unformat_error, input);
|
||||
return clib_error_return (0, "unknown input `%U'",
|
||||
format_unformat_error, input);
|
||||
}
|
||||
unformat_free (line_input);
|
||||
|
||||
if (host_if_name == NULL)
|
||||
return clib_error_return (0, "missing host interface name");
|
||||
return clib_error_return (0, "missing host interface name");
|
||||
|
||||
netmap_delete_if(vm, host_if_name);
|
||||
netmap_delete_if (vm, host_if_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
VLIB_CLI_COMMAND (netmap_delete_command, static) = {
|
||||
.path = "delete netmap",
|
||||
.short_help = "delete netmap name <interface name>",
|
||||
.function = netmap_delete_command_fn,
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
clib_error_t *
|
||||
netmap_cli_init (vlib_main_t * vm)
|
||||
@@ -125,3 +136,11 @@ netmap_cli_init (vlib_main_t * vm)
|
||||
}
|
||||
|
||||
VLIB_INIT_FUNCTION (netmap_cli_init);
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
@@ -30,36 +30,39 @@
|
||||
_(NO_FREE_SLOTS, "no free tx slots") \
|
||||
_(PENDING_MSGS, "pending msgs in tx ring")
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
#define _(f,s) NETMAP_TX_ERROR_##f,
|
||||
foreach_netmap_tx_func_error
|
||||
#undef _
|
||||
NETMAP_TX_N_ERROR,
|
||||
NETMAP_TX_N_ERROR,
|
||||
} netmap_tx_func_error_t;
|
||||
|
||||
static char * netmap_tx_func_error_strings[] = {
|
||||
static char *netmap_tx_func_error_strings[] = {
|
||||
#define _(n,s) s,
|
||||
foreach_netmap_tx_func_error
|
||||
foreach_netmap_tx_func_error
|
||||
#undef _
|
||||
};
|
||||
|
||||
|
||||
static u8 * format_netmap_device_name (u8 * s, va_list * args)
|
||||
static u8 *
|
||||
format_netmap_device_name (u8 * s, va_list * args)
|
||||
{
|
||||
u32 i = va_arg (*args, u32);
|
||||
netmap_main_t * apm = &netmap_main;
|
||||
netmap_if_t * nif = pool_elt_at_index (apm->interfaces, i);
|
||||
netmap_main_t *apm = &netmap_main;
|
||||
netmap_if_t *nif = pool_elt_at_index (apm->interfaces, i);
|
||||
|
||||
s = format (s, "netmap-%s", nif->host_if_name);
|
||||
return s;
|
||||
}
|
||||
|
||||
static u8 * format_netmap_device (u8 * s, va_list * args)
|
||||
static u8 *
|
||||
format_netmap_device (u8 * s, va_list * args)
|
||||
{
|
||||
u32 dev_instance = va_arg (*args, u32);
|
||||
int verbose = va_arg (*args, int);
|
||||
netmap_main_t * nm = &netmap_main;
|
||||
netmap_if_t * nif = vec_elt_at_index (nm->interfaces, dev_instance);
|
||||
netmap_main_t *nm = &netmap_main;
|
||||
netmap_if_t *nif = vec_elt_at_index (nm->interfaces, dev_instance);
|
||||
uword indent = format_get_indent (s);
|
||||
|
||||
s = format (s, "NETMAP interface");
|
||||
@@ -78,13 +81,13 @@ static u8 * format_netmap_device (u8 * s, va_list * args)
|
||||
format_white_space, indent + 2,
|
||||
nif->req->nr_tx_slots,
|
||||
nif->req->nr_rx_slots,
|
||||
nif->req->nr_tx_rings,
|
||||
nif->req->nr_rx_rings);
|
||||
nif->req->nr_tx_rings, nif->req->nr_rx_rings);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static u8 * format_netmap_tx_trace (u8 * s, va_list * args)
|
||||
static u8 *
|
||||
format_netmap_tx_trace (u8 * s, va_list * args)
|
||||
{
|
||||
s = format (s, "Unimplemented...");
|
||||
return s;
|
||||
@@ -92,95 +95,96 @@ static u8 * format_netmap_tx_trace (u8 * s, va_list * args)
|
||||
|
||||
static uword
|
||||
netmap_interface_tx (vlib_main_t * vm,
|
||||
vlib_node_runtime_t * node,
|
||||
vlib_frame_t * frame)
|
||||
vlib_node_runtime_t * node, vlib_frame_t * frame)
|
||||
{
|
||||
netmap_main_t * nm = &netmap_main;
|
||||
u32 * buffers = vlib_frame_args (frame);
|
||||
netmap_main_t *nm = &netmap_main;
|
||||
u32 *buffers = vlib_frame_args (frame);
|
||||
u32 n_left = frame->n_vectors;
|
||||
f64 const time_constant = 1e3;
|
||||
vnet_interface_output_runtime_t * rd = (void *) node->runtime_data;
|
||||
netmap_if_t * nif = pool_elt_at_index (nm->interfaces, rd->dev_instance);
|
||||
vnet_interface_output_runtime_t *rd = (void *) node->runtime_data;
|
||||
netmap_if_t *nif = pool_elt_at_index (nm->interfaces, rd->dev_instance);
|
||||
int cur_ring;
|
||||
|
||||
if (PREDICT_FALSE(nif->lockp != 0))
|
||||
if (PREDICT_FALSE (nif->lockp != 0))
|
||||
{
|
||||
while (__sync_lock_test_and_set (nif->lockp, 1))
|
||||
;
|
||||
;
|
||||
}
|
||||
|
||||
cur_ring = nif->first_tx_ring;
|
||||
|
||||
while(n_left && cur_ring <= nif->last_tx_ring)
|
||||
while (n_left && cur_ring <= nif->last_tx_ring)
|
||||
{
|
||||
struct netmap_ring * ring = NETMAP_TXRING(nif->nifp, cur_ring);
|
||||
int n_free_slots = nm_ring_space(ring);
|
||||
struct netmap_ring *ring = NETMAP_TXRING (nif->nifp, cur_ring);
|
||||
int n_free_slots = nm_ring_space (ring);
|
||||
uint cur = ring->cur;
|
||||
|
||||
if (nm_tx_pending(ring))
|
||||
{
|
||||
if (ioctl(nif->fd, NIOCTXSYNC, NULL) < 0)
|
||||
clib_unix_warning ("NIOCTXSYNC");
|
||||
clib_cpu_time_wait(time_constant);
|
||||
|
||||
if (nm_tx_pending(ring) && !n_free_slots)
|
||||
{
|
||||
cur_ring++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (nm_tx_pending (ring))
|
||||
{
|
||||
if (ioctl (nif->fd, NIOCTXSYNC, NULL) < 0)
|
||||
clib_unix_warning ("NIOCTXSYNC");
|
||||
clib_cpu_time_wait (time_constant);
|
||||
|
||||
if (nm_tx_pending (ring) && !n_free_slots)
|
||||
{
|
||||
cur_ring++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
while (n_left && n_free_slots)
|
||||
{
|
||||
vlib_buffer_t * b0 = 0;
|
||||
vlib_buffer_t *b0 = 0;
|
||||
u32 bi = buffers[0];
|
||||
u32 len;
|
||||
u32 offset = 0;
|
||||
buffers++;
|
||||
|
||||
struct netmap_slot * slot = &ring->slot[cur];
|
||||
struct netmap_slot *slot = &ring->slot[cur];
|
||||
|
||||
do
|
||||
{
|
||||
b0 = vlib_get_buffer (vm, bi);
|
||||
len = b0->current_length;
|
||||
/* memcpy */
|
||||
clib_memcpy ((u8 *) NETMAP_BUF(ring, slot->buf_idx) + offset,
|
||||
vlib_buffer_get_current(b0), len);
|
||||
clib_memcpy ((u8 *) NETMAP_BUF (ring, slot->buf_idx) + offset,
|
||||
vlib_buffer_get_current (b0), len);
|
||||
offset += len;
|
||||
}
|
||||
while ((bi = b0->next_buffer));
|
||||
while ((bi = b0->next_buffer));
|
||||
|
||||
slot->len = offset;
|
||||
cur = (cur + 1) % ring->num_slots;
|
||||
n_free_slots--;
|
||||
n_left--;
|
||||
n_left--;
|
||||
}
|
||||
CLIB_MEMORY_BARRIER();
|
||||
CLIB_MEMORY_BARRIER ();
|
||||
ring->head = ring->cur = cur;
|
||||
}
|
||||
|
||||
if (n_left < frame->n_vectors)
|
||||
ioctl(nif->fd, NIOCTXSYNC, NULL);
|
||||
ioctl (nif->fd, NIOCTXSYNC, NULL);
|
||||
|
||||
if (PREDICT_FALSE(nif->lockp != 0))
|
||||
*nif->lockp = 0;
|
||||
if (PREDICT_FALSE (nif->lockp != 0))
|
||||
*nif->lockp = 0;
|
||||
|
||||
if (n_left)
|
||||
vlib_error_count (vm, node->node_index,
|
||||
(n_left == frame->n_vectors ? NETMAP_TX_ERROR_PENDING_MSGS : NETMAP_TX_ERROR_NO_FREE_SLOTS), n_left);
|
||||
(n_left ==
|
||||
frame->n_vectors ? NETMAP_TX_ERROR_PENDING_MSGS :
|
||||
NETMAP_TX_ERROR_NO_FREE_SLOTS), n_left);
|
||||
|
||||
vlib_buffer_free (vm, vlib_frame_args (frame), frame->n_vectors);
|
||||
return frame->n_vectors;
|
||||
}
|
||||
|
||||
static void
|
||||
netmap_set_interface_next_node (vnet_main_t *vnm, u32 hw_if_index,
|
||||
u32 node_index)
|
||||
netmap_set_interface_next_node (vnet_main_t * vnm, u32 hw_if_index,
|
||||
u32 node_index)
|
||||
{
|
||||
netmap_main_t * apm = &netmap_main;
|
||||
netmap_main_t *apm = &netmap_main;
|
||||
vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
|
||||
netmap_if_t * nif = pool_elt_at_index (apm->interfaces, hw->dev_instance);
|
||||
netmap_if_t *nif = pool_elt_at_index (apm->interfaces, hw->dev_instance);
|
||||
|
||||
/* Shut off redirection */
|
||||
if (node_index == ~0)
|
||||
@@ -190,10 +194,12 @@ netmap_set_interface_next_node (vnet_main_t *vnm, u32 hw_if_index,
|
||||
}
|
||||
|
||||
nif->per_interface_next_index =
|
||||
vlib_node_add_next (vlib_get_main(), netmap_input_node.index, node_index);
|
||||
vlib_node_add_next (vlib_get_main (), netmap_input_node.index,
|
||||
node_index);
|
||||
}
|
||||
|
||||
static void netmap_clear_hw_interface_counters (u32 instance)
|
||||
static void
|
||||
netmap_clear_hw_interface_counters (u32 instance)
|
||||
{
|
||||
/* Nothing for now */
|
||||
}
|
||||
@@ -201,9 +207,9 @@ static void netmap_clear_hw_interface_counters (u32 instance)
|
||||
static clib_error_t *
|
||||
netmap_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
|
||||
{
|
||||
netmap_main_t * apm = &netmap_main;
|
||||
netmap_main_t *apm = &netmap_main;
|
||||
vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
|
||||
netmap_if_t * nif = pool_elt_at_index (apm->interfaces, hw->dev_instance);
|
||||
netmap_if_t *nif = pool_elt_at_index (apm->interfaces, hw->dev_instance);
|
||||
u32 hw_flags;
|
||||
|
||||
nif->is_admin_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;
|
||||
@@ -213,21 +219,21 @@ netmap_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
|
||||
else
|
||||
hw_flags = 0;
|
||||
|
||||
vnet_hw_interface_set_flags(vnm, hw_if_index, hw_flags);
|
||||
vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static clib_error_t *
|
||||
netmap_subif_add_del_function (vnet_main_t * vnm,
|
||||
u32 hw_if_index,
|
||||
struct vnet_sw_interface_t * st,
|
||||
int is_add)
|
||||
u32 hw_if_index,
|
||||
struct vnet_sw_interface_t *st, int is_add)
|
||||
{
|
||||
/* Nothing for now */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
VNET_DEVICE_CLASS (netmap_device_class) = {
|
||||
.name = "netmap",
|
||||
.tx_function = netmap_interface_tx,
|
||||
@@ -245,3 +251,12 @@ VNET_DEVICE_CLASS (netmap_device_class) = {
|
||||
|
||||
VLIB_DEVICE_TX_FUNCTION_MULTIARCH(netmap_device_class,
|
||||
netmap_interface_tx)
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -40,10 +40,11 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
CLIB_CACHE_LINE_ALIGN_MARK(cacheline0);
|
||||
volatile u32 * lockp;
|
||||
u8 * host_if_name;
|
||||
typedef struct
|
||||
{
|
||||
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
|
||||
volatile u32 *lockp;
|
||||
u8 *host_if_name;
|
||||
uword if_index;
|
||||
u32 hw_if_index;
|
||||
u32 sw_if_index;
|
||||
@@ -53,10 +54,10 @@ typedef struct {
|
||||
u8 is_admin_up;
|
||||
|
||||
/* netmap */
|
||||
struct nmreq * req;
|
||||
struct nmreq *req;
|
||||
u16 mem_region;
|
||||
int fd;
|
||||
struct netmap_if * nifp;
|
||||
struct netmap_if *nifp;
|
||||
u16 first_tx_ring;
|
||||
u16 last_tx_ring;
|
||||
u16 first_rx_ring;
|
||||
@@ -64,27 +65,29 @@ typedef struct {
|
||||
|
||||
} netmap_if_t;
|
||||
|
||||
typedef struct {
|
||||
char * mem;
|
||||
typedef struct
|
||||
{
|
||||
char *mem;
|
||||
u32 region_size;
|
||||
int refcnt;
|
||||
} netmap_mem_region_t;
|
||||
|
||||
typedef struct {
|
||||
CLIB_CACHE_LINE_ALIGN_MARK(cacheline0);
|
||||
netmap_if_t * interfaces;
|
||||
typedef struct
|
||||
{
|
||||
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
|
||||
netmap_if_t *interfaces;
|
||||
|
||||
/* bitmap of pending rx interfaces */
|
||||
uword * pending_input_bitmap;
|
||||
uword *pending_input_bitmap;
|
||||
|
||||
/* rx buffer cache */
|
||||
u32 ** rx_buffers;
|
||||
u32 **rx_buffers;
|
||||
|
||||
/* hash of host interface names */
|
||||
mhash_t if_index_by_host_if_name;
|
||||
|
||||
/* vector of memory regions */
|
||||
netmap_mem_region_t * mem_regions;
|
||||
netmap_mem_region_t *mem_regions;
|
||||
|
||||
/* first cpu index */
|
||||
u32 input_cpu_first_index;
|
||||
@@ -97,9 +100,9 @@ netmap_main_t netmap_main;
|
||||
extern vnet_device_class_t netmap_device_class;
|
||||
extern vlib_node_registration_t netmap_input_node;
|
||||
|
||||
int netmap_create_if(vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set,
|
||||
u8 is_pipe, u8 is_master, u32 *sw_if_index);
|
||||
int netmap_delete_if(vlib_main_t * vm, u8 * host_if_name);
|
||||
int netmap_create_if (vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set,
|
||||
u8 is_pipe, u8 is_master, u32 * sw_if_index);
|
||||
int netmap_delete_if (vlib_main_t * vm, u8 * host_if_name);
|
||||
|
||||
|
||||
/* Macros and helper functions from sys/net/netmap_user.h */
|
||||
@@ -125,9 +128,9 @@ int netmap_delete_if(vlib_main_t * vm, u8 * host_if_name);
|
||||
(ring)->nr_buf_size )
|
||||
|
||||
static inline uint32_t
|
||||
nm_ring_next(struct netmap_ring *ring, uint32_t i)
|
||||
nm_ring_next (struct netmap_ring *ring, uint32_t i)
|
||||
{
|
||||
return ( PREDICT_FALSE(i + 1 == ring->num_slots) ? 0 : i + 1);
|
||||
return (PREDICT_FALSE (i + 1 == ring->num_slots) ? 0 : i + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -136,18 +139,26 @@ nm_ring_next(struct netmap_ring *ring, uint32_t i)
|
||||
* When everything is complete ring->head = ring->tail + 1 (modulo ring size)
|
||||
*/
|
||||
static inline int
|
||||
nm_tx_pending(struct netmap_ring *ring)
|
||||
nm_tx_pending (struct netmap_ring *ring)
|
||||
{
|
||||
return nm_ring_next(ring, ring->tail) != ring->head;
|
||||
return nm_ring_next (ring, ring->tail) != ring->head;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
nm_ring_space(struct netmap_ring *ring)
|
||||
nm_ring_space (struct netmap_ring *ring)
|
||||
{
|
||||
int ret = ring->tail - ring->cur;
|
||||
if (ret < 0)
|
||||
ret += ring->num_slots;
|
||||
return ret;
|
||||
int ret = ring->tail - ring->cur;
|
||||
if (ret < 0)
|
||||
ret += ring->num_slots;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
+100
-77
File diff suppressed because it is too large
Load Diff
+842
-724
File diff suppressed because it is too large
Load Diff
+281
-229
File diff suppressed because it is too large
Load Diff
+38
-18
@@ -15,11 +15,12 @@
|
||||
|
||||
#include <vnet/devices/nic/sfp.h>
|
||||
|
||||
static u8 * format_space_terminated (u8 * s, va_list * args)
|
||||
static u8 *
|
||||
format_space_terminated (u8 * s, va_list * args)
|
||||
{
|
||||
u32 l = va_arg (*args, u32);
|
||||
u8 * v = va_arg (*args, u8 *);
|
||||
u8 * p;
|
||||
u8 *v = va_arg (*args, u8 *);
|
||||
u8 *p;
|
||||
|
||||
for (p = v + l - 1; p >= v && p[0] == ' '; p--)
|
||||
;
|
||||
@@ -27,10 +28,11 @@ static u8 * format_space_terminated (u8 * s, va_list * args)
|
||||
return s;
|
||||
}
|
||||
|
||||
static u8 * format_sfp_id (u8 * s, va_list * args)
|
||||
static u8 *
|
||||
format_sfp_id (u8 * s, va_list * args)
|
||||
{
|
||||
u32 id = va_arg (*args, u32);
|
||||
char * t = 0;
|
||||
char *t = 0;
|
||||
switch (id)
|
||||
{
|
||||
#define _(f) case SFP_ID_##f: t = #f; break;
|
||||
@@ -42,10 +44,11 @@ static u8 * format_sfp_id (u8 * s, va_list * args)
|
||||
return format (s, "%s", t);
|
||||
}
|
||||
|
||||
static u8 * format_sfp_compatibility (u8 * s, va_list * args)
|
||||
static u8 *
|
||||
format_sfp_compatibility (u8 * s, va_list * args)
|
||||
{
|
||||
u32 c = va_arg (*args, u32);
|
||||
char * t = 0;
|
||||
char *t = 0;
|
||||
switch (c)
|
||||
{
|
||||
#define _(a,b,f) case SFP_COMPATIBILITY_##f: t = #f; break;
|
||||
@@ -57,9 +60,14 @@ static u8 * format_sfp_compatibility (u8 * s, va_list * args)
|
||||
return format (s, "%s", t);
|
||||
}
|
||||
|
||||
u32 sfp_is_comatible (sfp_eeprom_t * e, sfp_compatibility_t c)
|
||||
u32
|
||||
sfp_is_comatible (sfp_eeprom_t * e, sfp_compatibility_t c)
|
||||
{
|
||||
static struct { u8 byte, bit; } t[] = {
|
||||
static struct
|
||||
{
|
||||
u8 byte, bit;
|
||||
} t[] =
|
||||
{
|
||||
#define _(a,b,f) { .byte = a, .bit = b, },
|
||||
foreach_sfp_compatibility
|
||||
#undef _
|
||||
@@ -69,9 +77,10 @@ u32 sfp_is_comatible (sfp_eeprom_t * e, sfp_compatibility_t c)
|
||||
return (e->compatibility[t[c].byte] & (1 << t[c].bit)) != 0;
|
||||
}
|
||||
|
||||
u8 * format_sfp_eeprom (u8 * s, va_list * args)
|
||||
u8 *
|
||||
format_sfp_eeprom (u8 * s, va_list * args)
|
||||
{
|
||||
sfp_eeprom_t * e = va_arg (*args, sfp_eeprom_t *);
|
||||
sfp_eeprom_t *e = va_arg (*args, sfp_eeprom_t *);
|
||||
uword indent = format_get_indent (s);
|
||||
int i;
|
||||
|
||||
@@ -85,13 +94,24 @@ u8 * format_sfp_eeprom (u8 * s, va_list * args)
|
||||
|
||||
s = format (s, "\n%Uvendor: %U, part %U",
|
||||
format_white_space, indent,
|
||||
format_space_terminated, sizeof (e->vendor_name), e->vendor_name,
|
||||
format_space_terminated, sizeof (e->vendor_part_number), e->vendor_part_number);
|
||||
s = format (s, "\n%Urevision: %U, serial: %U, date code: %U",
|
||||
format_white_space, indent,
|
||||
format_space_terminated, sizeof (e->vendor_revision), e->vendor_revision,
|
||||
format_space_terminated, sizeof (e->vendor_serial_number), e->vendor_serial_number,
|
||||
format_space_terminated, sizeof (e->vendor_date_code), e->vendor_date_code);
|
||||
format_space_terminated, sizeof (e->vendor_name),
|
||||
e->vendor_name, format_space_terminated,
|
||||
sizeof (e->vendor_part_number), e->vendor_part_number);
|
||||
s =
|
||||
format (s, "\n%Urevision: %U, serial: %U, date code: %U",
|
||||
format_white_space, indent, format_space_terminated,
|
||||
sizeof (e->vendor_revision), e->vendor_revision,
|
||||
format_space_terminated, sizeof (e->vendor_serial_number),
|
||||
e->vendor_serial_number, format_space_terminated,
|
||||
sizeof (e->vendor_date_code), e->vendor_date_code);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
@@ -24,13 +24,15 @@
|
||||
_ (on_motherboard) \
|
||||
_ (sfp)
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
#define _(f) SFP_ID_##f,
|
||||
foreach_sfp_id
|
||||
#undef _
|
||||
} sfp_id_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
u8 id;
|
||||
u8 extended_id;
|
||||
u8 connector_type;
|
||||
@@ -92,11 +94,12 @@ sfp_eeprom_is_valid (sfp_eeprom_t * e)
|
||||
_ (3, 1, 1g_base_lx) \
|
||||
_ (3, 0, 1g_base_sx)
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
#define _(a,b,f) SFP_COMPATIBILITY_##f,
|
||||
foreach_sfp_compatibility
|
||||
#undef _
|
||||
SFP_N_COMPATIBILITY,
|
||||
SFP_N_COMPATIBILITY,
|
||||
} sfp_compatibility_t;
|
||||
|
||||
u32 sfp_is_comatible (sfp_eeprom_t * e, sfp_compatibility_t c);
|
||||
@@ -104,3 +107,11 @@ u32 sfp_is_comatible (sfp_eeprom_t * e, sfp_compatibility_t c);
|
||||
format_function_t format_sfp_eeprom;
|
||||
|
||||
#endif /* included_vnet_optics_sfp_h */
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
+153
-143
File diff suppressed because it is too large
Load Diff
+180
-167
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,8 @@ extern vlib_node_registration_t ssvm_eth_input_node;
|
||||
(VLIB_BUFFER_DATA_SIZE + VLIB_BUFFER_PRE_DATA_SIZE)
|
||||
#define SSVM_PACKET_TYPE 1
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
/* Type of queue element */
|
||||
u8 type;
|
||||
u8 flags;
|
||||
@@ -51,17 +52,18 @@ typedef struct {
|
||||
u16 pad;
|
||||
u32 next_index;
|
||||
/* offset 16 */
|
||||
u8 data [SSVM_BUFFER_SIZE];
|
||||
u8 data[SSVM_BUFFER_SIZE];
|
||||
/* pad to an even multiple of 64 octets */
|
||||
u8 pad2[CLIB_CACHE_LINE_BYTES - 16];
|
||||
} ssvm_eth_queue_elt_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
/* vector of point-to-point connections */
|
||||
ssvm_private_t * intfcs;
|
||||
ssvm_private_t *intfcs;
|
||||
|
||||
u32 * buffer_cache;
|
||||
u32 * chunk_cache;
|
||||
u32 *buffer_cache;
|
||||
u32 *chunk_cache;
|
||||
|
||||
/* Configurable parameters */
|
||||
/* base address for next placement */
|
||||
@@ -71,19 +73,20 @@ typedef struct {
|
||||
u64 queue_elts;
|
||||
|
||||
/* Segment names */
|
||||
u8 ** names;
|
||||
u8 **names;
|
||||
|
||||
/* convenience */
|
||||
vlib_main_t * vlib_main;
|
||||
vnet_main_t * vnet_main;
|
||||
elog_main_t * elog_main;
|
||||
vlib_main_t *vlib_main;
|
||||
vnet_main_t *vnet_main;
|
||||
elog_main_t *elog_main;
|
||||
} ssvm_eth_main_t;
|
||||
|
||||
ssvm_eth_main_t ssvm_eth_main;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
CHUNK_POOL_FREELIST_INDEX = 0,
|
||||
CHUNK_POOL_INDEX,
|
||||
CHUNK_POOL_INDEX,
|
||||
CHUNK_POOL_NFREE,
|
||||
TO_MASTER_Q_INDEX,
|
||||
TO_SLAVE_Q_INDEX,
|
||||
@@ -94,13 +97,14 @@ typedef enum {
|
||||
/*
|
||||
* debug scaffolding.
|
||||
*/
|
||||
static inline void ssvm_eth_validate_freelists (int need_lock)
|
||||
static inline void
|
||||
ssvm_eth_validate_freelists (int need_lock)
|
||||
{
|
||||
#if CLIB_DEBUG > 0
|
||||
ssvm_eth_main_t * em = &ssvm_eth_main;
|
||||
ssvm_private_t * intfc;
|
||||
ssvm_shared_header_t * sh;
|
||||
u32 * elt_indices;
|
||||
ssvm_eth_main_t *em = &ssvm_eth_main;
|
||||
ssvm_private_t *intfc;
|
||||
ssvm_shared_header_t *sh;
|
||||
u32 *elt_indices;
|
||||
u32 n_available;
|
||||
int i;
|
||||
|
||||
@@ -109,20 +113,28 @@ static inline void ssvm_eth_validate_freelists (int need_lock)
|
||||
intfc = em->intfcs + i;
|
||||
sh = intfc->sh;
|
||||
u32 my_pid = intfc->my_pid;
|
||||
|
||||
if (need_lock)
|
||||
ssvm_lock (sh, my_pid, 15);
|
||||
|
||||
elt_indices = (u32 *) (sh->opaque [CHUNK_POOL_FREELIST_INDEX]);
|
||||
n_available = (u32) (uword) (sh->opaque [CHUNK_POOL_NFREE]);
|
||||
if (need_lock)
|
||||
ssvm_lock (sh, my_pid, 15);
|
||||
|
||||
elt_indices = (u32 *) (sh->opaque[CHUNK_POOL_FREELIST_INDEX]);
|
||||
n_available = (u32) (uword) (sh->opaque[CHUNK_POOL_NFREE]);
|
||||
|
||||
for (i = 0; i < n_available; i++)
|
||||
ASSERT (elt_indices[i] < 2048);
|
||||
|
||||
if (need_lock)
|
||||
ssvm_unlock (sh);
|
||||
ssvm_unlock (sh);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* __included_ssvm_eth_h__ */
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
+1280
-1045
File diff suppressed because it is too large
Load Diff
@@ -52,50 +52,58 @@
|
||||
_ (VHOST_USER_F_PROTOCOL_FEATURES, 30)
|
||||
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
#define _(f,n) FEAT_##f = (n),
|
||||
foreach_virtio_net_feature
|
||||
#undef _
|
||||
} virtio_net_feature_t;
|
||||
|
||||
int vhost_user_create_if(vnet_main_t * vnm, vlib_main_t * vm,
|
||||
const char * sock_filename, u8 is_server,
|
||||
u32 * sw_if_index, u64 feature_mask,
|
||||
u8 renumber, u32 custom_dev_instance, u8 *hwaddr);
|
||||
int vhost_user_modify_if(vnet_main_t * vnm, vlib_main_t * vm,
|
||||
const char * sock_filename, u8 is_server,
|
||||
u32 sw_if_index, u64 feature_mask,
|
||||
u8 renumber, u32 custom_dev_instance);
|
||||
int vhost_user_delete_if(vnet_main_t * vnm, vlib_main_t * vm, u32 sw_if_index);
|
||||
int vhost_user_create_if (vnet_main_t * vnm, vlib_main_t * vm,
|
||||
const char *sock_filename, u8 is_server,
|
||||
u32 * sw_if_index, u64 feature_mask,
|
||||
u8 renumber, u32 custom_dev_instance, u8 * hwaddr);
|
||||
int vhost_user_modify_if (vnet_main_t * vnm, vlib_main_t * vm,
|
||||
const char *sock_filename, u8 is_server,
|
||||
u32 sw_if_index, u64 feature_mask,
|
||||
u8 renumber, u32 custom_dev_instance);
|
||||
int vhost_user_delete_if (vnet_main_t * vnm, vlib_main_t * vm,
|
||||
u32 sw_if_index);
|
||||
|
||||
typedef struct vhost_user_memory_region {
|
||||
typedef struct vhost_user_memory_region
|
||||
{
|
||||
u64 guest_phys_addr;
|
||||
u64 memory_size;
|
||||
u64 userspace_addr;
|
||||
u64 mmap_offset;
|
||||
} vhost_user_memory_region_t;
|
||||
|
||||
typedef struct vhost_user_memory {
|
||||
typedef struct vhost_user_memory
|
||||
{
|
||||
u32 nregions;
|
||||
u32 padding;
|
||||
vhost_user_memory_region_t regions[VHOST_MEMORY_MAX_NREGIONS];
|
||||
} vhost_user_memory_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
unsigned int index, num;
|
||||
} vhost_vring_state_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
unsigned int index, flags;
|
||||
u64 desc_user_addr, used_user_addr, avail_user_addr, log_guest_addr;
|
||||
} vhost_vring_addr_t;
|
||||
|
||||
typedef struct vhost_user_log {
|
||||
typedef struct vhost_user_log
|
||||
{
|
||||
u64 size;
|
||||
u64 offset;
|
||||
} vhost_user_log_t;
|
||||
|
||||
typedef enum vhost_user_req {
|
||||
typedef enum vhost_user_req
|
||||
{
|
||||
VHOST_USER_NONE = 0,
|
||||
VHOST_USER_GET_FEATURES = 1,
|
||||
VHOST_USER_SET_FEATURES = 2,
|
||||
@@ -119,29 +127,35 @@ typedef enum vhost_user_req {
|
||||
} vhost_user_req_t;
|
||||
|
||||
// vring_desc I/O buffer descriptor
|
||||
typedef struct {
|
||||
/* *INDENT-OFF* */
|
||||
typedef struct
|
||||
{
|
||||
uint64_t addr; // packet data buffer address
|
||||
uint32_t len; // packet data buffer size
|
||||
uint16_t flags; // (see below)
|
||||
uint16_t next; // optional index next descriptor in chain
|
||||
} __attribute ((packed)) vring_desc_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
uint16_t flags;
|
||||
uint16_t idx;
|
||||
uint16_t ring[VHOST_VRING_MAX_SIZE];
|
||||
} __attribute ((packed)) vring_avail_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
uint16_t flags;
|
||||
uint16_t idx;
|
||||
struct /* vring_used_elem */ {
|
||||
uint32_t id;
|
||||
uint32_t len;
|
||||
} ring[VHOST_VRING_MAX_SIZE];
|
||||
struct /* vring_used_elem */
|
||||
{
|
||||
uint32_t id;
|
||||
uint32_t len;
|
||||
} ring[VHOST_VRING_MAX_SIZE];
|
||||
} __attribute ((packed)) vring_used_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
u8 flags;
|
||||
u8 gso_type;
|
||||
u16 hdr_len;
|
||||
@@ -156,19 +170,22 @@ typedef struct {
|
||||
} __attribute ((packed)) virtio_net_hdr_mrg_rxbuf_t;
|
||||
|
||||
typedef struct vhost_user_msg {
|
||||
vhost_user_req_t request;
|
||||
u32 flags;
|
||||
u32 size;
|
||||
union {
|
||||
u64 u64;
|
||||
vhost_vring_state_t state;
|
||||
vhost_vring_addr_t addr;
|
||||
vhost_user_memory_t memory;
|
||||
vhost_user_log_t log;
|
||||
vhost_user_req_t request;
|
||||
u32 flags;
|
||||
u32 size;
|
||||
union
|
||||
{
|
||||
u64 u64;
|
||||
vhost_vring_state_t state;
|
||||
vhost_vring_addr_t addr;
|
||||
vhost_user_memory_t memory;
|
||||
vhost_user_log_t log;
|
||||
};
|
||||
} __attribute ((packed)) vhost_user_msg_t;
|
||||
/* *INDENT-ON* */
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
u32 qsz;
|
||||
u16 last_avail_idx;
|
||||
u16 last_used_idx;
|
||||
@@ -186,9 +203,10 @@ typedef struct {
|
||||
f64 int_deadline;
|
||||
} vhost_user_vring_t;
|
||||
|
||||
typedef struct {
|
||||
CLIB_CACHE_LINE_ALIGN_MARK(cacheline0);
|
||||
volatile u32 * lockp;
|
||||
typedef struct
|
||||
{
|
||||
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
|
||||
volatile u32 *lockp;
|
||||
u32 is_up;
|
||||
u32 admin_up;
|
||||
u32 unix_fd;
|
||||
@@ -199,64 +217,71 @@ typedef struct {
|
||||
u8 sock_is_server;
|
||||
u32 hw_if_index, sw_if_index;
|
||||
u8 active;
|
||||
|
||||
|
||||
u32 nregions;
|
||||
u64 features;
|
||||
u64 feature_mask;
|
||||
u64 protocol_features;
|
||||
u32 num_vrings;
|
||||
vhost_user_memory_region_t regions[VHOST_MEMORY_MAX_NREGIONS];
|
||||
void * region_mmap_addr[VHOST_MEMORY_MAX_NREGIONS];
|
||||
void *region_mmap_addr[VHOST_MEMORY_MAX_NREGIONS];
|
||||
u32 region_mmap_fd[VHOST_MEMORY_MAX_NREGIONS];
|
||||
vhost_user_vring_t vrings[2];
|
||||
int virtio_net_hdr_sz;
|
||||
int is_any_layout;
|
||||
u32 * d_trace_buffers;
|
||||
u32 *d_trace_buffers;
|
||||
|
||||
void * log_base_addr;
|
||||
void *log_base_addr;
|
||||
u64 log_size;
|
||||
} vhost_user_intf_t;
|
||||
|
||||
typedef struct {
|
||||
u32 ** rx_buffers;
|
||||
typedef struct
|
||||
{
|
||||
u32 **rx_buffers;
|
||||
u32 mtu_bytes;
|
||||
vhost_user_intf_t * vhost_user_interfaces;
|
||||
u32 * vhost_user_inactive_interfaces_index;
|
||||
uword * vhost_user_interface_index_by_listener_fd;
|
||||
uword * vhost_user_interface_index_by_sock_fd;
|
||||
uword * vhost_user_interface_index_by_sw_if_index;
|
||||
u32 * show_dev_instance_by_real_dev_instance;
|
||||
vhost_user_intf_t *vhost_user_interfaces;
|
||||
u32 *vhost_user_inactive_interfaces_index;
|
||||
uword *vhost_user_interface_index_by_listener_fd;
|
||||
uword *vhost_user_interface_index_by_sock_fd;
|
||||
uword *vhost_user_interface_index_by_sw_if_index;
|
||||
u32 *show_dev_instance_by_real_dev_instance;
|
||||
u32 coalesce_frames;
|
||||
f64 coalesce_time;
|
||||
int dont_dump_vhost_user_memory;
|
||||
} vhost_user_main_t;
|
||||
|
||||
typedef struct {
|
||||
u8 if_name[64];
|
||||
u32 sw_if_index;
|
||||
u32 virtio_net_hdr_sz;
|
||||
u64 features;
|
||||
u8 is_server;
|
||||
u8 sock_filename[256];
|
||||
u32 num_regions;
|
||||
int sock_errno;
|
||||
typedef struct
|
||||
{
|
||||
u8 if_name[64];
|
||||
u32 sw_if_index;
|
||||
u32 virtio_net_hdr_sz;
|
||||
u64 features;
|
||||
u8 is_server;
|
||||
u8 sock_filename[256];
|
||||
u32 num_regions;
|
||||
int sock_errno;
|
||||
} vhost_user_intf_details_t;
|
||||
|
||||
int vhost_user_dump_ifs(vnet_main_t * vnm, vlib_main_t * vm,
|
||||
vhost_user_intf_details_t **out_vuids);
|
||||
int vhost_user_dump_ifs (vnet_main_t * vnm, vlib_main_t * vm,
|
||||
vhost_user_intf_details_t ** out_vuids);
|
||||
|
||||
// CLI commands to be used from dpdk
|
||||
clib_error_t *
|
||||
vhost_user_connect_command_fn (vlib_main_t * vm,
|
||||
unformat_input_t * input,
|
||||
vlib_cli_command_t * cmd);
|
||||
clib_error_t *
|
||||
vhost_user_delete_command_fn (vlib_main_t * vm,
|
||||
unformat_input_t * input,
|
||||
vlib_cli_command_t * cmd);
|
||||
clib_error_t *
|
||||
show_vhost_user_command_fn (vlib_main_t * vm,
|
||||
unformat_input_t * input,
|
||||
vlib_cli_command_t * cmd);
|
||||
clib_error_t *vhost_user_connect_command_fn (vlib_main_t * vm,
|
||||
unformat_input_t * input,
|
||||
vlib_cli_command_t * cmd);
|
||||
clib_error_t *vhost_user_delete_command_fn (vlib_main_t * vm,
|
||||
unformat_input_t * input,
|
||||
vlib_cli_command_t * cmd);
|
||||
clib_error_t *show_vhost_user_command_fn (vlib_main_t * vm,
|
||||
unformat_input_t * input,
|
||||
vlib_cli_command_t * cmd);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user