The network device uses two shared memory rings for communication: one
for transmit, one for receieve.
Transmit requests are described by the following structure:
typedef struct netif_tx_request {
grant_ref_t gref; /* Reference to buffer page */
uint16_t offset; /* Offset within buffer page */
uint16_t flags; /* NETTXF_* */
uint16_t id; /* Echoed in response message. */
uint16_t size; /* Packet size in bytes. */
} netif_tx_request_t;
- gref
- Grant reference for the network buffer
- offset
- Offset to data
- flags
- Transmit flags (currently only NETTXF_csum_blank is
supported, to indicate that the protocol checksum field is
incomplete).
- id
- Echoed to guest by the backend in the ring-level response so
that the guest can match it to this request
- size
- Buffer size
Each transmit request is followed by a transmit response at some later
date. This is part of the shared-memory communication protocol and
allows the guest to (potentially) retire internal structures related
to the request. It does not imply a network-level response. This
structure is as follows:
typedef struct netif_tx_response {
uint16_t id;
int16_t status;
} netif_tx_response_t;
- id
- Echo of the ID field in the corresponding transmit request.
- status
- Success / failure status of the transmit request.
Receive requests must be queued by the frontend, accompanied by a
donation of page-frames to the backend. The backend transfers page
frames full of data back to the guest
typedef struct {
uint16_t id; /* Echoed in response message. */
grant_ref_t gref; /* Reference to incoming granted frame */
} netif_rx_request_t;
- id
- Echoed by the frontend to identify this request when
responding.
- gref
- Transfer reference - the backend will use this reference
to transfer a frame of network data to us.
Receive response descriptors are queued for each received frame. Note
that these may only be queued in reply to an existing receive request,
providing an in-built form of traffic throttling.
typedef struct {
uint16_t id;
uint16_t offset; /* Offset in page of start of received packet */
uint16_t flags; /* NETRXF_* */
int16_t status; /* -ve: BLKIF_RSP_* ; +ve: Rx'ed pkt size. */
} netif_rx_response_t;
- id
- ID echoed from the original request, used by the guest to
match this response to the original request.
- offset
- Offset to data within the transferred frame.
- flags
- Transmit flags (currently only NETRXF_csum_valid is
supported, to indicate that the protocol checksum field has already
been validated).
- status
- Success / error status for this operation.
Note that the receive protocol includes a mechanism for guests to
receive incoming memory frames but there is no explicit transfer of
frames in the other direction. Guests are expected to return memory
to the hypervisor in order to use the network interface. They must do this or they will exceed their maximum memory reservation and
will not be able to receive incoming frame transfers. When necessary,
the backend is able to replenish its pool of free network buffers by
claiming some of this free memory from the hypervisor.