summaryrefslogtreecommitdiffstats
path: root/src/vnet/devices/af_packet/af_packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/devices/af_packet/af_packet.c')
-rw-r--r--src/vnet/devices/af_packet/af_packet.c131
1 files changed, 81 insertions, 50 deletions
diff --git a/src/vnet/devices/af_packet/af_packet.c b/src/vnet/devices/af_packet/af_packet.c
index ec65bf6d493..010bc1c266c 100644
--- a/src/vnet/devices/af_packet/af_packet.c
+++ b/src/vnet/devices/af_packet/af_packet.c
@@ -48,6 +48,10 @@ VNET_HW_INTERFACE_CLASS (af_packet_ip_device_hw_interface_class, static) = {
#define AF_PACKET_DEFAULT_TX_FRAME_SIZE (2048 * 33) // GSO packet of 64KB
#define AF_PACKET_TX_BLOCK_NR 1
+#define AF_PACKET_DEFAULT_RX_FRAMES_PER_BLOCK_V2 1024
+#define AF_PACKET_DEFAULT_RX_FRAME_SIZE_V2 (2048 * 33) // GSO packet of 64KB
+#define AF_PACKET_RX_BLOCK_NR_V2 1
+
#define AF_PACKET_DEFAULT_RX_FRAMES_PER_BLOCK 32
#define AF_PACKET_DEFAULT_RX_FRAME_SIZE 2048
#define AF_PACKET_RX_BLOCK_NR 160
@@ -189,23 +193,16 @@ af_packet_set_tx_queues (vlib_main_t *vm, af_packet_if_t *apif)
}
static int
-create_packet_v3_sock (int host_if_index, tpacket_req3_t *rx_req,
- tpacket_req3_t *tx_req, int *fd, af_packet_ring_t *ring,
- u32 fanout_id, af_packet_if_flags_t *flags)
+create_packet_sock (int host_if_index, tpacket_req_u_t *rx_req,
+ tpacket_req_u_t *tx_req, int *fd, af_packet_ring_t *ring,
+ u32 fanout_id, af_packet_if_flags_t *flags, int ver)
{
af_packet_main_t *apm = &af_packet_main;
struct sockaddr_ll sll;
socklen_t req_sz = sizeof (tpacket_req3_t);
int ret;
- int ver = TPACKET_V3;
u32 ring_sz = 0;
- if (rx_req)
- ring_sz += rx_req->tp_block_size * rx_req->tp_block_nr;
-
- if (tx_req)
- ring_sz += tx_req->tp_block_size * tx_req->tp_block_nr;
-
if ((*fd = socket (AF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0)
{
vlib_log_err (apm->log_class,
@@ -297,7 +294,13 @@ create_packet_v3_sock (int host_if_index, tpacket_req3_t *rx_req,
goto error;
}
}
-
+ if (ver == TPACKET_V2)
+ {
+ req_sz = sizeof (tpacket_req_t);
+ ring_sz += rx_req->req.tp_block_size * rx_req->req.tp_block_nr;
+ }
+ else
+ ring_sz += rx_req->req3.tp_block_size * rx_req->req3.tp_block_nr;
if (setsockopt (*fd, SOL_PACKET, PACKET_RX_RING, rx_req, req_sz) < 0)
{
vlib_log_err (apm->log_class,
@@ -309,15 +312,23 @@ create_packet_v3_sock (int host_if_index, tpacket_req3_t *rx_req,
}
if (tx_req)
- if (setsockopt (*fd, SOL_PACKET, PACKET_TX_RING, tx_req, req_sz) < 0)
- {
- vlib_log_err (apm->log_class,
- "Failed to set packet tx ring options: %s (errno %d)",
- strerror (errno), errno);
- ret = VNET_API_ERROR_SYSCALL_ERROR_1;
- goto error;
- }
-
+ {
+ if (ver == TPACKET_V2)
+ {
+ req_sz = sizeof (tpacket_req_t);
+ ring_sz += tx_req->req.tp_block_size * tx_req->req.tp_block_nr;
+ }
+ else
+ ring_sz += tx_req->req3.tp_block_size * tx_req->req3.tp_block_nr;
+ if (setsockopt (*fd, SOL_PACKET, PACKET_TX_RING, tx_req, req_sz) < 0)
+ {
+ vlib_log_err (apm->log_class,
+ "Failed to set packet tx ring options: %s (errno %d)",
+ strerror (errno), errno);
+ ret = VNET_API_ERROR_SYSCALL_ERROR_1;
+ goto error;
+ }
+ }
ring->ring_start_addr = mmap (NULL, ring_sz, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_LOCKED, *fd, 0);
if (ring->ring_start_addr == MAP_FAILED)
@@ -347,8 +358,8 @@ af_packet_queue_init (vlib_main_t *vm, af_packet_if_t *apif,
u8 queue_id)
{
af_packet_main_t *apm = &af_packet_main;
- tpacket_req3_t *rx_req = 0;
- tpacket_req3_t *tx_req = 0;
+ tpacket_req_u_t *rx_req = 0;
+ tpacket_req_u_t *tx_req = 0;
int ret, fd = -1;
af_packet_ring_t ring = { 0 };
u8 *ring_addr = 0;
@@ -360,22 +371,32 @@ af_packet_queue_init (vlib_main_t *vm, af_packet_if_t *apif,
{
rx_frames_per_block = arg->rx_frames_per_block ?
arg->rx_frames_per_block :
- AF_PACKET_DEFAULT_RX_FRAMES_PER_BLOCK;
-
- rx_frame_size = arg->rx_frame_size ? arg->rx_frame_size :
- AF_PACKET_DEFAULT_RX_FRAME_SIZE;
+ ((apif->version == TPACKET_V3) ?
+ AF_PACKET_DEFAULT_RX_FRAMES_PER_BLOCK :
+ AF_PACKET_DEFAULT_RX_FRAMES_PER_BLOCK_V2);
+
+ rx_frame_size =
+ arg->rx_frame_size ?
+ arg->rx_frame_size :
+ ((apif->version == TPACKET_V3) ? AF_PACKET_DEFAULT_RX_FRAME_SIZE :
+ AF_PACKET_DEFAULT_RX_FRAME_SIZE_V2);
vec_validate (rx_queue->rx_req, 0);
- rx_queue->rx_req->tp_block_size = rx_frame_size * rx_frames_per_block;
- rx_queue->rx_req->tp_frame_size = rx_frame_size;
- rx_queue->rx_req->tp_block_nr = AF_PACKET_RX_BLOCK_NR;
- rx_queue->rx_req->tp_frame_nr =
- AF_PACKET_RX_BLOCK_NR * rx_frames_per_block;
- rx_queue->rx_req->tp_retire_blk_tov = 1; // 1 ms block timout
- rx_queue->rx_req->tp_feature_req_word = 0;
- rx_queue->rx_req->tp_sizeof_priv = 0;
+ rx_queue->rx_req->req.tp_block_size =
+ rx_frame_size * rx_frames_per_block;
+ rx_queue->rx_req->req.tp_frame_size = rx_frame_size;
+ rx_queue->rx_req->req.tp_block_nr = (apif->version == TPACKET_V3) ?
+ AF_PACKET_RX_BLOCK_NR :
+ AF_PACKET_RX_BLOCK_NR_V2;
+ rx_queue->rx_req->req.tp_frame_nr =
+ rx_queue->rx_req->req.tp_block_nr * rx_frames_per_block;
+ if (apif->version == TPACKET_V3)
+ {
+ rx_queue->rx_req->req3.tp_retire_blk_tov = 1; // 1 ms block timout
+ rx_queue->rx_req->req3.tp_feature_req_word = 0;
+ rx_queue->rx_req->req3.tp_sizeof_priv = 0;
+ }
rx_req = rx_queue->rx_req;
}
-
if (tx_queue)
{
tx_frames_per_block = arg->tx_frames_per_block ?
@@ -385,21 +406,26 @@ af_packet_queue_init (vlib_main_t *vm, af_packet_if_t *apif,
AF_PACKET_DEFAULT_TX_FRAME_SIZE;
vec_validate (tx_queue->tx_req, 0);
- tx_queue->tx_req->tp_block_size = tx_frame_size * tx_frames_per_block;
- tx_queue->tx_req->tp_frame_size = tx_frame_size;
- tx_queue->tx_req->tp_block_nr = AF_PACKET_TX_BLOCK_NR;
- tx_queue->tx_req->tp_frame_nr =
+ tx_queue->tx_req->req.tp_block_size =
+ tx_frame_size * tx_frames_per_block;
+ tx_queue->tx_req->req.tp_frame_size = tx_frame_size;
+ tx_queue->tx_req->req.tp_block_nr = AF_PACKET_TX_BLOCK_NR;
+ tx_queue->tx_req->req.tp_frame_nr =
AF_PACKET_TX_BLOCK_NR * tx_frames_per_block;
- tx_queue->tx_req->tp_retire_blk_tov = 0;
- tx_queue->tx_req->tp_sizeof_priv = 0;
- tx_queue->tx_req->tp_feature_req_word = 0;
+ if (apif->version == TPACKET_V3)
+ {
+ tx_queue->tx_req->req3.tp_retire_blk_tov = 0;
+ tx_queue->tx_req->req3.tp_sizeof_priv = 0;
+ tx_queue->tx_req->req3.tp_feature_req_word = 0;
+ }
tx_req = tx_queue->tx_req;
}
if (rx_queue || tx_queue)
{
- ret = create_packet_v3_sock (apif->host_if_index, rx_req, tx_req, &fd,
- &ring, apif->dev_instance, &arg->flags);
+ ret =
+ create_packet_sock (apif->host_if_index, rx_req, tx_req, &fd, &ring,
+ apif->dev_instance, &arg->flags, apif->version);
if (ret != 0)
goto error;
@@ -411,28 +437,28 @@ af_packet_queue_init (vlib_main_t *vm, af_packet_if_t *apif,
if (rx_queue)
{
rx_queue->fd = fd;
- vec_validate (rx_queue->rx_ring, rx_queue->rx_req->tp_block_nr - 1);
+ vec_validate (rx_queue->rx_ring, rx_queue->rx_req->req.tp_block_nr - 1);
vec_foreach_index (i, rx_queue->rx_ring)
{
rx_queue->rx_ring[i] =
- ring_addr + i * rx_queue->rx_req->tp_block_size;
+ ring_addr + i * rx_queue->rx_req->req.tp_block_size;
}
rx_queue->next_rx_block = 0;
rx_queue->queue_id = queue_id;
rx_queue->is_rx_pending = 0;
- ring_addr = ring_addr + rx_queue->rx_req->tp_block_size *
- rx_queue->rx_req->tp_block_nr;
+ ring_addr = ring_addr + rx_queue->rx_req->req.tp_block_size *
+ rx_queue->rx_req->req.tp_block_nr;
}
if (tx_queue)
{
tx_queue->fd = fd;
- vec_validate (tx_queue->tx_ring, tx_queue->tx_req->tp_block_nr - 1);
+ vec_validate (tx_queue->tx_ring, tx_queue->tx_req->req.tp_block_nr - 1);
vec_foreach_index (i, tx_queue->tx_ring)
{
tx_queue->tx_ring[i] =
- ring_addr + i * tx_queue->tx_req->tp_block_size;
+ ring_addr + i * tx_queue->tx_req->req.tp_block_size;
}
tx_queue->next_tx_frame = 0;
@@ -604,6 +630,11 @@ af_packet_create_if (af_packet_create_if_arg_t *arg)
apif->per_interface_next_index = ~0;
apif->mode = arg->mode;
+ if (arg->is_v2)
+ apif->version = TPACKET_V2;
+ else
+ apif->version = TPACKET_V3;
+
ret = af_packet_device_init (vm, apif, arg);
if (ret != 0)
goto error;