VDSM pluggable networking

Created by Antoni Segura Puimedon / @celebdor

## What is VDSM? * oVirt's hypervisor node controller * Exposes XML RPC API for controlling nodes: 1. Virtualization 2. **Networking** 3. Storage * Python 2

Architecture

Architecture

Communication

Networking

Allowed configurations over physical device

VDSM networking modules

VDSM networking API

  • Host networking
    • setupNetworks Hooks Configurators
    • setSafeNetworkConfig Configurators
    • getVdsCapabilities
  • VM networking
    • hotplugNic Hooks
    • hotunplugNic Hooks
    • vmUpdateDevice Hooks
    • getVmStats

Hooks

  • Scripts installed to /usr/libexec/vdsm/hooks/
  • Multiple scripts per hooking point (sorted by priority)
  • Can be written in any programming language (Python)
  • IO via environment variables and files
  • XML and JSON file interface
  • Placed before and after API calls to extend VDSM

Host networking Hooks

  • before_network_setup
    • Input: JSON of setupNetworks API command (nets and bonds definitions)
    • Output: JSON dump of network and bonding definitions for setupNetworks to apply
  • after_network_setup
    • Input: JSON of what was set for setupNetworks to apply

Example that integrates with journald


#!/usr/bin/env python
from systemd import journal
from vdsm import netinfo
import json, os, sys

with open(os.environ['_hook_json']) as data_file:
    setup_nets_config = json.load(data_file)

networks = netinfo.networks()  # Current nets
for network, data in setup_nets_config['request']['networks'].items():
    if 'remove' in data:
        journal.send('VDSM to remove network %s' % network)
    else:
        journal.send('VDSM to configure network %s' % network,
                     NEWNET=network in networks, DEF=str(data))
                                        

VM networking Hooks

  • before_nic_hotplug
  • after_nic_hotplug
  • after_nic_hotplug_fail
  • before_nic_hotunplug
  • after_nic_hotunplug
  • after_nic_hotunplug_fail
  • before_device_create
  • after_device_create
  • before_device_destroy
  • after_device_destroy
  • before_update_device
  • after_update_device
  • after_update_device_fail

Example that overrides vnic net


#!/usr/bin/env python
import hooking, os, sys, xml.dom

libvirt_net = os.environ.get('extnet')
if libvirt_net is not None:
    doc_xml = hooking.read_domxml()
    vnic_xml, = doc_xml.getElementsByTagName('interface')

    # Replace net from vnic xml
    source, = vnic_xml.getElementsByTagName('source')
    source.removeAttribute('bridge')
    source.setAttribute('network', libvirt_net)
    vnic_xml.setAttribute('type', 'network')

    hooking.write_domxml(doc)  # Write back the xml for vdsm/libvirt
                                        

some shipped hooks

  • Cisco UCS vNIC
  • extnet
  • macspoofing filter removal
  • openstack nets for vNIC
  • Attach sriov to VMs
  • QoS (obsoleted by new API)

Configurators

  • Apply network configuration to the system
  • Operates on network device objects
  • Advantages:
    • Using different networking systems
    • Supporting multiple distributions
    • Controlling each step of the network configuration
  • Pain points:
    • Each configurator can have different persistence semantics
    • Dealing with transactions

Mandatory API

  • begin
  • configureBridge
  • configureBond
  • configureVlan
  • configureNic
  • configureSourceRoute
  • editBonding
  • removeBridge
  • removeBond
  • removeVlan
  • removeNic
  • removeSourceRoute
  • flush

Optional API

  • configureLibvirtNetwork
  • removeLibvirtNetwork
  • rollback

Configurator flow

configure Vlan example


def configureVlan(self, vlan, **opts):
    vlan.device.configure(**opts)
    ipwrapper.linkAdd(name=vlan.name, linkType='vlan',
                      link=vlan.device.name args=['id', str(vlan.tag)])
    if vlan.ip:
        ipwrapper.addrFlush(vlan.name)
        ipwrapper.addrAdd(vlan.name, vlan.ipConfig.ipaddr,
                          ipConfig.netmask)
        if vlan.ipConfig.gateway and vlan.ipConfig.defaultRoute:
            ipwrapper.routeAdd(['default', 'via', vlan.ipConfig.gateway])
    if vlan.mtu:
        ipwrapper.linkSet(vlan.name, ['mtu', str(mtu)])
    ipwrapper.linkSet(vlan.name, ['up'])
    if vlan.ipConfig.bootproto == 'dhcp':
        DhcpClient(vlan.name).start(vlan.ipConfig.async)
                                        

Shipped configurators

  • ifcfg (Fedora, el6)
  • iproute2

Unified persistence: Addressing Configurator pain points

  • Abstracts away the network configuration persistence
  • Deals with transactionality
  • File system based
  • One JSON file per each network and/or bond
  • Introduces:
    • Running Configuration
    • Persistent Configuration

Running Configuration

  • On tmpfs: /var/run/vdsm/netconf/{nets,bonds}
  • Exact vdsm network and bond state
  • Written on successful network operation
  • Can be persisted atomically by setSafeNetworkConfig

Persistent Configuration

  • On: /var/lib/vdsm/persistence/netconf/{nets,bonds}
  • Configuration to roll back to when rebooting or restoring connectivity
  • netconf is a link to the latest snapshot copied from Running Configuration
  • Allows recovery from wrong configurations

Creation flow

Reboot flow

Restore flow

Future work

  • Missing hooks work
    • before_returning_capabilites
  • Missing configurator work
    • Have configurator-like extension points for netinfo
    • Straight-to-Netlink configurator (in progress)
    • Team configurator
    • Your configurator

Join us

http://gerrit.ovirt.org

#ovirt@oftc.net

#vdsm@irc.freenode.net