mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
util: new virFirewallD APIs + docs
virFirewallDGetBackend() reports whether firewalld is currently using an iptables or an nftables backend. virFirewallDGetVersion() learns the version of the firewalld running on this system and returns it as 1000000*major + 1000*minor + micro. virFirewallDGetZones() gets a list of all currently active firewalld zones. virFirewallDInterfaceSetZone() sets the firewalld zone of the given interface. virFirewallDZoneExists() can be used to learn whether or not a particular zone is present and active in firewalld. Signed-off-by: Laine Stump <laine@laine.org> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
d8393b56e2
commit
3bba4825c2
@ -1920,7 +1920,12 @@ virFirewallStartTransaction;
|
|||||||
|
|
||||||
# util/virfirewalld.h
|
# util/virfirewalld.h
|
||||||
virFirewallDApplyRule;
|
virFirewallDApplyRule;
|
||||||
|
virFirewallDGetBackend;
|
||||||
|
virFirewallDGetVersion;
|
||||||
|
virFirewallDGetZones;
|
||||||
|
virFirewallDInterfaceSetZone;
|
||||||
virFirewallDIsRegistered;
|
virFirewallDIsRegistered;
|
||||||
|
virFirewallDZoneExists;
|
||||||
|
|
||||||
|
|
||||||
# util/virfirmware.h
|
# util/virfirmware.h
|
||||||
|
@ -46,6 +46,14 @@ VIR_ENUM_IMPL(virFirewallLayerFirewallD, VIR_FIREWALL_LAYER_LAST,
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
VIR_ENUM_DECL(virFirewallDBackend);
|
||||||
|
VIR_ENUM_IMPL(virFirewallDBackend, VIR_FIREWALLD_BACKEND_LAST,
|
||||||
|
"",
|
||||||
|
"iptables",
|
||||||
|
"nftables",
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virFirewallDIsRegistered:
|
* virFirewallDIsRegistered:
|
||||||
*
|
*
|
||||||
@ -57,6 +65,195 @@ virFirewallDIsRegistered(void)
|
|||||||
return virDBusIsServiceRegistered(VIR_FIREWALL_FIREWALLD_SERVICE);
|
return virDBusIsServiceRegistered(VIR_FIREWALL_FIREWALLD_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virFirewallDGetVersion:
|
||||||
|
* @version: pointer to location to save version in the form of:
|
||||||
|
* 1000000 * major + 1000 * minor + micro
|
||||||
|
*
|
||||||
|
* queries the firewalld version property from dbus, and converts it
|
||||||
|
* from a string into a number.
|
||||||
|
*
|
||||||
|
* Returns 0 if version was successfully retrieved, or -1 on error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virFirewallDGetVersion(unsigned long *version)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
DBusConnection *sysbus = virDBusGetSystemBus();
|
||||||
|
DBusMessage *reply = NULL;
|
||||||
|
VIR_AUTOFREE(char *) versionStr = NULL;
|
||||||
|
|
||||||
|
if (!sysbus)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (virDBusCallMethod(sysbus,
|
||||||
|
&reply,
|
||||||
|
NULL,
|
||||||
|
VIR_FIREWALL_FIREWALLD_SERVICE,
|
||||||
|
"/org/fedoraproject/FirewallD1",
|
||||||
|
"org.freedesktop.DBus.Properties",
|
||||||
|
"Get",
|
||||||
|
"ss",
|
||||||
|
"org.fedoraproject.FirewallD1",
|
||||||
|
"version") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virDBusMessageRead(reply, "v", "s", &versionStr) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virParseVersionString(versionStr, version, false) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Failed to parse firewalld version '%s'"),
|
||||||
|
versionStr);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_DEBUG("FirewallD version: %s - %lu", versionStr, *version);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
virDBusMessageUnref(reply);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virFirewallDGetBackend:
|
||||||
|
*
|
||||||
|
* Returns virVirewallDBackendType value representing which packet
|
||||||
|
* filtering backend is currently in use by firewalld, or -1 on error.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virFirewallDGetBackend(void)
|
||||||
|
{
|
||||||
|
DBusConnection *sysbus = virDBusGetSystemBus();
|
||||||
|
DBusMessage *reply = NULL;
|
||||||
|
virError error;
|
||||||
|
VIR_AUTOFREE(char *) backendStr = NULL;
|
||||||
|
int backend = -1;
|
||||||
|
|
||||||
|
if (!sysbus)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memset(&error, 0, sizeof(error));
|
||||||
|
|
||||||
|
if (virDBusCallMethod(sysbus,
|
||||||
|
&reply,
|
||||||
|
&error,
|
||||||
|
VIR_FIREWALL_FIREWALLD_SERVICE,
|
||||||
|
"/org/fedoraproject/FirewallD1/config",
|
||||||
|
"org.freedesktop.DBus.Properties",
|
||||||
|
"Get",
|
||||||
|
"ss",
|
||||||
|
"org.fedoraproject.FirewallD1.config",
|
||||||
|
"FirewallBackend") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (error.level == VIR_ERR_ERROR) {
|
||||||
|
/* we don't want to log any error in the case that
|
||||||
|
* FirewallBackend isn't implemented in this firewalld, since
|
||||||
|
* that just means that it is an old version, and only has an
|
||||||
|
* iptables backend.
|
||||||
|
*/
|
||||||
|
VIR_DEBUG("Failed to get FirewallBackend setting, assuming 'iptables'");
|
||||||
|
backend = VIR_FIREWALLD_BACKEND_IPTABLES;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virDBusMessageRead(reply, "v", "s", &backendStr) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
VIR_DEBUG("FirewallD backend: %s", backendStr);
|
||||||
|
|
||||||
|
if ((backend = virFirewallDBackendTypeFromString(backendStr)) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Unrecognized firewalld backend type: %s"),
|
||||||
|
backendStr);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virResetError(&error);
|
||||||
|
virDBusMessageUnref(reply);
|
||||||
|
return backend;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virFirewallDGetZones:
|
||||||
|
* @zones: array of char *, each entry is a null-terminated zone name
|
||||||
|
* @nzones: number of entries in @zones
|
||||||
|
*
|
||||||
|
* Get the number of currently active firewalld zones, and their names
|
||||||
|
* in an array of null-terminated strings. The memory pointed to by
|
||||||
|
* @zones will belong to the caller, and must be freed.
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -1 (and failure logged) on error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virFirewallDGetZones(char ***zones, size_t *nzones)
|
||||||
|
{
|
||||||
|
DBusConnection *sysbus = virDBusGetSystemBus();
|
||||||
|
DBusMessage *reply = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
*nzones = 0;
|
||||||
|
*zones = NULL;
|
||||||
|
|
||||||
|
if (!sysbus)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (virDBusCallMethod(sysbus,
|
||||||
|
&reply,
|
||||||
|
NULL,
|
||||||
|
VIR_FIREWALL_FIREWALLD_SERVICE,
|
||||||
|
"/org/fedoraproject/FirewallD1",
|
||||||
|
"org.fedoraproject.FirewallD1.zone",
|
||||||
|
"getZones",
|
||||||
|
NULL) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virDBusMessageRead(reply, "a&s", nzones, zones) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
virDBusMessageUnref(reply);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virFirewallDZoneExists:
|
||||||
|
* @match: name of zone to look for
|
||||||
|
*
|
||||||
|
* Returns true if the requested zone exists, or false if it doesn't exist
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
virFirewallDZoneExists(const char *match)
|
||||||
|
{
|
||||||
|
size_t nzones = 0, i;
|
||||||
|
char **zones = NULL;
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (virFirewallDGetZones(&zones, &nzones) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
for (i = 0; i < nzones; i++) {
|
||||||
|
if (STREQ_NULLABLE(zones[i], match))
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_DEBUG("Requested zone '%s' %s exist",
|
||||||
|
match, result ? "does" : "doesn't");
|
||||||
|
for (i = 0; i < nzones; i++)
|
||||||
|
VIR_FREE(zones[i]);
|
||||||
|
VIR_FREE(zones);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virFirewallDApplyRule:
|
* virFirewallDApplyRule:
|
||||||
@ -149,3 +346,26 @@ virFirewallDApplyRule(virFirewallLayer layer,
|
|||||||
virDBusMessageUnref(reply);
|
virDBusMessageUnref(reply);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
virFirewallDInterfaceSetZone(const char *iface,
|
||||||
|
const char *zone)
|
||||||
|
{
|
||||||
|
DBusConnection *sysbus = virDBusGetSystemBus();
|
||||||
|
DBusMessage *reply = NULL;
|
||||||
|
|
||||||
|
if (!sysbus)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return virDBusCallMethod(sysbus,
|
||||||
|
&reply,
|
||||||
|
NULL,
|
||||||
|
VIR_FIREWALL_FIREWALLD_SERVICE,
|
||||||
|
"/org/fedoraproject/FirewallD1",
|
||||||
|
"org.fedoraproject.FirewallD1.zone",
|
||||||
|
"changeZoneOfInterface",
|
||||||
|
"ss",
|
||||||
|
zone,
|
||||||
|
iface);
|
||||||
|
}
|
||||||
|
@ -23,11 +23,24 @@
|
|||||||
|
|
||||||
# define VIR_FIREWALL_FIREWALLD_SERVICE "org.fedoraproject.FirewallD1"
|
# define VIR_FIREWALL_FIREWALLD_SERVICE "org.fedoraproject.FirewallD1"
|
||||||
|
|
||||||
int virFirewallDIsRegistered(void);
|
typedef enum {
|
||||||
|
VIR_FIREWALLD_BACKEND_NONE,
|
||||||
|
VIR_FIREWALLD_BACKEND_IPTABLES,
|
||||||
|
VIR_FIREWALLD_BACKEND_NFTABLES,
|
||||||
|
VIR_FIREWALLD_BACKEND_LAST,
|
||||||
|
} virFirewallDBackendType;
|
||||||
|
|
||||||
|
int virFirewallDGetVersion(unsigned long *version);
|
||||||
|
int virFirewallDGetBackend(void);
|
||||||
|
int virFirewallDIsRegistered(void);
|
||||||
|
int virFirewallDGetZones(char ***zones, size_t *nzones);
|
||||||
|
bool virFirewallDZoneExists(const char *match);
|
||||||
int virFirewallDApplyRule(virFirewallLayer layer,
|
int virFirewallDApplyRule(virFirewallLayer layer,
|
||||||
char **args, size_t argsLen,
|
char **args, size_t argsLen,
|
||||||
bool ignoreErrors,
|
bool ignoreErrors,
|
||||||
char **output);
|
char **output);
|
||||||
|
|
||||||
|
int virFirewallDInterfaceSetZone(const char *iface,
|
||||||
|
const char *zone);
|
||||||
|
|
||||||
#endif /* LIBVIRT_VIRFIREWALLD_H */
|
#endif /* LIBVIRT_VIRFIREWALLD_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user