mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
net_util: Tolerate some unsupported command classes
Windows NetKVM driver (>= 0.1.271) issues unsupported command classes even when they are not even advertised. According to the Virtio 1.2 specification: RX, VLAN, and ANNOUNCE control paths are only meaningful when their corresponding features are negotiated in sections 5.1.3.1, 5.1.6.5.1.2, 5.1.6.5.2.2, and 5.1.6.5.4.1. RX and VLAN are explicitly described as best-effort in sections 5.1.6.5.1 and 5.1.6.5.3. Instead of returning an error to the guest, return success to the guest. Fixes: #7925 Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
@@ -2,12 +2,16 @@
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
|
||||
|
||||
use log::{error, info, warn};
|
||||
use log::{debug, error, info, warn};
|
||||
use thiserror::Error;
|
||||
use virtio_bindings::virtio_net::{
|
||||
VIRTIO_NET_CTRL_GUEST_OFFLOADS, VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET, VIRTIO_NET_CTRL_MQ,
|
||||
VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX, VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN,
|
||||
VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, VIRTIO_NET_ERR, VIRTIO_NET_OK,
|
||||
VIRTIO_NET_CTRL_ANNOUNCE, VIRTIO_NET_CTRL_ANNOUNCE_ACK, VIRTIO_NET_CTRL_GUEST_OFFLOADS,
|
||||
VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET, VIRTIO_NET_CTRL_MQ, VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX,
|
||||
VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN, VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, VIRTIO_NET_CTRL_RX,
|
||||
VIRTIO_NET_CTRL_RX_ALLMULTI, VIRTIO_NET_CTRL_RX_ALLUNI, VIRTIO_NET_CTRL_RX_NOBCAST,
|
||||
VIRTIO_NET_CTRL_RX_NOMULTI, VIRTIO_NET_CTRL_RX_NOUNI, VIRTIO_NET_CTRL_RX_PROMISC,
|
||||
VIRTIO_NET_CTRL_VLAN, VIRTIO_NET_CTRL_VLAN_ADD, VIRTIO_NET_CTRL_VLAN_DEL, VIRTIO_NET_ERR,
|
||||
VIRTIO_NET_OK,
|
||||
};
|
||||
use virtio_queue::{Queue, QueueT};
|
||||
use vm_memory::{ByteValued, Bytes, GuestMemoryError};
|
||||
@@ -53,6 +57,26 @@ pub struct ControlHeader {
|
||||
// SAFETY: ControlHeader only contains a series of integers
|
||||
unsafe impl ByteValued for ControlHeader {}
|
||||
|
||||
fn is_tolerated_ctrl_command(ctrl_hdr: ControlHeader) -> bool {
|
||||
match u32::from(ctrl_hdr.class) {
|
||||
VIRTIO_NET_CTRL_RX => matches!(
|
||||
u32::from(ctrl_hdr.cmd),
|
||||
VIRTIO_NET_CTRL_RX_PROMISC
|
||||
| VIRTIO_NET_CTRL_RX_ALLMULTI
|
||||
| VIRTIO_NET_CTRL_RX_ALLUNI
|
||||
| VIRTIO_NET_CTRL_RX_NOMULTI
|
||||
| VIRTIO_NET_CTRL_RX_NOUNI
|
||||
| VIRTIO_NET_CTRL_RX_NOBCAST
|
||||
),
|
||||
VIRTIO_NET_CTRL_VLAN => matches!(
|
||||
u32::from(ctrl_hdr.cmd),
|
||||
VIRTIO_NET_CTRL_VLAN_ADD | VIRTIO_NET_CTRL_VLAN_DEL
|
||||
),
|
||||
VIRTIO_NET_CTRL_ANNOUNCE => u32::from(ctrl_hdr.cmd) == VIRTIO_NET_CTRL_ANNOUNCE_ACK,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CtrlQueue {
|
||||
pub taps: Vec<Tap>,
|
||||
}
|
||||
@@ -128,6 +152,10 @@ impl CtrlQueue {
|
||||
false
|
||||
}
|
||||
}
|
||||
_ if is_tolerated_ctrl_command(ctrl_hdr) => {
|
||||
debug!("Ignoring unsupported but tolerated control command {ctrl_hdr:?}");
|
||||
true
|
||||
}
|
||||
_ => {
|
||||
warn!("Unsupported command {ctrl_hdr:?}");
|
||||
false
|
||||
|
||||
Reference in New Issue
Block a user