Skip to content

Commit c601682

Browse files
liuwrbradford
authored andcommitted
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: cloud-hypervisor#7925 Signed-off-by: Wei Liu <liuwe@microsoft.com>
1 parent 8026eb1 commit c601682

1 file changed

Lines changed: 32 additions & 4 deletions

File tree

net_util/src/ctrl_queue.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22
//
33
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
44

5-
use log::{error, info, warn};
5+
use log::{debug, error, info, warn};
66
use thiserror::Error;
77
use virtio_bindings::virtio_net::{
8-
VIRTIO_NET_CTRL_GUEST_OFFLOADS, VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET, VIRTIO_NET_CTRL_MQ,
9-
VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX, VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN,
10-
VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, VIRTIO_NET_ERR, VIRTIO_NET_OK,
8+
VIRTIO_NET_CTRL_ANNOUNCE, VIRTIO_NET_CTRL_ANNOUNCE_ACK, VIRTIO_NET_CTRL_GUEST_OFFLOADS,
9+
VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET, VIRTIO_NET_CTRL_MQ, VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX,
10+
VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN, VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, VIRTIO_NET_CTRL_RX,
11+
VIRTIO_NET_CTRL_RX_ALLMULTI, VIRTIO_NET_CTRL_RX_ALLUNI, VIRTIO_NET_CTRL_RX_NOBCAST,
12+
VIRTIO_NET_CTRL_RX_NOMULTI, VIRTIO_NET_CTRL_RX_NOUNI, VIRTIO_NET_CTRL_RX_PROMISC,
13+
VIRTIO_NET_CTRL_VLAN, VIRTIO_NET_CTRL_VLAN_ADD, VIRTIO_NET_CTRL_VLAN_DEL, VIRTIO_NET_ERR,
14+
VIRTIO_NET_OK,
1115
};
1216
use virtio_queue::{Queue, QueueT};
1317
use vm_memory::{ByteValued, Bytes, GuestMemoryError};
@@ -53,6 +57,26 @@ pub struct ControlHeader {
5357
// SAFETY: ControlHeader only contains a series of integers
5458
unsafe impl ByteValued for ControlHeader {}
5559

60+
fn is_tolerated_ctrl_command(ctrl_hdr: ControlHeader) -> bool {
61+
match u32::from(ctrl_hdr.class) {
62+
VIRTIO_NET_CTRL_RX => matches!(
63+
u32::from(ctrl_hdr.cmd),
64+
VIRTIO_NET_CTRL_RX_PROMISC
65+
| VIRTIO_NET_CTRL_RX_ALLMULTI
66+
| VIRTIO_NET_CTRL_RX_ALLUNI
67+
| VIRTIO_NET_CTRL_RX_NOMULTI
68+
| VIRTIO_NET_CTRL_RX_NOUNI
69+
| VIRTIO_NET_CTRL_RX_NOBCAST
70+
),
71+
VIRTIO_NET_CTRL_VLAN => matches!(
72+
u32::from(ctrl_hdr.cmd),
73+
VIRTIO_NET_CTRL_VLAN_ADD | VIRTIO_NET_CTRL_VLAN_DEL
74+
),
75+
VIRTIO_NET_CTRL_ANNOUNCE => u32::from(ctrl_hdr.cmd) == VIRTIO_NET_CTRL_ANNOUNCE_ACK,
76+
_ => false,
77+
}
78+
}
79+
5680
pub struct CtrlQueue {
5781
pub taps: Vec<Tap>,
5882
}
@@ -128,6 +152,10 @@ impl CtrlQueue {
128152
false
129153
}
130154
}
155+
_ if is_tolerated_ctrl_command(ctrl_hdr) => {
156+
debug!("Ignoring unsupported but tolerated control command {ctrl_hdr:?}");
157+
true
158+
}
131159
_ => {
132160
warn!("Unsupported command {ctrl_hdr:?}");
133161
false

0 commit comments

Comments
 (0)