|
iPXE
|
A persistent I/O buffer. More...
#include <iobuf.h>
Data Fields | |
| struct list_head | list |
| List of which this buffer is a member. | |
| struct dma_mapping | map |
| DMA mapping. | |
| void * | head |
| Start of the buffer. | |
| void * | data |
| Start of data. | |
| void * | tail |
| End of data. | |
| void * | end |
| End of the buffer. | |
A persistent I/O buffer.
This data structure encapsulates a long-lived I/O buffer. The buffer may be passed between multiple owners, queued for possible retransmission, etc.
The datapath model uses a zero-copy fast path for both transmit and receive directions. Headers and footers are appended/prepended and stripped in situ as the buffer is passed between layers of the network stack. Adding or stripping a header or footer is merely a pointer update: no existing data is ever moved.
The buffer content is delineated by four pointers, which satisfy the invariant:
head <= data <= tail <= end
The head and end pointers are set when the buffer is first allocated and are never changed. The data and tail pointers represent the current data region within the buffer, and are modified by the accessor functions iob_push(), iob_pull(), iob_put(), iob_unput() etc.
The current length of the data region may be obtained using iob_len(). The space currently between the head and data pointers is the available headroom and its length may be obtained using iob_headroom(). Similarly, the space currently between the tail and end pointers is the available tailroom and its length may be obtained using iob_tailroom().
It is the responsibility of the allocator of the I/O buffer to ensure that sufficient headroom and tailroom exists for all subsequent users of the I/O buffer. For example: a transmit buffer allocated by the TCP layer must ensure that there is sufficient headroom for the TCP headers, the network-layer (IPv4/IPv6) headers, and the longest possible link-layer header. The lower layers are permitted to assume that sufficient headroom exists and may call iob_push() to prepend their headers without performing any further checks.
On the receive datapath, I/O buffers are typically allocated by the device driver. Some care must be taken to ensure that received buffers that end up being reflected and transmitted (e.g. responses to ARP requests) contain sufficient headroom. For most devices, transmit and receive buffers are symmetric and so any receive buffer will always have sufficient headroom for this purpose. Devices that require additional transmit headers (such as the Asix USB NICs) must ensure that additional headroom is allocated in receive buffers to allow for this reflection.
Received I/O buffers should always be treated as containing untrusted data. Device drivers may assume that DMA-capable hardware will not report erroneous lengths (e.g. a received length greater than the original allocation length), but all other consumers must validate the buffer length before accessing its contents or stripping headers or footers.
The accessor functions iob_push(), iob_pull(), iob_unput() etc include assertion checks but do not perform any runtime checks that the pointer invariant is maintained. In particular, using iob_pull() or iob_unput() to strip a header without first using iob_len() to check the available length will result in an invariant violation that causes the iob_len() calculation to underflow and report an extremely large buffer length (which is then likely to cause a false positive for any subsequent buffer length checks).
| struct list_head io_buffer::list |
List of which this buffer is a member.
The list must belong to the current owner of the buffer. Different owners may maintain different lists (e.g. a retransmission list for TCP).
Definition at line 105 of file iobuf.h.
Referenced by ath5k_tx_processq(), efi_pxe_udp_close(), efi_pxe_udp_deliver(), efi_pxe_udp_read(), efi_snp_flush(), efi_snp_poll(), efi_snp_receive(), efi_undi_get_status(), eoib_duplicate(), free_tls(), iob_concatenate(), lotest_dequeue(), lotest_rx(), neighbour_drop(), neighbour_tx(), neighbour_tx_queue(), net80211_handle_mgmt(), net80211_mgmt_dequeue(), net_discard(), netdev_rx(), netdev_rx_dequeue(), netdev_tx(), netdev_tx_complete_err(), netdev_tx_complete_next_err(), netdev_tx_defer(), netfront_discard(), netfront_poll_rx(), netvsc_recv_data(), posix_file_free(), posix_file_xfer_deliver(), pxe_udp_deliver(), pxe_udp_discard(), pxenv_udp_close(), pxenv_udp_read(), read(), tcp_close(), tcp_discard(), tcp_process_rx_queue(), tcp_process_tx_queue(), tcp_rx_enqueue(), tcp_xfer_deliver(), tls_cipherstream_deliver(), tls_hmac_list(), tls_new_ciphertext(), tls_new_data(), tls_newdata_process_data(), tls_newdata_process_header(), tls_send_certificate(), unregister_usb(), usb_control(), usb_control_complete(), usb_flush(), usb_prefill(), usb_recycle(), usb_refill_limit(), vlan_transmit(), and vmbus_xfer_page_iobufs().
| struct dma_mapping io_buffer::map |
DMA mapping.
Definition at line 108 of file iobuf.h.
Referenced by alloc_iob_raw(), free_iob(), iob_dma(), iob_map(), iob_unmap(), net_discard(), netdev_rx(), netdev_rx_err(), netdev_tx(), and netdev_tx_err().
| void* io_buffer::head |
Start of the buffer.
Definition at line 111 of file iobuf.h.
Referenced by alloc_iob_okx(), alloc_iob_raw(), free_iob(), iob_headroom(), iob_populate(), and net80211_probe_step().
| void* io_buffer::data |
Start of data.
Definition at line 113 of file iobuf.h.
Referenced by a3c90x_prepare_rx_desc(), a3c90x_transmit(), acm_control_receive(), acm_control_transmit(), acm_intr_complete(), acm_transmit(), af_packet_nic_poll(), af_packet_nic_transmit(), alloc_iob_okx(), alloc_iob_raw(), aoe_rx(), aoecmd_rx(), aoecmd_tx(), arbel_complete(), arbel_fill_mlx_send_wqe(), arbel_fill_rc_send_wqe(), arbel_fill_ud_send_wqe(), arbel_post_recv(), arp_rx(), ath5k_rx_iob_alloc(), ath5k_txbuf_setup(), ath_rx_init(), ath_tx_setup_buffer(), atl1e_clean_rx_irq(), atl1e_tx_map(), axge_in_complete(), axge_intr_complete(), b44_process_rx_packets(), b44_rx_refill(), b44_transmit(), bnxt_add_vlan(), bnxt_rx_drop(), bnxt_rx_process(), bnxt_tx(), bnxt_tx_adjust_pkt(), bnxt_tx_complete(), ccmp_decrypt(), ccmp_encrypt(), cgem_refill_rx(), cgem_transmit(), dhcp_deliver(), dhcp_tx(), dhcpv6_rx(), dm96xx_in_complete(), dm96xx_intr_complete(), dns_xfer_deliver(), dwmac_refill_rx(), dwmac_transmit(), eapol_eap_rx(), eapol_key_rx(), eapol_rx(), ecm_intr_complete(), efab_fill_rx_queue(), efab_receive(), efab_transmit(), efi_download_deliver_iob(), efi_local_step(), efi_pxe_udp_read(), efi_snp_receive(), efi_usb_async_complete(), efi_usb_sync_transfer(), efx_hunt_build_rx_desc(), efx_hunt_build_tx_desc(), efx_hunt_receive(), efx_hunt_rxq_fill(), efx_hunt_transmit(), ehci_endpoint_message(), ehci_endpoint_stream(), ena_refill_rx(), ena_transmit(), eoib_complete_recv(), eoib_duplicate(), eoib_transmit(), eth_pull(), eth_slow_lacp_dump(), eth_slow_lacp_rx(), eth_slow_marker_dump(), eth_slow_marker_rx(), eth_slow_rx(), exanic_transmit(), falcon_build_rx_desc(), falcon_build_tx_desc(), fc_els_rx(), fc_ns_query_deliver(), fc_port_deliver(), fc_xchg_rx(), fcoe_deliver(), fcoe_fip_rx(), fcoe_rx(), fcpcmd_recv_rddata(), fcpcmd_recv_rsp(), fcpcmd_recv_unknown(), fcpcmd_recv_xfer_rdy(), flexboot_nodnic_post_recv(), forcedeth_transmit(), fragment_reassemble(), free_iob(), ftp_control_deliver(), gdbudp_recv(), get_hw_packet_type(), golan_post_recv(), golan_post_send(), gve_transmit(), hermon_fill_eth_send_wqe(), hermon_fill_mlx_send_wqe(), hermon_fill_rc_send_wqe(), hermon_fill_ud_send_wqe(), hermon_post_recv(), http_rx_linebuf(), hub_complete(), hunt_mcdi_copyin(), hunt_mcdi_copyout(), hunt_mcdi_request_poll(), ib_cmrc_complete_recv(), ib_cmrc_xfer_deliver(), ib_mi_complete_recv(), ib_pull(), ib_push(), icmp_rx_echo_reply(), icmp_rx_echo_request(), icmp_tx_echo(), icmp_tx_echo_reply(), icmp_tx_echo_request(), icmpv4_rx(), icmpv6_rx(), icplus_refill_rx(), icplus_transmit(), ifec_net_transmit(), igbvf_refill_rx_ring(), igbvf_setup_rx_resources(), igbvf_transmit(), imux_in_complete(), imux_rx_tcp(), imux_tx(), imux_tx_tcp(), intel_refill_rx(), intel_transmit(), intelxl_refill_rx(), intelxl_transmit(), iob_concatenate(), iob_dma(), iob_empty(), iob_headroom(), iob_len(), iob_map(), iob_pad(), iob_populate(), iob_pull(), iob_push(), iob_reserve(), iob_split(), ipair_deliver(), iphone_in_complete(), ipoib_complete_recv(), ipoib_translate_rx_arp(), ipoib_translate_tx_arp(), ipoib_transmit(), ipv4_fragment_offset(), ipv4_is_fragment(), ipv4_more_fragments(), ipv4_pshdr_chksum(), ipv4_rx(), ipv6_fragment_offset(), ipv6_is_fragment(), ipv6_more_fragments(), ipv6_rx(), iscsi_socket_deliver(), iscsi_tx_login_request(), jme_fill_tx_desc(), jme_set_clean_rxdesc(), jme_tx_clean(), legacy_poll(), legacy_transmit(), linda_post_recv(), linda_post_send(), lldp_rx(), loopback_wait(), mnpnet_transmit(), myri10ge_net_transmit(), myri10ge_post_receive(), myson_refill_rx(), myson_transmit(), natsemi_refill_rx(), natsemi_transmit(), ncm_in_complete(), ncm_intr_complete(), ndp_rx_neighbour(), ndp_rx_router_advertisement(), ndp_tx_ll_addr(), neighbour_tx_queue(), net80211_accum_frags(), net80211_handle_assoc_reply(), net80211_handle_auth(), net80211_handle_mgmt(), net80211_ll_pull(), net80211_netdev_transmit(), net80211_prepare_assoc(), net80211_probe_step(), net80211_rx(), net80211_rx_frag(), net80211_send_assoc(), net80211_update_link_quality(), net_poll(), netdev_rx(), netdev_tx(), netfront_poll_rx(), netfront_refill_rx(), netfront_transmit(), netvsc_transmit(), nfs_get_read_reply(), nfs_get_readlink_reply(), nfs_iob_get_fh(), nii_transmit(), ntp_deliver(), oncrpc_iob_get_cred(), pcnet32_transmit(), peerblk_raw_rx(), peerblk_retrieval_rx(), peerdisc_socket_rx(), phantom_refill_rx_ring(), phantom_transmit(), ping_rx(), pinger_deliver(), pnic_poll(), pnic_transmit(), pxe_tftp_xfer_deliver(), pxenv_udp_read(), pxenv_undi_isr(), qib7322_post_recv(), qib7322_post_send(), rdc_refill_rx(), read(), realtek_refill_rx(), realtek_transmit(), rhine_refill_rx(), rhine_transmit(), rndis_rx(), rndis_rx_data(), rndis_rx_initialise(), rndis_rx_message(), rndis_rx_query_oid(), rndis_rx_set_oid(), rndis_rx_status(), rndis_tx_complete_err(), rndis_tx_defer(), rtl818x_handle_rx(), rtl818x_init_rx_ring(), rtl818x_tx(), sec80211_detect(), shomron_fill_eth_send_wqe(), sis190_alloc_rx_iob(), sis190_process_rx(), sis190_transmit(), skge_rx_setup(), skge_xmit_frame(), sky2_rx_map_iob(), sky2_xmit_frame(), slam_pull_header(), slam_pull_value(), slam_socket_deliver(), slirp_transmit(), smsc75xx_in_complete(), smsc95xx_in_complete(), smscusb_intr_complete(), snpnet_transmit(), srp_login(), srpdev_deliver(), stp_rx(), tap_poll(), tap_transmit(), tcp_process_rx_queue(), tcp_process_tx_queue(), tcp_rx(), tcp_rx_enqueue(), tcp_sack_block(), tcp_xmit_reset(), tcp_xmit_sack(), tftp_rx(), tftp_rx_data(), tkip_decrypt(), tkip_encrypt(), tls_cipherstream_deliver(), tls_hmac_list(), tls_new_alert(), tls_new_change_cipher(), tls_new_ciphertext(), tls_new_handshake(), tls_send_record(), tls_verify_padding(), txnic_refill_rq(), txnic_send(), udp_rx(), uhci_endpoint_message(), uhci_endpoint_stream(), uhci_enqueue(), undinet_transmit(), usb_control(), usb_message(), usbblk_in_complete(), usbio_bulk_in_poll(), usbio_bulk_out_poll(), usbio_control_poll(), usbio_interrupt_poll(), usbkbd_complete(), velocity_poll_rx(), velocity_transmit(), virtio_net_submit(), vlan_rx(), vmbus_send_data(), vmxnet3_refill_rx(), vmxnet3_transmit(), vxge_hw_fifo_txdl_buffer_set(), vxge_hw_ring_rxd_1b_set(), vxge_hw_vpath_poll_rx(), wep_decrypt(), wep_encrypt(), wpa_make_rsn_ie(), wpa_send_2_of_4(), wpa_send_eapol(), wpa_send_final(), wpa_start(), xcm_deliver(), xferbuf_deliver(), and xhci_endpoint_message().
| void* io_buffer::tail |
End of data.
Definition at line 115 of file iobuf.h.
Referenced by af_packet_nic_transmit(), alloc_iob_raw(), ccmp_decrypt(), eapol_key_rx(), free_iob(), iob_empty(), iob_len(), iob_populate(), iob_pull(), iob_put(), iob_reserve(), iob_tailroom(), iob_unput(), net80211_handle_assoc_reply(), net80211_prepare_assoc(), net80211_probe_step(), sec80211_detect(), tap_transmit(), tftp_send_rrq(), tkip_decrypt(), tls_new_ciphertext(), tls_verify_padding(), wpa_make_rsn_ie(), wpa_send_eapol(), and wpa_start().
| void* io_buffer::end |
End of the buffer.
Definition at line 117 of file iobuf.h.
Referenced by alloc_iob_okx(), alloc_iob_raw(), free_iob(), iob_populate(), and iob_tailroom().