(
&mut self,
mem: &GuestMemoryMmap,
queue: &mut Queue,
access_platform: Option<&dyn AccessPlatform>,
)
| 87 | } |
| 88 | |
| 89 | pub fn process( |
| 90 | &mut self, |
| 91 | mem: &GuestMemoryMmap, |
| 92 | queue: &mut Queue, |
| 93 | access_platform: Option<&dyn AccessPlatform>, |
| 94 | ) -> Result<()> { |
| 95 | while let Some(mut desc_chain) = queue.pop_descriptor_chain(mem) { |
| 96 | let ctrl_desc = desc_chain.next().ok_or(Error::NoControlHeaderDescriptor)?; |
| 97 | |
| 98 | let ctrl_hdr: ControlHeader = desc_chain |
| 99 | .memory() |
| 100 | .read_obj( |
| 101 | ctrl_desc |
| 102 | .addr() |
| 103 | .translate_gva(access_platform, ctrl_desc.len() as usize) |
| 104 | .map_err(|e| Error::GuestMemory(GuestMemoryError::IOError(e)))?, |
| 105 | ) |
| 106 | .map_err(Error::GuestMemory)?; |
| 107 | let data_desc = desc_chain.next().ok_or(Error::NoDataDescriptor)?; |
| 108 | |
| 109 | let data_desc_addr = data_desc |
| 110 | .addr() |
| 111 | .translate_gva(access_platform, data_desc.len() as usize) |
| 112 | .map_err(|e| Error::GuestMemory(GuestMemoryError::IOError(e)))?; |
| 113 | |
| 114 | let status_desc = desc_chain.next().ok_or(Error::NoStatusDescriptor)?; |
| 115 | |
| 116 | let ok = match u32::from(ctrl_hdr.class) { |
| 117 | VIRTIO_NET_CTRL_MQ => { |
| 118 | let queue_pairs = desc_chain |
| 119 | .memory() |
| 120 | .read_obj::<u16>(data_desc_addr) |
| 121 | .map_err(Error::GuestMemory)?; |
| 122 | if u32::from(ctrl_hdr.cmd) != VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET { |
| 123 | warn!("Unsupported command: {}", ctrl_hdr.cmd); |
| 124 | false |
| 125 | } else if (queue_pairs < VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN as u16) |
| 126 | || (queue_pairs > VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX as u16) |
| 127 | { |
| 128 | warn!("Number of MQ pairs out of range: {queue_pairs}"); |
| 129 | false |
| 130 | } else { |
| 131 | info!("Number of MQ pairs requested: {queue_pairs}"); |
| 132 | true |
| 133 | } |
| 134 | } |
| 135 | VIRTIO_NET_CTRL_GUEST_OFFLOADS => { |
| 136 | let features = desc_chain |
| 137 | .memory() |
| 138 | .read_obj::<u64>(data_desc_addr) |
| 139 | .map_err(Error::GuestMemory)?; |
| 140 | if u32::from(ctrl_hdr.cmd) == VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET { |
| 141 | let mut ok = true; |
| 142 | for tap in self.taps.iter_mut() { |
| 143 | info!("Reprogramming tap offload with features: {features}"); |
| 144 | tap.set_offload(virtio_features_to_tap_offload(features)) |
| 145 | .map_err(|e| { |
| 146 | error!("Error programming tap offload: {e:?}"); |
no test coverage detected