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
|
// 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 thiserror::Error;
|
||||||
use virtio_bindings::virtio_net::{
|
use virtio_bindings::virtio_net::{
|
||||||
VIRTIO_NET_CTRL_GUEST_OFFLOADS, VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET, VIRTIO_NET_CTRL_MQ,
|
VIRTIO_NET_CTRL_ANNOUNCE, VIRTIO_NET_CTRL_ANNOUNCE_ACK, VIRTIO_NET_CTRL_GUEST_OFFLOADS,
|
||||||
VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX, VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN,
|
VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET, VIRTIO_NET_CTRL_MQ, VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX,
|
||||||
VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, VIRTIO_NET_ERR, VIRTIO_NET_OK,
|
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 virtio_queue::{Queue, QueueT};
|
||||||
use vm_memory::{ByteValued, Bytes, GuestMemoryError};
|
use vm_memory::{ByteValued, Bytes, GuestMemoryError};
|
||||||
@@ -53,6 +57,26 @@ pub struct ControlHeader {
|
|||||||
// SAFETY: ControlHeader only contains a series of integers
|
// SAFETY: ControlHeader only contains a series of integers
|
||||||
unsafe impl ByteValued for ControlHeader {}
|
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 struct CtrlQueue {
|
||||||
pub taps: Vec<Tap>,
|
pub taps: Vec<Tap>,
|
||||||
}
|
}
|
||||||
@@ -128,6 +152,10 @@ impl CtrlQueue {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ if is_tolerated_ctrl_command(ctrl_hdr) => {
|
||||||
|
debug!("Ignoring unsupported but tolerated control command {ctrl_hdr:?}");
|
||||||
|
true
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
warn!("Unsupported command {ctrl_hdr:?}");
|
warn!("Unsupported command {ctrl_hdr:?}");
|
||||||
false
|
false
|
||||||
|
|||||||
Reference in New Issue
Block a user