<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Virtio on inetshell</title><link>https://inet.sh/en/tags/virtio/</link><description>Recent content in Virtio on inetshell</description><generator>Hugo</generator><language>en</language><lastBuildDate>Fri, 25 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://inet.sh/en/tags/virtio/index.xml" rel="self" type="application/rss+xml"/><item><title>Virtualized pfSense with VirtIO: no traffic until hardware checksum offload is disabled</title><link>https://inet.sh/en/posts/pfsense/virtio-disable-hardware-checksum-offload/</link><pubDate>Fri, 25 Sep 2026 00:00:00 +0000</pubDate><guid>https://inet.sh/en/posts/pfsense/virtio-disable-hardware-checksum-offload/</guid><description>pfSense or OPNsense on Proxmox, KVM or bhyve with VirtIO NICs (vtnet): the firewall boots but passes no traffic, or hosts behind it cannot be reached from the hypervisor and other VMs. It is vtnet checksum offload on FreeBSD. System &amp;gt; Advanced &amp;gt; Networking &amp;gt; Disable hardware checksum offload and a mandatory reboot.</description><content:encoded><![CDATA[<h2 id="tldr">TL;DR</h2>
<p><strong>System → Advanced → Networking → Disable hardware checksum offload</strong> ✔ → <strong>Save</strong> → <strong>reboot the VM</strong>. The GUI does not say so, but the change does not apply to <code>vtnet</code> interfaces until the reboot.</p>
<p>To test without rebooting (lost at boot):</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">ifconfig vtnet0 -rxcsum -txcsum -tso -lro
</span></span><span class="line"><span class="cl">ifconfig vtnet1 -rxcsum -txcsum -tso -lro
</span></span></code></pre></td></tr></table>
</div>
</div><p>On OPNsense: <strong>Interfaces → Settings → Hardware CRC → Disable hardware checksum offload</strong>, and the same reboot.</p>
<h2 id="symptoms">Symptoms</h2>
<p>The VM boots, the interfaces are <code>UP</code>, LAN DHCP hands out addresses, and still:</p>
<ul>
<li>Hosts behind the firewall cannot reach the Internet, or connections stall halfway (ping passes, TCP hangs).</li>
<li>From the virtualization host itself or from other VMs on the same host nothing protected by pfSense is reachable, not even the GUI.</li>
<li>Switching the VM&rsquo;s NIC to <code>e1000</code> fixes it on the spot, which confirms the diagnosis.</li>
</ul>
<h2 id="why-it-happens">Why it happens</h2>
<p>FreeBSD&rsquo;s <code>vtnet</code> driver, with checksum offload enabled, hands the network stack packets whose checksum never got computed: between VMs on the same host, and between the host and the VM, traffic never crosses a physical NIC that would do it. FreeBSD sees invalid checksums and drops them (FreeBSD bug 165059). Netgate documents it under <a href="https://docs.netgate.com/pfsense/en/latest/virtualization/virtio-driver-support.html">VirtIO Driver Support</a>.</p>
<p>pfSense tries to tick the option only when it detects <code>vtnet</code> interfaces <strong>at install time</strong>. If the VirtIO NIC was added later, if you restored the <code>config.xml</code> from a physical firewall, or if you migrated the VM from another hypervisor with a different NIC type, the option stays off.</p>
<h2 id="procedure">Procedure</h2>
<ol>
<li>
<p><strong>System → Advanced → Networking</strong>, <em>Network Interfaces</em> section:</p>
<ul>
<li><strong>Disable hardware checksum offload</strong>: tick it.</li>
<li><strong>Disable hardware TCP segmentation offload</strong> and <strong>Disable hardware large receive offload</strong>: already ticked by default; leave them.</li>
</ul>
</li>
<li>
<p><strong>Save</strong>.</p>
</li>
<li>
<p><strong>Reboot</strong> from Diagnostics → Reboot. Without this step nothing changes on <code>vtnet</code>.</p>
</li>
<li>
<p>Check:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">ifconfig vtnet0 <span class="p">|</span> grep options
</span></span></code></pre></td></tr></table>
</div>
</div><p>Neither <code>RXCSUM</code> nor <code>TXCSUM</code> (nor <code>TSO4</code>, <code>LRO</code>) should show up.</p>
</li>
</ol>
<h2 id="if-it-is-still-the-same">If it is still the same</h2>
<ul>
<li><strong>All of the VM&rsquo;s NICs must be the same kind.</strong> A <code>vtnet</code> with offload and an <code>e1000</code> behave differently; check every <code>ifconfig</code>.</li>
<li><strong>Offload on the host.</strong> Netgate notes that sometimes checksums and TSO must also be turned off on the hypervisor. On Proxmox/KVM, on the VM&rsquo;s <code>tap</code> interface: <code>ethtool -K tap100i0 tx off</code> (the number is the VMID and <code>i0</code> the NIC). Rarely needed; try it last.</li>
<li><strong>Plan B</strong>: <code>e1000</code> NIC model on the VM. Less throughput than VirtIO without offload, but none of this bug.</li>
</ul>
<h2 id="traps">Traps</h2>
<ul>
<li><strong>The reboot is not optional</strong> and the GUI does not ask for it. It is the number one cause of &ldquo;I ticked it and it still does not work&rdquo;.</li>
<li><strong>It is not a rules problem.</strong> With offload on, packets are dropped before reaching <code>pf</code>; the firewall log shows nothing.</li>
<li><strong><code>e1000</code> on OPNsense too</strong> as plan B; the equivalent setting lives under <em>Interfaces → Settings</em>.</li>
<li><strong>Multiqueue</strong> (<code>queues=N</code> on Proxmox) works fine with <code>vtnet</code> once offload is off; do not mistake it for the cause.</li>
</ul>
]]></content:encoded></item></channel></rss>