summaryrefslogtreecommitdiffstats
path: root/src/vnet/devices/af_packet/device.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/devices/af_packet/device.c')
-rw-r--r--src/vnet/devices/af_packet/device.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/vnet/devices/af_packet/device.c b/src/vnet/devices/af_packet/device.c
index e1eb46a5e9b..74bc1c8c42c 100644
--- a/src/vnet/devices/af_packet/device.c
+++ b/src/vnet/devices/af_packet/device.c
@@ -632,6 +632,40 @@ error:
return 0; /* no error */
}
+static clib_error_t *
+af_packet_interface_rx_mode_change (vnet_main_t *vnm, u32 hw_if_index, u32 qid,
+ vnet_hw_if_rx_mode mode)
+{
+ 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;
+
+ apif = vec_elt_at_index (apm->interfaces, hw->dev_instance);
+
+ if (mode == VNET_HW_IF_RX_MODE_ADAPTIVE)
+ {
+ vlib_log_err (apm->log_class,
+ "af_packet_%s adaptive mode is not supported",
+ apif->host_if_name);
+ return clib_error_return (
+ 0, "af_packet_%s adaptive mode is not supported", apif->host_if_name);
+ }
+
+ af_packet_queue_t *rx_queue = vec_elt_at_index (apif->rx_queues, qid);
+
+ if (rx_queue->mode != mode)
+ {
+ rx_queue->mode = mode;
+
+ if (mode == VNET_HW_IF_RX_MODE_POLLING)
+ apm->polling_count++;
+ else if (mode == VNET_HW_IF_RX_MODE_INTERRUPT && apm->polling_count > 0)
+ apm->polling_count--;
+ }
+
+ return 0;
+}
+
VNET_DEVICE_CLASS (af_packet_device_class) = {
.name = "af-packet",
.format_device_name = format_af_packet_device_name,
@@ -644,6 +678,7 @@ VNET_DEVICE_CLASS (af_packet_device_class) = {
.admin_up_down_function = af_packet_interface_admin_up_down,
.subif_add_del_function = af_packet_subif_add_del_function,
.mac_addr_change_function = af_packet_set_mac_address_function,
+ .rx_mode_change_function = af_packet_interface_rx_mode_change,
};
/*