Re: [PATCH v5 12/30] network: support setting firewallBackend from network.conf

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

 



On Mon, May 20, 2024 at 12:14:26PM -0400, Laine Stump wrote:
> On 5/20/24 6:14 AM, Daniel P. Berrangé wrote:
> > On Fri, May 17, 2024 at 01:29:49PM -0400, Laine Stump wrote:
> > > It still can have only one useful value ("iptables"), but once a 2nd
> > > value is supported, it will be selectable by setting
> > > "firewall_backend=nftables" in /etc/libvirt/network.conf.
> > > 
> > > If firewall_backend isn't set in network.conf, then libvirt will check
> > > to see if FIREWALL_BACKEND_DEFAULT_1 is available and, if so, set
> > > that. (Since FIREWALL_BACKEND_DEFAULT_1 is currently "iptables", this
> > > means checking to see it the iptables binary is present on the
> > > system).  If the default backend isn't available, that is considered a
> > > fatal error (since no networks can be started anyway), so an error is
> > > logged and startup of the network driver fails.
> > > 
> > > NB: network.conf is itself created from network.conf.in at build time,
> > > and the advertised default setting of firewall_backend (in a commented
> > > out line) is set from the meson_options.txt setting
> > > "firewall_backend_default_1". This way the conf file will have correct
> > > information no matter what ordering is chosen for default backend at
> > > build time (as more backends are added, settings will be added for
> > > "firewall_backend_default_n", and those will be settable in
> > > meson_options.txt and on the meson commandline to change the ordering
> > > of the auto-detection when no backend is set in network.conf).
> > > 
> > > virNetworkLoadDriverConfig() may look more complicated than necessary,
> > > but as additional backends are added, it will be easier to add checks
> > > for those backends (and to re-order the checks based on builders'
> > > preferences).
> > > 
> > > Signed-off-by: Laine Stump <laine@xxxxxxxxxx>
> > 
> > > @@ -62,18 +62,75 @@ virNetworkLoadDriverConfig(virNetworkDriverConfig *cfg G_GNUC_UNUSED,
> > >                              const char *filename)
> > >   {
> > >       g_autoptr(virConf) conf = NULL;
> > > +    g_autofree char *fwBackendStr = NULL;
> > > +    bool fwBackendSelected = false;
> > > +    size_t i;
> > > +    int fwBackends[] = { FIREWALL_BACKEND_DEFAULT_1 };
> > > +    G_STATIC_ASSERT(G_N_ELEMENTS(fwBackends) == VIR_FIREWALL_BACKEND_LAST);
> > 
> > I'd say we shoule remove this assert and use:
> > 
> >    size_t nfwBackends = G_N_ELEMENTS(fwBackends));
> 
> The reason I put in the assert was to make sure there is a compile-time
> error if someone adds a new backend and forgets to add an entry in the above
> array, or to add a new FIREWALL_BACKEND_n in the meson_options + an
> additional item for it in fwBackends (similar to typecasting ints into enums
> so the compile will catch it when you add an enum value and forget to add a
> case to a switch statement).

Ah right, yes.

> > > +    if (access(filename, R_OK) == 0) {
> > > +
> > > +        conf = virConfReadFile(filename, 0);
> > > +        if (!conf)
> > > +            return -1;
> > > +
> > > +        /* use virConfGetValue*(conf, ...) functions to read any settings into cfg */
> > > +
> > > +        if (virConfGetValueString(conf, "firewall_backend", &fwBackendStr) < 0)
> > > +            return -1;
> > > +
> > > +        if (fwBackendStr) {
> > > +            fwBackends[0] = virFirewallBackendTypeFromString(fwBackendStr);
> > > +
> > > +            if (fwBackends[0] < 0) {
> > > +                virReportError(VIR_ERR_INTERNAL_ERROR,
> > > +                               _("unrecognized 'firewall_backend = '%1$s' set in network driver config file %2$s"),
> > > +                               fwBackendStr, filename);
> > > +                return -1;
> > > +            }
> > > +            VIR_INFO("firewall_backend setting requested from config file %s: '%s'",
> > > +                     virFirewallBackendTypeToString(fwBackends[0]), filename);
> > 
> > Here set
> > 
> >     nfwBackends = 1;
> > 
> > since when a config param is set, we don't want to ever fallback to
> > the 2nd entry
> 
> That is taken care of by [see [*] below], but I'll add this suggestion
> anyway to reduce the brain cells required for someone reading through the
> code :-) (and also as a backup in case the code at [*] gets changed in the
> future).

Yeah, the current code works, but is a bit confusing to me.
Meanwhile

  Reviewed-by: Daniel P. Berrangé <berrange@xxxxxxxxxx>

> 
> > 
> > > +        }
> > > +    }
> > > -    /* if file doesn't exist or is unreadable, ignore the "error" */
> > > -    if (access(filename, R_OK) == -1)
> > > -        return 0;
> > > +    for (i = 0; i < G_N_ELEMENTS(fwBackends) && !fwBackendSelected; i++) {
> > 
> > s/G_N_ELEMENTS(...)/nfwBackends/;
> > 
> > > -    conf = virConfReadFile(filename, 0);
> > > -    if (!conf)
> > > -        return -1;
> > > +        switch ((virFirewallBackend)fwBackends[i]) {
> > > +        case VIR_FIREWALL_BACKEND_IPTABLES: {
> > > +            g_autofree char *iptablesInPath = virFindFileInPath(IPTABLES);
> > > -    /* use virConfGetValue*(conf, ...) functions to read any settings into cfg */
> > > +            if (iptablesInPath)
> > > +                fwBackendSelected = true;
> > > +            break;
> > > +        }
> > > +        case VIR_FIREWALL_BACKEND_LAST:
> > > +            virReportEnumRangeError(virFirewallBackend, fwBackends[i]);
> > > +            return -1;
> > > +        }
> > > -    return 0;
> > > +        if (fwBackendSelected) {
> > > +
> > > +            cfg->firewallBackend = fwBackends[i];
> > > +
> 
> [*] The else clause just below this comment makes sure that if a backend is
> specified in the config (and thus fwBackendStr is non-null) then we'll never
> fall back to one of the alternates, but will instead immediately log an
> error and fail. And it has the added advantage (over just setting
> nFwBackends = 1) of giving us an easy way to differentiate the log message
> of "couldn't find a working backend among all the possibilities" and "the
> backend you specifically requested is unavailable".
> 
> > > +        } else if (fwBackendStr) {
> > > +
> > > +            /* explicitly requested backend not found - this is a failure */
> > > +            virReportError(VIR_ERR_INTERNAL_ERROR,
> > > +                           _("requested firewall_backend '%1$s' is not available"),
> > > +                           virFirewallBackendTypeToString(fwBackends[i]));
> > > +            return -1;
> > > +        }
> > > +    }
> > > +
> > > +    if (fwBackendSelected) {
> > > +        VIR_INFO("using firewall_backend: '%s'",
> > > +                 virFirewallBackendTypeToString(cfg->firewallBackend));
> > > +        return 0;
> > > +    } else {
> > > +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> > > +                       _("could not find a usable firewall backend"));
> > > +        return -1;
> > > +    }
> > >   }
> > 
> > With regards,
> > Daniel
> 

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 :|




[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