• T
    network: use firewalld instead of iptables, when available · bf156385
    Thomas Woerner 提交于
    * configure.ac, spec file: firewalld defaults to enabled if dbus is
      available, otherwise is disabled. If --with_firewalld is explicitly
      requested and dbus is not available, configure will fail.
    
    * bridge_driver: add dbus filters to get the FirewallD1.Reloaded
      signal and DBus.NameOwnerChanged on org.fedoraproject.FirewallD1.
      When these are encountered, reload all the iptables reuls of all
      libvirt's virtual networks (similar to what happens when libvirtd is
      restarted).
    
    * iptables, ebtables: use firewall-cmd's direct passthrough interface
      when available, otherwise use iptables and ebtables commands. This
      decision is made once the first time libvirt calls
      iptables/ebtables, and that decision is maintained for the life of
      libvirtd.
    
    * Note that the nwfilter part of this patch was separated out into
      another patch by Stefan in V2, so that needs to be revised and
      re-reviewed as well.
    
    ================
    
    All the configure.ac and specfile changes are unchanged from Thomas'
    V3.
    
    V3 re-ran "firewall-cmd --state" every time a new rule was added,
    which was extremely inefficient.  V4 uses VIR_ONCE_GLOBAL_INIT to set
    up a one-time initialization function.
    
    The VIR_ONCE_GLOBAL_INIT(x) macro references a static function called
    vir(Ip|Eb)OnceInit(), which will then be called the first time that
    the static function vir(Ip|Eb)TablesInitialize() is called (that
    function is defined for you by the macro). This is
    thread-safe, so there is no chance of any race.
    
    IMPORTANT NOTE: I've left the VIR_DEBUG messages in these two init
    functions (one for iptables, on for ebtables) as VIR_WARN so that I
    don't have to turn on all the other debug message just to see
    these. Even if this patch doesn't need any other modification, those
    messages need to be changed to VIR_DEBUG before pushing.
    
    This one-time initialization works well. However, I've encountered
    problems with testing:
    
    1) Whenever I have enabled the firewalld service, *all* attempts to
    call firewall-cmd from within libvirtd end with firewall-cmd hanging
    internally somewhere. This is *not* the case if firewall-cmd returns
    non-0 in response to "firewall-cmd --state" (i.e. *that* command runs
    and returns to libvirt successfully.)
    
    2) If I start libvirtd while firewalld is stopped, then start
    firewalld later, this triggers libvirtd to reload its iptables rules,
    however it also spits out a *ton* of complaints about deletion failing
    (I suppose because firewalld has nuked all of libvirt's rules). I
    guess we need to suppress those messages (which is a more annoying
    problem to fix than you might think, but that's another story).
    
    3) I noticed a few times during this long line of errors that
    firewalld made a complaint about "Resource Temporarily
    unavailable. Having libvirtd access iptables commands directly at the
    same time as firewalld is doing so is apparently problematic.
    
    4) In general, I'm concerned about the "set it once and never change
    it" method - if firewalld is disabled at libvirtd startup, causing
    libvirtd to always use iptables/ebtables directly, this won't cause
    *terrible* problems, but if libvirtd decides to use firewall-cmd and
    firewalld is later disabled, libvirtd will not be able to recover.
    bf156385
libvirt.spec.in 67.8 KB