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(a)redhat.com>
>
> > @@ -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(a)redhat.com>
>
> > + }
> > + }
> > - /* 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 :|