• S
    nwfilter: Support for learning a VM's IP address · 3bf24abc
    Stefan Berger 提交于
    This patch implements support for learning a VM's IP address. It uses
    the pcap library to listen on the VM's backend network interface (tap)
    or the physical ethernet device (macvtap) and tries to capture packets
    with source or destination MAC address of the VM and learn from DHCP
    Offers, ARP traffic, or first-sent IPv4 packet what the IP address of
    the VM's interface is. This then allows to instantiate the network
    traffic filtering rules without the user having to provide the IP
    parameter somewhere in the filter description or in the interface
    description as a parameter. This only supports to detect the parameter
    IP, which is for the assumed single IPv4 address of a VM. There is not
    support for interfaces that may have multiple  IP addresses (IP
    aliasing) or IPv6 that may then require more than one valid IP address
    to be detected. A VM can have multiple independent interfaces that each
    uses a different IP address and in that case it will be attempted to
    detect each one of the address independently.
    
    So, when for example an interface description in the domain XML has
    looked like this up to now:
    
        <interface type='bridge'>
          <source bridge='mybridge'/>
          <model type='virtio'/>
          <filterref filter='clean-traffic'>
            <parameter name='IP' value='10.2.3.4'/>
          </filterref>
        </interface>
    
    you may omit the IP parameter:
    
        <interface type='bridge'>
          <source bridge='mybridge'/>
          <model type='virtio'/>
          <filterref filter='clean-traffic'/>
        </interface>
    
    Internally I am walking the 'tree' of a VM's referenced network filters
    and determine with the given variables which variables are missing. Now,
    the above IP parameter may be missing and this causes a libvirt-internal
    thread to be started that uses the pcap library's API to listen to the
    backend interface  (in case of macvtap to the physical interface) in an
    attempt to determine the missing IP parameter. If the backend interface
    disappears the thread terminates assuming the VM was brought down. In
    case of a macvtap device a timeout is being used to wait for packets
    from the given VM (filtering by VM's interface MAC address). If the VM's
    macvtap device disappeared the thread also terminates. In all other
    cases it tries to determine the IP address of the VM and will then apply
    the rules late on the given interface, which would have happened
    immediately if the IP parameter had been explicitly given. In case an
    error happens while the firewall rules are applied, the VM's backend
    interface is 'down'ed preventing it to communicate. Reasons for failure
    for applying the network firewall rules may that an ebtables/iptables
    command failes or OOM errors. Essentially the same failure reasons may
    occur as when the firewall rules are applied immediately on VM start,
    except that due to the late application of the filtering rules the VM
    now is already running and cannot be hindered anymore from starting.
    Bringing down the whole VM would probably be considered too drastic.
    While a VM's IP address is attempted to be determined only limited
    updates to network filters are allowed. In particular it is prevented
    that filters are modified in such a way that they would introduce new
    variables.
    
    A caveat: The algorithm does not know which one is the appropriate IP
    address of a VM. If the VM spoofs an IP address in its first ARP traffic
    or IPv4 packets its filtering rules will be instantiated for this IP
    address, thus 'locking' it to the found IP address. So, it's still
    'safer' to explicitly provide the IP address of a VM's interface in the
    filter description if it is known beforehand.
    
    * configure.ac: detect libpcap
    * libvirt.spec.in: require libpcap[-devel] if qemu is built
    * src/internal.h: add the new ATTRIBUTE_PACKED define
    * src/Makefile.am src/libvirt_private.syms: add the new modules and symbols
    * src/nwfilter/nwfilter_learnipaddr.[ch]: new module being added
    * src/nwfilter/nwfilter_driver.c src/conf/nwfilter_conf.[ch]
      src/nwfilter/nwfilter_ebiptables_driver.[ch]
      src/nwfilter/nwfilter_gentech_driver.[ch]: plu the new functionality in
    * tests/nwfilterxml2xmltest: extend testing
    3bf24abc
internal.h 5.2 KB