Many of the functions in virnetfilter.c are nearly identical to one or more other functions (e.g. they just call the same iptables function, but with INSERT|DELETE action). Rather than adding a switch(backend) into all 24 of these functions, make small wrappers for the 10 iptables* functions that those 24 call, and put switch(backend) in *those* functions. This is more work now, but will make shorter work of adding in nftables backend support. (To be truthful, I've gotten this far basically ignoring the details of the plethora of functions in the viriptables.c API, just faithfully tooling it around while keeping the callers unchanged (aside from the function renaming back at the beginning of the series). I'm now thinking maybe the original API should be simplified, and the callers (i.e. the network driver) modified to use that simplified API instead. But I've gotten this far so I might as well demonstrate working patches and ask for opinions rather than throwing away multiple patches and dealing with associated local merge/rebase conflicts due to changing patches early in the series for possibly no reason.) Signed-off-by: Laine Stump <laine@xxxxxxxxxx> --- po/POTFILES | 1 + src/util/virfirewall.c | 14 +- src/util/virnetfilter.c | 320 +++++++++++++++++++++++++++++++++++----- 3 files changed, 293 insertions(+), 42 deletions(-) diff --git a/po/POTFILES b/po/POTFILES index b122f02818..d20ac36062 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -302,6 +302,7 @@ src/util/virnetdevopenvswitch.c src/util/virnetdevtap.c src/util/virnetdevveth.c src/util/virnetdevvportprofile.c +src/util/virnetfilter.c src/util/virnetlink.c src/util/virnodesuspend.c src/util/virnuma.c diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c index e1fda162c4..fa21266fb2 100644 --- a/src/util/virfirewall.c +++ b/src/util/virfirewall.c @@ -99,7 +99,19 @@ virFirewallGroupNew(void) */ virFirewall *virFirewallNew(virFirewallBackend backend) { - virFirewall *firewall = g_new0(virFirewall, 1); + virFirewall *firewall = NULL; + + /* If we arrive here and backend is _UNSET, then either there is a + * bug in our code, or we couldn't find the necessary binaries for + * a working backend (e.g. no iptables of nft binary). + */ + if (backend == VIR_FIREWALL_BACKEND_UNSET) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("firewall_backend wasn't set, and no usable setting could be auto-detected")); + return NULL; + } + + firewall = g_new0(virFirewall, 1); firewall->backend = backend; return firewall; diff --git a/src/util/virnetfilter.c b/src/util/virnetfilter.c index f0fa0d5cd2..e6a748e877 100644 --- a/src/util/virnetfilter.c +++ b/src/util/virnetfilter.c @@ -44,6 +44,18 @@ VIR_LOG_INIT("util.netfilter"); #define VIR_FROM_THIS VIR_FROM_NONE +static void +virNetFilterBackendUnsetError(void) +{ + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("firewall_backend wasn't set, and no usable setting could be auto-detected")); +} + + +/* All functions with a switch checking virFirewallGetBackend(fw) will + * need a case in the switch for each backend. + */ + /** * virNetfilterApplyFirewallRule: * @fw: the virFirewall this rule is part of (currently unused) @@ -59,7 +71,16 @@ virNetfilterApplyFirewallRule(virFirewall *fw, virFirewallRule *rule, char **output) { - return virIptablesApplyFirewallRule(fw, rule, output); + switch (virFirewallGetBackend(fw)) { + case VIR_FIREWALL_BACKEND_IPTABLES: + return virIptablesApplyFirewallRule(fw, rule, output); + + case VIR_FIREWALL_BACKEND_UNSET: + case VIR_FIREWALL_BACKEND_LAST: + virNetFilterBackendUnsetError(); + return -1; + } + return 0; } @@ -73,12 +94,228 @@ virNetfilterApplyFirewallRule(virFirewall *fw, * */ int -virNetfilterSetupPrivateChains(virFirewallBackend backend G_GNUC_UNUSED, +virNetfilterSetupPrivateChains(virFirewallBackend backend, virFirewallLayer layer) { - return iptablesSetupPrivateChains(layer); + switch (backend) { + case VIR_FIREWALL_BACKEND_IPTABLES: + return iptablesSetupPrivateChains(layer); + + case VIR_FIREWALL_BACKEND_UNSET: + case VIR_FIREWALL_BACKEND_LAST: + virNetFilterBackendUnsetError(); + return -1; + } + return 0; +} + + +static void +virNetfilterInput(virFirewall *fw, + virFirewallLayer layer, + const char *iface, + int port, + virFirewallAction action, + int tcp) +{ + switch (virFirewallGetBackend(fw)) { + case VIR_FIREWALL_BACKEND_IPTABLES: + iptablesInput(fw, layer, iface, port, action, tcp); + break; + + case VIR_FIREWALL_BACKEND_UNSET: + case VIR_FIREWALL_BACKEND_LAST: + break; + } +} + + +static void +virNetfilterOutput(virFirewall *fw, + virFirewallLayer layer, + const char *iface, + int port, + virFirewallAction action, + int tcp) +{ + switch (virFirewallGetBackend(fw)) { + case VIR_FIREWALL_BACKEND_IPTABLES: + iptablesOutput(fw, layer, iface, port, action, tcp); + break; + + case VIR_FIREWALL_BACKEND_UNSET: + case VIR_FIREWALL_BACKEND_LAST: + break; + } +} + + +static int +virNetfilterForwardAllowOut(virFirewall *fw, + virSocketAddr *netaddr, + unsigned int prefix, + const char *iface, + const char *physdev, + virFirewallAction action) +{ + switch (virFirewallGetBackend(fw)) { + case VIR_FIREWALL_BACKEND_IPTABLES: + return iptablesForwardAllowOut(fw, netaddr, prefix, + iface, physdev, action); + + case VIR_FIREWALL_BACKEND_UNSET: + case VIR_FIREWALL_BACKEND_LAST: + virNetFilterBackendUnsetError(); + return -1; + } + return 0; +} + + +static int +virNetfilterForwardAllowRelatedIn(virFirewall *fw, + virSocketAddr *netaddr, + unsigned int prefix, + const char *iface, + const char *physdev, + virFirewallAction action) +{ + switch (virFirewallGetBackend(fw)) { + case VIR_FIREWALL_BACKEND_IPTABLES: + return iptablesForwardAllowRelatedIn(fw, netaddr, prefix, + iface, physdev, action); + + case VIR_FIREWALL_BACKEND_UNSET: + case VIR_FIREWALL_BACKEND_LAST: + virNetFilterBackendUnsetError(); + return -1; + } + return 0; } + +static int +virNetfilterForwardAllowIn(virFirewall *fw, + virSocketAddr *netaddr, + unsigned int prefix, + const char *iface, + const char *physdev, + virFirewallAction action) +{ + switch (virFirewallGetBackend(fw)) { + case VIR_FIREWALL_BACKEND_IPTABLES: + return iptablesForwardAllowIn(fw, netaddr, prefix, + iface, physdev, action); + + case VIR_FIREWALL_BACKEND_UNSET: + case VIR_FIREWALL_BACKEND_LAST: + virNetFilterBackendUnsetError(); + return -1; + } + return 0; +} + + +static void +virNetfilterForwardAllowCross(virFirewall *fw, + virFirewallLayer layer, + const char *iface, + virFirewallAction action) +{ + switch (virFirewallGetBackend(fw)) { + case VIR_FIREWALL_BACKEND_IPTABLES: + iptablesForwardAllowCross(fw, layer, iface, action); + break; + + case VIR_FIREWALL_BACKEND_UNSET: + case VIR_FIREWALL_BACKEND_LAST: + break; + } +} + + +static void +virNetfilterForwardRejectOut(virFirewall *fw, + virFirewallLayer layer, + const char *iface, + virFirewallAction action) +{ + switch (virFirewallGetBackend(fw)) { + case VIR_FIREWALL_BACKEND_IPTABLES: + iptablesForwardRejectOut(fw, layer, iface, action); + break; + + case VIR_FIREWALL_BACKEND_UNSET: + case VIR_FIREWALL_BACKEND_LAST: + break; + } +} + + +static void +virNetfilterForwardRejectIn(virFirewall *fw, + virFirewallLayer layer, + const char *iface, + virFirewallAction action) +{ + switch (virFirewallGetBackend(fw)) { + case VIR_FIREWALL_BACKEND_IPTABLES: + iptablesForwardRejectIn(fw, layer, iface, action); + break; + + case VIR_FIREWALL_BACKEND_UNSET: + case VIR_FIREWALL_BACKEND_LAST: + break; + } +} + + +static int +virNetfilterForwardMasquerade(virFirewall *fw, + virSocketAddr *netaddr, + unsigned int prefix, + const char *physdev, + virSocketAddrRange *addr, + virPortRange *port, + const char *protocol, + virFirewallAction action) +{ + switch (virFirewallGetBackend(fw)) { + case VIR_FIREWALL_BACKEND_IPTABLES: + return iptablesForwardMasquerade(fw, netaddr, prefix, physdev, + addr, port, protocol, action); + + case VIR_FIREWALL_BACKEND_UNSET: + case VIR_FIREWALL_BACKEND_LAST: + virNetFilterBackendUnsetError(); + return -1; + } + return 0; +} + + +static int +virNetfilterForwardDontMasquerade(virFirewall *fw, + virSocketAddr *netaddr, + unsigned int prefix, + const char *physdev, + const char *destaddr, + virFirewallAction action) +{ + switch (virFirewallGetBackend(fw)) { + case VIR_FIREWALL_BACKEND_IPTABLES: + return iptablesForwardDontMasquerade(fw, netaddr, prefix, + physdev, destaddr, action); + + case VIR_FIREWALL_BACKEND_UNSET: + case VIR_FIREWALL_BACKEND_LAST: + virNetFilterBackendUnsetError(); + return -1; + } + return 0; +} + + /** * virNetfilterAddTcpInput: * @ctx: pointer to the IP table context @@ -94,7 +331,7 @@ virNetfilterAddTcpInput(virFirewall *fw, const char *iface, int port) { - iptablesInput(fw, layer, iface, port, VIR_FIREWALL_ACTION_INSERT, 1); + virNetfilterInput(fw, layer, iface, port, VIR_FIREWALL_ACTION_INSERT, 1); } @@ -113,7 +350,7 @@ virNetfilterRemoveTcpInput(virFirewall *fw, const char *iface, int port) { - iptablesInput(fw, layer, iface, port, VIR_FIREWALL_ACTION_DELETE, 1); + virNetfilterInput(fw, layer, iface, port, VIR_FIREWALL_ACTION_DELETE, 1); } @@ -132,7 +369,7 @@ virNetfilterAddUdpInput(virFirewall *fw, const char *iface, int port) { - iptablesInput(fw, layer, iface, port, VIR_FIREWALL_ACTION_INSERT, 0); + virNetfilterInput(fw, layer, iface, port, VIR_FIREWALL_ACTION_INSERT, 0); } @@ -151,7 +388,7 @@ virNetfilterRemoveUdpInput(virFirewall *fw, const char *iface, int port) { - iptablesInput(fw, layer, iface, port, VIR_FIREWALL_ACTION_DELETE, 0); + virNetfilterInput(fw, layer, iface, port, VIR_FIREWALL_ACTION_DELETE, 0); } @@ -170,7 +407,7 @@ virNetfilterAddTcpOutput(virFirewall *fw, const char *iface, int port) { - iptablesOutput(fw, layer, iface, port, VIR_FIREWALL_ACTION_INSERT, 1); + virNetfilterOutput(fw, layer, iface, port, VIR_FIREWALL_ACTION_INSERT, 1); } @@ -189,7 +426,7 @@ virNetfilterRemoveTcpOutput(virFirewall *fw, const char *iface, int port) { - iptablesOutput(fw, layer, iface, port, VIR_FIREWALL_ACTION_DELETE, 1); + virNetfilterOutput(fw, layer, iface, port, VIR_FIREWALL_ACTION_DELETE, 1); } @@ -208,7 +445,7 @@ virNetfilterAddUdpOutput(virFirewall *fw, const char *iface, int port) { - iptablesOutput(fw, layer, iface, port, VIR_FIREWALL_ACTION_INSERT, 0); + virNetfilterOutput(fw, layer, iface, port, VIR_FIREWALL_ACTION_INSERT, 0); } @@ -227,7 +464,7 @@ virNetfilterRemoveUdpOutput(virFirewall *fw, const char *iface, int port) { - iptablesOutput(fw, layer, iface, port, VIR_FIREWALL_ACTION_DELETE, 0); + virNetfilterOutput(fw, layer, iface, port, VIR_FIREWALL_ACTION_DELETE, 0); } @@ -251,8 +488,8 @@ virNetfilterAddForwardAllowOut(virFirewall *fw, const char *iface, const char *physdev) { - return iptablesForwardAllowOut(fw, netaddr, prefix, iface, physdev, - VIR_FIREWALL_ACTION_INSERT); + return virNetfilterForwardAllowOut(fw, netaddr, prefix, iface, physdev, + VIR_FIREWALL_ACTION_INSERT); } @@ -276,8 +513,8 @@ virNetfilterRemoveForwardAllowOut(virFirewall *fw, const char *iface, const char *physdev) { - return iptablesForwardAllowOut(fw, netaddr, prefix, iface, physdev, - VIR_FIREWALL_ACTION_DELETE); + return virNetfilterForwardAllowOut(fw, netaddr, prefix, iface, physdev, + VIR_FIREWALL_ACTION_DELETE); } @@ -301,8 +538,8 @@ virNetfilterAddForwardAllowRelatedIn(virFirewall *fw, const char *iface, const char *physdev) { - return iptablesForwardAllowRelatedIn(fw, netaddr, prefix, iface, physdev, - VIR_FIREWALL_ACTION_INSERT); + return virNetfilterForwardAllowRelatedIn(fw, netaddr, prefix, iface, physdev, + VIR_FIREWALL_ACTION_INSERT); } @@ -326,8 +563,8 @@ virNetfilterRemoveForwardAllowRelatedIn(virFirewall *fw, const char *iface, const char *physdev) { - return iptablesForwardAllowRelatedIn(fw, netaddr, prefix, iface, physdev, - VIR_FIREWALL_ACTION_DELETE); + return virNetfilterForwardAllowRelatedIn(fw, netaddr, prefix, iface, physdev, + VIR_FIREWALL_ACTION_DELETE); } @@ -351,8 +588,8 @@ virNetfilterAddForwardAllowIn(virFirewall *fw, const char *iface, const char *physdev) { - return iptablesForwardAllowIn(fw, netaddr, prefix, iface, physdev, - VIR_FIREWALL_ACTION_INSERT); + return virNetfilterForwardAllowIn(fw, netaddr, prefix, iface, physdev, + VIR_FIREWALL_ACTION_INSERT); } @@ -376,8 +613,8 @@ virNetfilterRemoveForwardAllowIn(virFirewall *fw, const char *iface, const char *physdev) { - return iptablesForwardAllowIn(fw, netaddr, prefix, iface, physdev, - VIR_FIREWALL_ACTION_DELETE); + return virNetfilterForwardAllowIn(fw, netaddr, prefix, iface, physdev, + VIR_FIREWALL_ACTION_DELETE); } @@ -397,7 +634,7 @@ virNetfilterAddForwardAllowCross(virFirewall *fw, virFirewallLayer layer, const char *iface) { - iptablesForwardAllowCross(fw, layer, iface, VIR_FIREWALL_ACTION_INSERT); + virNetfilterForwardAllowCross(fw, layer, iface, VIR_FIREWALL_ACTION_INSERT); } @@ -417,7 +654,7 @@ virNetfilterRemoveForwardAllowCross(virFirewall *fw, virFirewallLayer layer, const char *iface) { - iptablesForwardAllowCross(fw, layer, iface, VIR_FIREWALL_ACTION_DELETE); + virNetfilterForwardAllowCross(fw, layer, iface, VIR_FIREWALL_ACTION_DELETE); } @@ -436,9 +673,10 @@ virNetfilterAddForwardRejectOut(virFirewall *fw, virFirewallLayer layer, const char *iface) { - iptablesForwardRejectOut(fw, layer, iface, VIR_FIREWALL_ACTION_INSERT); + virNetfilterForwardRejectOut(fw, layer, iface, VIR_FIREWALL_ACTION_INSERT); } + /** * virNetfilterRemoveForwardRejectOut: * @ctx: pointer to the IP table context @@ -454,7 +692,7 @@ virNetfilterRemoveForwardRejectOut(virFirewall *fw, virFirewallLayer layer, const char *iface) { - iptablesForwardRejectOut(fw, layer, iface, VIR_FIREWALL_ACTION_DELETE); + virNetfilterForwardRejectOut(fw, layer, iface, VIR_FIREWALL_ACTION_DELETE); } @@ -473,7 +711,7 @@ virNetfilterAddForwardRejectIn(virFirewall *fw, virFirewallLayer layer, const char *iface) { - iptablesForwardRejectIn(fw, layer, iface, VIR_FIREWALL_ACTION_INSERT); + virNetfilterForwardRejectIn(fw, layer, iface, VIR_FIREWALL_ACTION_INSERT); } @@ -492,7 +730,7 @@ virNetfilterRemoveForwardRejectIn(virFirewall *fw, virFirewallLayer layer, const char *iface) { - iptablesForwardRejectIn(fw, layer, iface, VIR_FIREWALL_ACTION_DELETE); + virNetfilterForwardRejectIn(fw, layer, iface, VIR_FIREWALL_ACTION_DELETE); } @@ -518,9 +756,9 @@ virNetfilterAddForwardMasquerade(virFirewall *fw, virPortRange *port, const char *protocol) { - return iptablesForwardMasquerade(fw, netaddr, prefix, - physdev, addr, port, protocol, - VIR_FIREWALL_ACTION_INSERT); + return virNetfilterForwardMasquerade(fw, netaddr, prefix, + physdev, addr, port, protocol, + VIR_FIREWALL_ACTION_INSERT); } @@ -546,9 +784,9 @@ virNetfilterRemoveForwardMasquerade(virFirewall *fw, virPortRange *port, const char *protocol) { - return iptablesForwardMasquerade(fw, netaddr, prefix, - physdev, addr, port, protocol, - VIR_FIREWALL_ACTION_DELETE); + return virNetfilterForwardMasquerade(fw, netaddr, prefix, + physdev, addr, port, protocol, + VIR_FIREWALL_ACTION_DELETE); } @@ -573,9 +811,9 @@ virNetfilterAddDontMasquerade(virFirewall *fw, const char *physdev, const char *destaddr) { - return iptablesForwardDontMasquerade(fw, netaddr, prefix, - physdev, destaddr, - VIR_FIREWALL_ACTION_INSERT); + return virNetfilterForwardDontMasquerade(fw, netaddr, prefix, + physdev, destaddr, + VIR_FIREWALL_ACTION_INSERT); } @@ -600,7 +838,7 @@ virNetfilterRemoveDontMasquerade(virFirewall *fw, const char *physdev, const char *destaddr) { - return iptablesForwardDontMasquerade(fw, netaddr, prefix, - physdev, destaddr, - VIR_FIREWALL_ACTION_DELETE); + return virNetfilterForwardDontMasquerade(fw, netaddr, prefix, + physdev, destaddr, + VIR_FIREWALL_ACTION_DELETE); } -- 2.39.2