Long long ago (commit fd5b15ff in July 2010), we determined that the
combination of virtio-net + vhost packet handling (i.e. handling
packets in the kernel rather than userspace) + very old guest OSes
(e.g. RHEL5, but not even RHEL6) would result in the checksum of dhcp
packets being unset, which would cause the packet to be dropped, and
the guest would never acquire an IP address. The fix for this was for
iptables to create a new rule that would fixup packet checksums for
certain packets, and for libvirt to add one of these rules to the
iptables "mangle" table.
This was considered a horrid hack even at the time, and when nftables
was created, the functionality wasn't replicated there. So when we add
rules using nftables, there is no way to add such a rule, and your
options are thus:
1) stop using outdated, out of support guest OSes
2) Don't use vhost=on for the guest virtio interface, ie. add
<driver name='qemu'/> to the <interface> definition.
3) continue having libvirt use iptables for its rules (I'm not
certain, but I think even this may fail depending on which iptables
compatability packages are being used).
All of this is to explain why we simply ignore calls to add a
"checksum fixup" rule when the firewall backend isn't iptables.
I could have plumbed this function all the way through virNetfilter*
-> virNftables* and then done an empty return from there, but figured
since it is a hack I'd rather keep it as localized as possible, and
just cut it off right at the top of the call chain in the network
driver.
P.S. This specific behavior is really the only concrete reason for
keeping around an iptables backend, rather than just replacing it with
nftables.
Signed-off-by: Laine Stump <laine(a)redhat.com>
---
src/network/bridge_driver_linux.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_linux.c
index ff2f87054d..3efb669789 100644
--- a/src/network/bridge_driver_linux.c
+++ b/src/network/bridge_driver_linux.c
@@ -721,6 +721,15 @@ networkAddChecksumFirewallRules(virFirewall *fw,
size_t i;
virNetworkIPDef *ipv4def;
+ /* these rules are only supported by the iptables
+ * backend. nftables doesn't have equivalent functionality,
+ * because it was always seen as an ugly hack. Fortunately this
+ * hack was only ever needed for *very* old guest OSes (RHEL5 era)
+ * using virtio network device with vhost enabled.
+ */
+ if (virFirewallGetBackend(fw) != VIR_FIREWALL_BACKEND_IPTABLES)
+ return;
+
/* First look for first IPv4 address that has dhcp or tftpboot defined. */
/* We support dhcp config on 1 IPv4 interface only. */
for (i = 0;
@@ -747,6 +756,10 @@ networkRemoveChecksumFirewallRules(virFirewall *fw,
size_t i;
virNetworkIPDef *ipv4def;
+ /* iptables backend only */
+ if (virFirewallGetBackend(fw) != VIR_FIREWALL_BACKEND_IPTABLES)
+ return;
+
/* First look for first IPv4 address that has dhcp or tftpboot defined. */
/* We support dhcp config on 1 IPv4 interface only. */
for (i = 0;
--
2.39.2