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;
*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)
{
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;
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;
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);
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);
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;
;
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,
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,
};