diff options
-rw-r--r-- | src/vnet/devices/af_packet/af_packet.c | 36 | ||||
-rw-r--r-- | src/vnet/devices/af_packet/af_packet.h | 1 | ||||
-rw-r--r-- | src/vnet/devices/af_packet/af_packet_api.c | 4 | ||||
-rw-r--r-- | src/vnet/devices/af_packet/cli.c | 6 | ||||
-rw-r--r-- | src/vnet/devices/af_packet/device.c | 2 |
5 files changed, 29 insertions, 20 deletions
diff --git a/src/vnet/devices/af_packet/af_packet.c b/src/vnet/devices/af_packet/af_packet.c index a8ab944a513..fd2f6fc9a57 100644 --- a/src/vnet/devices/af_packet/af_packet.c +++ b/src/vnet/devices/af_packet/af_packet.c @@ -191,7 +191,7 @@ 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, - u8 *is_cksum_gso_enabled, u32 fanout_id, u8 is_fanout, + u32 fanout_id, u8 is_fanout, af_packet_if_flags_t *flags) { af_packet_main_t *apm = &af_packet_main; @@ -250,16 +250,21 @@ create_packet_v3_sock (int host_if_index, tpacket_req3_t *rx_req, goto error; } - int opt2 = 1; - if (setsockopt (*fd, SOL_PACKET, PACKET_VNET_HDR, &opt2, sizeof (opt2)) < 0) + if (*flags & AF_PACKET_IF_FLAGS_CKSUM_GSO) { - vlib_log_debug ( - apm->log_class, - "Failed to set packet vnet hdr error handling option: %s (errno %d)", - strerror (errno), errno); + + int opt2 = 1; + if (setsockopt (*fd, SOL_PACKET, PACKET_VNET_HDR, &opt2, sizeof (opt2)) < + 0) + { + // remove the flag + *flags &= ~AF_PACKET_IF_FLAGS_CKSUM_GSO; + vlib_log_debug (apm->log_class, + "Failed to set packet vnet hdr error handling " + "option: %s (errno %d)", + strerror (errno), errno); + } } - else - *is_cksum_gso_enabled = 1; #if defined(PACKET_QDISC_BYPASS) if (*flags & AF_PACKET_IF_FLAGS_QDISC_BYPASS) @@ -347,7 +352,6 @@ af_packet_queue_init (vlib_main_t *vm, af_packet_if_t *apif, u32 rx_frames_per_block, tx_frames_per_block; u32 rx_frame_size, tx_frame_size; u32 i = 0; - u8 is_cksum_gso_enabled = 0; if (rx_queue) { @@ -391,9 +395,9 @@ af_packet_queue_init (vlib_main_t *vm, af_packet_if_t *apif, if (rx_queue || tx_queue) { - ret = create_packet_v3_sock (apif->host_if_index, rx_req, tx_req, &fd, - &ring, &is_cksum_gso_enabled, - apif->dev_instance, is_fanout, &arg->flags); + ret = + create_packet_v3_sock (apif->host_if_index, rx_req, tx_req, &fd, &ring, + apif->dev_instance, is_fanout, &arg->flags); if (ret != 0) goto error; @@ -434,9 +438,6 @@ af_packet_queue_init (vlib_main_t *vm, af_packet_if_t *apif, clib_spinlock_init (&tx_queue->lockp); } - if (queue_id == 0) - apif->is_cksum_gso_enabled = is_cksum_gso_enabled; - return 0; error: vlib_log_err (apm->log_class, "Failed to set queue %u error", queue_id); @@ -648,6 +649,9 @@ af_packet_create_if (af_packet_create_if_arg_t *arg) apif->is_qdisc_bypass_enabled = (arg->flags & AF_PACKET_IF_FLAGS_QDISC_BYPASS); + if (arg->flags & AF_PACKET_IF_FLAGS_CKSUM_GSO) + apif->is_cksum_gso_enabled = 1; + if (apif->is_cksum_gso_enabled) caps |= VNET_HW_IF_CAP_TCP_GSO | VNET_HW_IF_CAP_TX_IP4_CKSUM | VNET_HW_IF_CAP_TX_TCP_CKSUM | VNET_HW_IF_CAP_TX_UDP_CKSUM; diff --git a/src/vnet/devices/af_packet/af_packet.h b/src/vnet/devices/af_packet/af_packet.h index 2b051251455..64daaa197eb 100644 --- a/src/vnet/devices/af_packet/af_packet.h +++ b/src/vnet/devices/af_packet/af_packet.h @@ -35,6 +35,7 @@ typedef enum typedef enum { AF_PACKET_IF_FLAGS_QDISC_BYPASS = 1, + AF_PACKET_IF_FLAGS_CKSUM_GSO = 2, } af_packet_if_flags_t; typedef struct diff --git a/src/vnet/devices/af_packet/af_packet_api.c b/src/vnet/devices/af_packet/af_packet_api.c index 2a58ba7438a..d991a2e6852 100644 --- a/src/vnet/devices/af_packet/af_packet_api.c +++ b/src/vnet/devices/af_packet/af_packet_api.c @@ -48,7 +48,7 @@ vl_api_af_packet_create_t_handler (vl_api_af_packet_create_t * mp) arg->hw_addr = mp->use_random_hw_addr ? 0 : mp->hw_addr; arg->mode = AF_PACKET_IF_MODE_ETHERNET; // Default flags - arg->flags = AF_PACKET_IF_FLAGS_QDISC_BYPASS; + arg->flags = AF_PACKET_IF_FLAGS_QDISC_BYPASS | AF_PACKET_IF_FLAGS_CKSUM_GSO; rv = af_packet_create_if (arg); vec_free (arg->host_if_name); @@ -80,7 +80,7 @@ vl_api_af_packet_create_v2_t_handler (vl_api_af_packet_create_v2_t *mp) arg->hw_addr = mp->use_random_hw_addr ? 0 : mp->hw_addr; arg->mode = AF_PACKET_IF_MODE_ETHERNET; // Default flags - arg->flags = AF_PACKET_IF_FLAGS_QDISC_BYPASS; + arg->flags = AF_PACKET_IF_FLAGS_QDISC_BYPASS | AF_PACKET_IF_FLAGS_CKSUM_GSO; if (mp->num_rx_queues > 1) arg->num_rxqs = clib_net_to_host_u16 (mp->num_rx_queues); diff --git a/src/vnet/devices/af_packet/cli.c b/src/vnet/devices/af_packet/cli.c index 443a1d5c737..e730659bfcd 100644 --- a/src/vnet/devices/af_packet/cli.c +++ b/src/vnet/devices/af_packet/cli.c @@ -59,7 +59,7 @@ af_packet_create_command_fn (vlib_main_t * vm, unformat_input_t * input, arg->num_txqs = 1; // Default flags - arg->flags = AF_PACKET_IF_FLAGS_QDISC_BYPASS; + arg->flags = AF_PACKET_IF_FLAGS_QDISC_BYPASS | AF_PACKET_IF_FLAGS_CKSUM_GSO; /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) @@ -85,6 +85,8 @@ af_packet_create_command_fn (vlib_main_t * vm, unformat_input_t * input, ; else if (unformat (line_input, "qdisc-bypass-disable")) arg->flags &= ~AF_PACKET_IF_FLAGS_QDISC_BYPASS; + else if (unformat (line_input, "cksum-gso-disable")) + arg->flags &= ~AF_PACKET_IF_FLAGS_CKSUM_GSO; else if (unformat (line_input, "mode ip")) arg->mode = AF_PACKET_IF_MODE_IP; else if (unformat (line_input, "hw-addr %U", unformat_ethernet_address, @@ -160,7 +162,7 @@ VLIB_CLI_COMMAND (af_packet_create_command, static) = { .path = "create host-interface", .short_help = "create host-interface name <ifname> [num-rx-queues <n>] " "[num-tx-queues <n>] [hw-addr <mac-addr>] [mode ip] " - "[qdisc-bypass-disable]", + "[qdisc-bypass-disable] [cksum-gso-disable]", .function = af_packet_create_command_fn, }; diff --git a/src/vnet/devices/af_packet/device.c b/src/vnet/devices/af_packet/device.c index 214aa019a6b..822dcdc7c22 100644 --- a/src/vnet/devices/af_packet/device.c +++ b/src/vnet/devices/af_packet/device.c @@ -95,6 +95,8 @@ format_af_packet_device (u8 * s, va_list * args) s = format (s, "\n%UFEATURES:", format_white_space, indent); if (apif->is_qdisc_bypass_enabled) s = format (s, "\n%Uqdisc-bpass-enabled", format_white_space, indent + 2); + if (apif->is_cksum_gso_enabled) + s = format (s, "\n%Ucksum-gso-enabled", format_white_space, indent + 2); vec_foreach (rx_queue, apif->rx_queues) { |