
On 12/3/18 10:07 AM, Laine Stump wrote:
On 11/1/18 8:52 AM, Daniel P. Berrangé wrote:
Historically rules were added straight into the base chains. This works but it is inflexible for admins adding extra rules via hook scripts, and it is not clear which rules are libvirt created.
There is a further complexity with the FORWARD chain where a specific ordering of rules is needed to ensure traffic is matched correctly. This would require complex interleaving of rules instead of plain appending. By splitting the FORWARD chain into three chains management will be simpler. Thus we create
INPUT -> INP_libvirt OUTPUT -> OUT_libvirt FORWARD -> FWD_libvirt_cross FORWARD -> FWD_libvirt_in FORWARD -> FWD_libvirt_out POSTROUTING -> PRT_libvirt
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/libvirt_private.syms | 1 + src/util/viriptables.c | 81 ++++++++++++++++++++++++++++++++++++++++ src/util/viriptables.h | 2 + 3 files changed, 84 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 335210c31d..e42c946de6 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2062,6 +2062,7 @@ iptablesRemoveOutputFixUdpChecksum; iptablesRemoveTcpInput; iptablesRemoveUdpInput; iptablesRemoveUdpOutput; +iptablesSetupPrivateChains;
# util/viriscsi.h diff --git a/src/util/viriptables.c b/src/util/viriptables.c index f379844d28..4a7ea54b38 100644 --- a/src/util/viriptables.c +++ b/src/util/viriptables.c @@ -51,6 +51,87 @@ enum { };
+ +typedef struct { + virFirewallLayer layer; + const char *table; + const char *parent; + const char *child; +} iptablesChain; + +static int +iptablesCheckPrivateChain(virFirewallPtr fw, + const char *const *lines, + void *opaque) +{ + iptablesChain *data = opaque; + bool found = false; + + while (lines && *lines && !found) { + if (STRPREFIX(*lines, data->child)) + found = true; + lines++; + } + + if (!found) + virFirewallAddRule(fw, data->layer, + "--table", data->table, + "--insert", data->parent, + "--jump", data->child, NULL); + + return 0; +} + + +int +iptablesSetupPrivateChains(void) +{ + virFirewallPtr fw; + int ret = -1; + iptablesChain chains[] = { + {VIR_FIREWALL_LAYER_IPV4, "filter", "INPUT", "INP_libvirt"}, + {VIR_FIREWALL_LAYER_IPV4, "filter", "OUTPUT", "OUT_libvirt"}, + {VIR_FIREWALL_LAYER_IPV4, "filter", "FORWARD", "FWD_libvirt_out"}, + {VIR_FIREWALL_LAYER_IPV4, "filter", "FORWARD", "FWD_libvirt_in"}, + {VIR_FIREWALL_LAYER_IPV4, "filter", "FORWARD", "FWD_libvirt_cross"}, + {VIR_FIREWALL_LAYER_IPV4, "nat", "POSTROUTING", "PRT_libvirt"},
You also need this entry (for the rule that fixes the UDP checksum of dhcp packets): + {VIR_FIREWALL_LAYER_IPV4, "mangle", "POSTROUTING", "PRT_libvirt"}, (that is, unless we think it's okay to do away with that rule. It was originally added because of some strange combination of virtio+vhost+[old OS, e.g. RHEL5] getting dhcp requests with incorrect checksums on the host. See https://bugzilla.redhat.com/show_bug.cgi?id=612588 for more info (although it's difficult since the Bug description is marked as Private :-( )