diff options
-rw-r--r-- | src/vnet/devices/af_packet/af_packet.c | 29 | ||||
-rw-r--r-- | src/vnet/devices/af_packet/af_packet.h | 7 | ||||
-rw-r--r-- | src/vnet/devices/af_packet/af_packet_api.c | 4 | ||||
-rw-r--r-- | src/vnet/devices/af_packet/cli.c | 8 | ||||
-rw-r--r-- | src/vnet/devices/af_packet/device.c | 3 |
5 files changed, 39 insertions, 12 deletions
diff --git a/src/vnet/devices/af_packet/af_packet.c b/src/vnet/devices/af_packet/af_packet.c index c941d3763cf..a8ab944a513 100644 --- a/src/vnet/devices/af_packet/af_packet.c +++ b/src/vnet/devices/af_packet/af_packet.c @@ -191,7 +191,8 @@ 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) + u8 *is_cksum_gso_enabled, u32 fanout_id, u8 is_fanout, + af_packet_if_flags_t *flags) { af_packet_main_t *apm = &af_packet_main; struct sockaddr_ll sll; @@ -261,15 +262,18 @@ create_packet_v3_sock (int host_if_index, tpacket_req3_t *rx_req, *is_cksum_gso_enabled = 1; #if defined(PACKET_QDISC_BYPASS) - /* Introduced with Linux 3.14 so the ifdef should eventually be removed */ - if (setsockopt (*fd, SOL_PACKET, PACKET_QDISC_BYPASS, &opt, sizeof (opt)) < - 0) - { - vlib_log_debug (apm->log_class, - "Failed to set qdisc bypass error " - "handling option: %s (errno %d)", - strerror (errno), errno); - } + if (*flags & AF_PACKET_IF_FLAGS_QDISC_BYPASS) + /* Introduced with Linux 3.14 so the ifdef should eventually be removed */ + if (setsockopt (*fd, SOL_PACKET, PACKET_QDISC_BYPASS, &opt, sizeof (opt)) < + 0) + { + // remove the flag + *flags &= ~AF_PACKET_IF_FLAGS_QDISC_BYPASS; + vlib_log_debug (apm->log_class, + "Failed to set qdisc bypass error " + "handling option: %s (errno %d)", + strerror (errno), errno); + } #endif if (is_fanout) @@ -389,7 +393,7 @@ af_packet_queue_init (vlib_main_t *vm, af_packet_if_t *apif, { ret = create_packet_v3_sock (apif->host_if_index, rx_req, tx_req, &fd, &ring, &is_cksum_gso_enabled, - apif->dev_instance, is_fanout); + apif->dev_instance, is_fanout, &arg->flags); if (ret != 0) goto error; @@ -641,6 +645,9 @@ af_packet_create_if (af_packet_create_if_arg_t *arg) af_packet_set_rx_queues (vm, apif); af_packet_set_tx_queues (vm, apif); + apif->is_qdisc_bypass_enabled = + (arg->flags & AF_PACKET_IF_FLAGS_QDISC_BYPASS); + 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 1b24eef788c..2b051251455 100644 --- a/src/vnet/devices/af_packet/af_packet.h +++ b/src/vnet/devices/af_packet/af_packet.h @@ -32,6 +32,11 @@ typedef enum AF_PACKET_IF_MODE_IP = 2 } af_packet_if_mode_t; +typedef enum +{ + AF_PACKET_IF_FLAGS_QDISC_BYPASS = 1, +} af_packet_if_flags_t; + typedef struct { u32 sw_if_index; @@ -101,6 +106,7 @@ typedef struct u32 dev_instance; af_packet_ring_t *rings; + u8 is_qdisc_bypass_enabled; } af_packet_if_t; typedef struct @@ -129,6 +135,7 @@ typedef struct u8 num_rxqs; u8 num_txqs; af_packet_if_mode_t mode; + af_packet_if_flags_t flags; /* return */ u32 sw_if_index; diff --git a/src/vnet/devices/af_packet/af_packet_api.c b/src/vnet/devices/af_packet/af_packet_api.c index 693380d8ae5..2a58ba7438a 100644 --- a/src/vnet/devices/af_packet/af_packet_api.c +++ b/src/vnet/devices/af_packet/af_packet_api.c @@ -47,6 +47,8 @@ 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; rv = af_packet_create_if (arg); vec_free (arg->host_if_name); @@ -77,6 +79,8 @@ vl_api_af_packet_create_v2_t_handler (vl_api_af_packet_create_v2_t *mp) arg->tx_frames_per_block = clib_net_to_host_u32 (mp->tx_frames_per_block); 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; 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 c90d5251f9f..443a1d5c737 100644 --- a/src/vnet/devices/af_packet/cli.c +++ b/src/vnet/devices/af_packet/cli.c @@ -58,6 +58,9 @@ af_packet_create_command_fn (vlib_main_t * vm, unformat_input_t * input, arg->num_rxqs = 1; arg->num_txqs = 1; + // Default flags + arg->flags = AF_PACKET_IF_FLAGS_QDISC_BYPASS; + /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return 0; @@ -80,6 +83,8 @@ af_packet_create_command_fn (vlib_main_t * vm, unformat_input_t * input, ; else if (unformat (line_input, "num-tx-queues %u", &arg->num_txqs)) ; + else if (unformat (line_input, "qdisc-bypass-disable")) + arg->flags &= ~AF_PACKET_IF_FLAGS_QDISC_BYPASS; 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, @@ -154,7 +159,8 @@ done: 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]", + "[num-tx-queues <n>] [hw-addr <mac-addr>] [mode ip] " + "[qdisc-bypass-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 013d9f71733..214aa019a6b 100644 --- a/src/vnet/devices/af_packet/device.c +++ b/src/vnet/devices/af_packet/device.c @@ -92,6 +92,9 @@ format_af_packet_device (u8 * s, va_list * args) af_packet_queue_t *tx_queue = 0; s = format (s, "Linux PACKET socket interface"); + 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); vec_foreach (rx_queue, apif->rx_queues) { |