On Sun, Apr 21, 2024 at 10:53:26PM -0400, Laine Stump wrote:
> These functions convert a virFirewall object to/from XML so that it
> can be serialized to disk (in a virNetworkObj's status file) and
> restored later (e.g. after libvirtd/virtnetworkd is restarted).
>
> Signed-off-by: Laine Stump <[email protected]>
> ---
> src/libvirt_private.syms | 2 +
> src/util/virfirewall.c | 217 +++++++++++++++++++++++++++++++++++++++
> src/util/virfirewall.h | 9 ++
> 3 files changed, 228 insertions(+)
>
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index e3dcb353b7..aa253a238b 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -2413,10 +2413,12 @@ virFirewallCmdAddArgList;
> virFirewallCmdAddArgSet;
> virFirewallCmdGetArgCount;
> virFirewallCmdToString;
> +virFirewallFormat;
> virFirewallFree;
> virFirewallGetBackend;
> virFirewallNew;
> virFirewallNewFromRollback;
> +virFirewallParseXML;
> virFirewallRemoveCmd;
> virFirewallStartRollback;
> virFirewallStartTransaction;
> diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c
> index 57d45abc17..684569c760 100644
> --- a/src/util/virfirewall.c
> +++ b/src/util/virfirewall.c
> @@ -40,6 +40,14 @@ VIR_ENUM_IMPL(virFirewallBackend,
> "UNSET", /* not yet set */
> "iptables");
>
> +VIR_ENUM_DECL(virFirewallLayer);
> +VIR_ENUM_IMPL(virFirewallLayer,
> + VIR_FIREWALL_LAYER_LAST,
> + "ethernet",
> + "ipv4",
> + "ipv6",
> +);
> +
> typedef struct _virFirewallGroup virFirewallGroup;
>
> VIR_ENUM_DECL(virFirewallLayerCommand);
> @@ -810,3 +818,212 @@ virFirewallNewFromRollback(virFirewall *original,
>
> return 0;
> }
> +
> +
> +/* virFirewallGetFlagsFromNode:
> + * @node: the xmlNode to check for an ignoreErrors attribute
> + *
> + * A short helper to get the setting of the ignorErrors attribute from
> + * an xmlNode. Returns -1 on error (with error reported), or the
> + * VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS bit set/reset according to
> + * the value of the attribute.
> + */
> +static int
> +virFirewallGetFlagsFromNode(xmlNodePtr node)
> +{
> + virTristateBool ignoreErrors;
> +
> + if (virXMLPropTristateBool(node, "ignoreErrors", VIR_XML_PROP_NONE,
> &ignoreErrors) < 0)
> + return -1;
> +
> + if (ignoreErrors == VIR_TRISTATE_BOOL_YES)
> + return VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS;
> + return 0;
> +}
> +
> +
> +/**
> + * virFirewallParseXML:
> + * @firewall: pointer to virFirewall* to fill in with new virFirewall object
> + *
> + * Construct a new virFirewall object according to the XML in
> + * xmlNodePtr. Return 0 (and new object) on success, or -1 (with
> + * error reported) on error.
> + *
> + * Example of <firewall> element XML:
> + *
> + * <firewall backend='iptables|nftables'>
> + * <group ignoreErrors='yes|no'>
> + * <action layer='ethernet|ipv4|ipv6' ignoreErrors='yes|no'>
> + * <args>
> + * <item>arg1</item>
> + * <item>arg2</item>
> + * ...
> + * </args>
> + * </action>
> + * <action ...>
> + * ...
> + </action>
> + * ...
> + * </group>
> + * ...
> + * </firewall>
> + */
> +int
> +virFirewallParseXML(virFirewall **firewall,
> + xmlNodePtr node,
> + xmlXPathContextPtr ctxt)
> +{
> + g_autoptr(virFirewall) newfw = NULL;
> + virFirewallBackend backend;
> + g_autofree xmlNodePtr *groupNodes = NULL;
> + ssize_t ngroups;
> + size_t g;
> + VIR_XPATH_NODE_AUTORESTORE(ctxt);
> +
> + ctxt->node = node;
> +
> + ngroups = virXPathNodeSet("./group", ctxt, &groupNodes);
> + if (ngroups < 0)
> + return -1;
> + if (ngroups == 0)
> + return 0;
> +
> + if (virXMLPropEnum(node, "backend", virFirewallBackendTypeFromString,
> + VIR_XML_PROP_REQUIRED, &backend) < 0) {
> + return -1;
> + }
> +
> + newfw = virFirewallNew(backend);
> +
> + for (g = 0; g < ngroups; g++) {
> + int flags = 0;
> + g_autofree xmlNodePtr *actionNodes = NULL;
> + ssize_t nactions;
> + size_t a;
> +
> + ctxt->node = groupNodes[g];
> + nactions = virXPathNodeSet("./action", ctxt, &actionNodes);
> + if (nactions < 0)
> + return -1;
> + if (nactions == 0)
> + continue;
> +
> + if ((flags = virFirewallGetFlagsFromNode(groupNodes[g])) < 0)
> + return -1;
> +
> + virFirewallStartTransaction(newfw, flags);
> +
> + for (a = 0; a < nactions; a++) {
> + g_autofree xmlNodePtr *argsNodes = NULL;
> + ssize_t nargs;
> + size_t i;
> + virFirewallLayer layer;
> + virFirewallCmd *action;
> + bool ignoreErrors;
> +
> + ctxt->node = actionNodes[a];
> +
> + if (!(ctxt->node = virXPathNode("./args", ctxt)))
> + continue;
> +
> + if ((flags = virFirewallGetFlagsFromNode(actionNodes[a])) < 0)
> + return -1;
> +
> + ignoreErrors = flags & VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS;
> +
> + if (virXMLPropEnum(actionNodes[a], "layer",
> + virFirewallLayerTypeFromString,
> + VIR_XML_PROP_REQUIRED, &layer) < 0) {
> + return -1;
> + }
> +
> + nargs = virXPathNodeSet("./item", ctxt, &argsNodes);
> + if (nargs < 0)
> + return -1;
> + if (nargs == 0)
> + continue;
In an earlier patch you indicated that nargs == 0 was an error
condition we should check and report. How about reporting it
here too, rather than delaying it ?
> +
> + action = virFirewallAddCmdFull(newfw, layer, ignoreErrors,
> + NULL, NULL, NULL);
> + for (i = 0; i < nargs; i++) {
> +
> + char *arg = virXMLNodeContentString(argsNodes[i]);
> + if (!arg)
> + return -1;
> +
> + virFirewallCmdAddArg(newfw, action, arg);
> + }
> + }
> + }
> +
> + *firewall = g_steal_pointer(&newfw);
> + return 0;
> +}
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
_______________________________________________
Devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]