VTNET(4)
VTNET ππ¦ β the VirtIO Ethernet driver, explained by your fav Unix bestie
Okay so picture this: you're in a virtual machine, right, and you need network. That's literally where vtnet comes in. The manual page is vtnet(4) and it lives in the Kernel Interfaces Manual, and I'm about to walk you through every single line because you deserve to understand it, periodt. π
β¨ SYNOPSIS β¨
So you wanna get this driver into your kernel? Bestie, you got two options. Option one, drop these lines in your kernel configuration file:
device vtnet
Option two, if you'd rather load it as a module at boot time (lowkey easier), put this line in loader.conf(5):
if_vtnet_load="YES"
Both work. Choose your fighter. π
πΈ DESCRIPTION πΈ
The vtnet device driver provides support for VirtIO Ethernet devices. That's the whole vibe. π«Ά
Okay so here's where it gets iconic. If the hypervisor advertises the appropriate features (iykyk), the vtnet driver supports so many things, let me list them because they all matter:
- TCP/UDP checksum offload for both transmit and receive
- TCP segmentation offload (TSO)
- TCP large receive offload (LRO)
- hardware VLAN tag stripping/insertion features
- a multicast hash filter
- Jumbo Frames (up to 9216 bytes)
That Jumbo Frames one can be configured via the interface MTU setting, ngl that's kinda the main character move. π₯
Now, about TCP LRO, there are literally two flavors and you need to know both:
- Hardware TCP LRO β this is performed by the host providing TCP segments larger than the MTU to the guest.
- Software TCP LRO β this is performed by the network stack of the guest processing TCP segments in an optimized way.
Only one flavour of TCP LRO should be used. One. Not both. Please. π And since hardware TCP LRO can have bad interactions with IP forwarding and software TCP LRO mitigates several drawbacks of hardware TCP LRO, the default setting is to disable hardware TCP LRO. See the loader tunable hw.vtnet.X.lro_disable for that.
Also important, bestie: TCP/UDP receive checksum offload cannot be configured independently for IPv4 and IPv6. Not a thing. And if you select an MTU larger than 1500 bytes with the ifconfig(8) utility, that configures the adapter to receive and transmit Jumbo Frames. Slay.
For more info on configuring this device, see ifconfig(8). π
π LOADER TUNABLES π
Okay so these tunables can be set at the loader(8) prompt before booting the kernel or stored in loader.conf(5). Either way, here they all are, and yes I'm giving you every single one because I'm not about to skip the boring parts. π
hw.vtnet.csum_disable/hw.vtnet.X.csum_disableβ This tunable disables receive and transmit checksum offloading for TCP and UDP. This also implies that TCP segmentation offloading and large receive offload are disabled. The default value is0.hw.vtnet.fixup_needs_csum/hw.vtnet.X.fixup_needs_csumβ This tunable enforces the calculation of a valid TCP or UDP checksum for packets received withVIRTIO_NET_HDR_F_NEEDS_CSUMbeing set in the flags field of the structurestruct virtio_net_hdr. It also marks the checksum as being correct in the mbuf packet header. The default value is0. > Heads up bestie: this tunable is deprecated and will be removed in FreeBSD 16. πhw.vtnet.tso_disable/hw.vtnet.X.tso_disableβ This tunable disables TCP segmentation offloading. The default value is0.hw.vtnet.lro_disable/hw.vtnet.X.lro_disableβ This tunable disables hardware TCP LRO. The default value is1.hw.vtnet.mq_disable/hw.vtnet.X.mq_disableβ This tunable disables multiqueue. The default value is0.hw.vtnet.mq_max_pairs/hw.vtnet.X.mq_max_pairsβ This tunable sets the maximum number of transmit and receive queue pairs. Multiple queues are only supported when the Multiqueue feature is negotiated. This driver supports a maximum of 8 queue pairs. The number of queue pairs used is the lesser of the maximum supported by the driver and the hypervisor, the number of CPUs present in the guest, and this tunable if not zero. The default value is0.hw.vtnet.tso_maxlen/hw.vtnet.X.tso_maxlenβ This tunable sets the TSO burst limit. The default value is65535.hw.vtnet.rx_process_limit/hw.vtnet.X.rx_process_limitβ This tunable sets the number of RX segments processed in one pass. The default value is1024.hw.vtnet.lro_entry_count/hw.vtnet.X.lro_entry_countβ This tunable sets the software TCP LRO entry count. The default value is128, the minimum value is8.hw.vtnet.lro_mbufq_depth/hw.vtnet.X.lro_mbufq_depthβ This tunable sets the depth of the software TCP LRO mbuf queue. The default value is0.hw.vtnet.altq_disableβ This tunable disables ALTQ support, allowing the use of multiqueue instead. This option applies to all interfaces. The default value is0. (Note: this one has nohw.vtnet.X.version, just so you know. π§)
πΊ TRANSMIT QUEUE STATISTICS πΊ
For each transmit queue of each interface, the following read-only statistics are provided. Get your screenshot finger ready because these are all facts:
dev.vtnet.X.txqY.rescheduledβ The number of times the transmit interrupt handler was rescheduled.dev.vtnet.X.txqY.tsoβ The number of times TCP segment offloading was performed.dev.vtnet.X.txqY.csumβ The number of times transmit checksum offloading for UDP or TCP was performed.dev.vtnet.X.txqY.omcastsβ The number of multicast packets that were transmitted.dev.vtnet.X.txqY.obytesβ The number of bytes that were transmitted (based on Ethernet frames).dev.vtnet.X.txqY.opacketsβ The number of packets that were transmitted (Ethernet frames).
π RECEIVE QUEUE STATISTICS π
Same energy but for receive queues. For each receive queue of each interface, the following read-only statistics are provided:
dev.vtnet.X.rxqY.rescheduledβ The number of times the receive interrupt handler was rescheduled.dev.vtnet.X.rxqY.host_lroβ The number of times TCP large receive offload was performed.dev.vtnet.X.rxqY.csum_failedβ The number of times a packet with a request for receive or transmit checksum offloading was received and this request failed. The different reasons for the failure are counted bydev.vtnet.X.rx_csum_inaccessible_ipproto,dev.vtnet.X.rx_csum_bad_ipproto,dev.vtnet.X.rx_csum_bad_ethtype, anddev.vtnet.X.rx_csum_bad_offset.dev.vtnet.X.rxqY.csumβ The number of times receive checksum offloading for UDP or TCP was performed.dev.vtnet.X.rxqY.ierrorsβ The number of times an error occurred during input processing.dev.vtnet.X.rxqY.iqdropsβ The number of times a packet was dropped during input processing.dev.vtnet.X.rxqY.ibytesβ The number of bytes that were received (based on Ethernet frames).dev.vtnet.X.rxqY.ipacketsβ The number of packets that were received (Ethernet frames).
π¦ INTERFACE TRANSMIT STATISTICS π¦
Now we're zooming out to the whole interface. For each interface, the following read-only transmit statistics are provided:
dev.vtnet.X.tx_task_rescheduledβ The sum ofdev.vtnet.X.txqY.rescheduledover all transmit queues of the interface.dev.vtnet.X.tx_tso_offloadedβ The sum ofdev.vtnet.X.txqY.tsoover all transmit queues of the interface.dev.vtnet.X.tx_csum_offloadedβ The sum ofdev.vtnet.X.txqY.csumover all transmit queues of the interface.dev.vtnet.X.tx_defrag_failedβ The number of times an attempt to defragment an mbuf chain failed during a transmit operation.dev.vtnet.X.tx_defraggedβ The number of times an mbuf chain was defragmented during a transmit operation.dev.vtnet.X.tx_tso_without_csumβ The number of times TCP segment offloading was attempted without transmit checksum offloading.dev.vtnet.X.tx_tso_not_tcpβ The number of times TCP segment offloading was attempted for a non-TCP packet.dev.vtnet.X.tx_csum_proto_mismatchβ The number of times the IP protocol version of the transmit checksum offloading request did not match the IP protocol version of the packet.dev.vtnet.X.tx_csum_unknown_ethtypeβ The number of times a transmit offload operation was requested for an ethernet frame for which the EtherType was neither IPv4 nor IPv6 (considering simple VLAN tagging).
π INTERFACE RECEIVE STATISTICS π
And now the receive side, same deal. For each interface, the following read-only receive statistics are provided:
dev.vtnet.X.rx_task_rescheduledβ The sum ofdev.vtnet.X.rxqY.rescheduledover all receive queues of the interface.dev.vtnet.X.rx_csum_offloadedβ The sum ofdev.vtnet.X.rxqY.csumover all receive queues of the interface.dev.vtnet.X.rx_csum_failedβ The sum ofdev.vtnet.X.rxqY.csum_failedover all receive queues of the interface.dev.vtnet.X.rx_csum_inaccessible_ipprotoβ The number of times a packet with a request for receive or transmit checksum offloading was received where the IP protocol was not accessible.dev.vtnet.X.rx_csum_bad_offsetβ The number of times fixing the checksum required byhw.vtnet.fixup_needs_csumorhw.vtnet.X.fixup_needs_csumwas attempted for a packet where the csum is not located in the first mbuf.dev.vtnet.X.rx_csum_bad_ipprotoβ The number of times a packet with a request for receive or transmit checksum offloading was received where the IP protocol was neither TCP nor UDP.dev.vtnet.X.rx_csum_bad_ethtypeβ The number of times a packet with a request for receive or transmit checksum offloading was received where the EtherType was neither IPv4 nor IPv6.dev.vtnet.X.rx_mergeable_failedβ The number of times receiving a mergable buffer failed.dev.vtnet.X.rx_enq_replacement_failedβ The number of times the enqueuing the replacement receive mbuf chain failed.dev.vtnet.X.rx_frame_too_largeβ The number of times the frame was loger than the mbuf chain during large receive offload without mergeable buffers. (Yes, "loger" is in the original, I'm not fixing it, it's iconic. π)dev.vtnet.X.mbuf_alloc_failedβ The number of times an mbuf cluster allocation for the receive buffer failed.
Lowkey that "loger" typo is giving "the original author was tired" and I respect it. π«Ά
π INTERFACE CONFIGURATION PARAMETER π
For each interface, the following read-only configuration parameters are provided. These are the big-picture vibes:
dev.vtnet.X.act_vq_pairsβ The number of active virtqueue pairs.dev.vtnet.X.req_vq_pairsβ The number of requested virtqueue pairs.dev.vtnet.X.max_vq_pairsβ The maximum number of supported virtqueue pairs.dev.vtnet.X.flagsβ The flags of the interface. Mostly for debugging purposes.dev.vtnet.X.featuresβ The features of the interface as defined by the virtio specification.
π SEE ALSO π
You already know, but here's where to go next, no cap:
arp(4), netintro(4), ng_ether(4), virtio(4), vlan(4), ifconfig(8)
β HISTORY β
The vtnet driver was written by Bryan Venteicher <bryanv@FreeBSD.org>. It first appeared in FreeBSD 9.0. Iconic behavior. π
π CAVEATS π
Only one big warning here but it matters: the vtnet driver only supports LRO when the hypervisor advertises the mergeable buffer feature. That's it. That's the caveat. Don't forget it. π
And that's the whole page, bestie. This masterpiece of a man page is from the VTNET(4) kernel interfaces manual, dated December 19, 2025, on Debian. Go forth and configure your virtual ethernet with confidence. You got this. πβ¨π¦
π¦ where this page comes from
- freebsd 15.1: base 15.1
- Copyright (c) 2011 Bryan Venteicher
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms