Supporting virtio on vwifi by pretending vwifi as a virtio-net driver. For now, we can do inter-guest communication by the correct setting described in README.md. We mainly enhance vwifi in two aspects:
virtio: We make vwifi recognize the virtio-net devices by registering vwifi with the virtio-driver and providing the probe/remove function. For virtqueue (hereinafter called vq), we have one RX vq and one TX vq (right now we don't support multi-queue):
TX vq: every time we have a frame to be sent, we add an output buffer to the vq, and call virtqueue_kick() to kick the data to the virtio-net device.
RX vq: on ndo_open(), we fill an input buffer into the vq and refill the input buffer on every RX interrupt. Note that whenever we put/get buffer or kick the buffer, we need to hold the virtio spin lock to ensure that we won't have other operations on the vq at the same time. We should note that we need to ensure that while holding the spin lock, we can't call dev_kfree_skb() (not safe in interrupt context) and only call kmalloc() with GFP_ATOMIC. Also, we call the spin_lock_irqsave() since the TX/RX done interrupt may be reentrant and will cause deadlock.
For now, most of the virtio-net features are not supported by vwifi. For future support, we can firstly focus on the multi-queue feature and using NAPI on the RX path.
vwifi mangement frame: Originally, vwifi does any management operation (like cfg80211_ops->scan()) and TX/RX path by "shortcut", which means we get the other network interface structures and struct owl_vif by iterating the vif list and finding the one with the same MAC address. This is possible only when every interface is in the same host.
We introduce the "vwifi management frame" since it's not possible to get the other network interface structures or struct owl_vif when vwifi is across many machines.
Most of these management frame types are inspired by IEEE 802.11 management frames, with little modifications since we are sending Ethernet frames. And note that we send these management frames with the Ethertype/length field being length (i.e. 802.3 frames), so we can distinguish it from a data frame (Ethernet II).
Note that any multi-octet field should be in a specific byte-order so that any machine reads the same data as the writer's wish. For byte order, we use little-endian so that most of the machine can directly read the data. The multi-octet fields should be in __leX type, and the sender is responsible to call cpu_to_leX() on the data to be sent so that anytime the receiver can use leX_to_cpu() to access the data and store it in its machine byte-order.
For a more detailed description of all the management frame types (or how an STA will not receive the frames from other BSS), please check the comments in vwifi.c (above the definition of enum VWIFI_VIRTIO_PACKET_TYPE).
Supporting virtio on vwifi by pretending vwifi as a virtio-net driver. For now, we can do inter-guest communication by the correct setting described in
README.md
. We mainly enhance vwifi in two aspects:For now, most of the virtio-net features are not supported by vwifi. For future support, we can firstly focus on the multi-queue feature and using NAPI on the RX path.
struct owl_vif
by iterating the vif list and finding the one with the same MAC address. This is possible only when every interface is in the same host.We introduce the "vwifi management frame" since it's not possible to get the other network interface structures or
struct owl_vif
when vwifi is across many machines.Most of these management frame types are inspired by IEEE 802.11 management frames, with little modifications since we are sending Ethernet frames. And note that we send these management frames with the Ethertype/length field being length (i.e. 802.3 frames), so we can distinguish it from a data frame (Ethernet II).
Note that any multi-octet field should be in a specific byte-order so that any machine reads the same data as the writer's wish. For byte order, we use little-endian so that most of the machine can directly read the data. The multi-octet fields should be in __leX type, and the sender is responsible to call cpu_to_leX() on the data to be sent so that anytime the receiver can use leX_to_cpu() to access the data and store it in its machine byte-order.
For a more detailed description of all the management frame types (or how an STA will not receive the frames from other BSS), please check the comments in vwifi.c (above the definition of
enum VWIFI_VIRTIO_PACKET_TYPE
).