Re: [PATCH v2 18/27] util: new functions virFirewallParseXML() and virFirewallFormat()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <laine@xxxxxxxxxx>
> ---
>  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 -- devel@xxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxx




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux