VIFVHostUserFP

Introduction
Starting from Newton the new os-vif framework has been introduced to allow nova delegating virtual interface management (plug/unplug) to specific external plugins, leveraging the stevedore capabilities. Among all the supported VIF types in nova, at this time only linuxbridge and openvswitch provide their own os-vif plugins.

For the vhostuser vif type the situation is a little bit different compared to other vif types. Since mitaka, two different implementations exist in nova to plug/unplug vhostuser ports according to the underlying technology (ovs-dpdk or fast path). The fast path technology behaves as a transparent acceleration layer for traditional switches (ovs, linuxbridge) and for alternative networking mechanisms (calico, midonet).

The fast path creates a linux netdevice for each vhostuser port. It is then possible to plug such port in ovs, linuxbridge, calico as it is commonly done for linux tap interfaces. At current state, the networking_6wind neutron plugin offers mechanism drivers (ovs-fp, lb-fp) [1] to support fast path vhostuser with ovs and linuxbridge agents. On nova side, the current implementation (plug_vhostuser_fp) is only supporting the ovs scenario.

Problem description
A full migration of the plug_vhostuser_fp method to an os-vif driver is not possible with the current os-vif VIFVHostUser object implementation.

This object provides two fields (socket path and mode) that are necessary for vhostuser ports creation but not enough to plug/unplug ports when the fastpath technology is used together with ovs and security groups. In particular when ovs hybrid_plug is chosen, the name of this hybrid bridge is not available in the VIFVHostUser object (while the nova implementation can access this information).

More generally, each time a traditional mechanism driver (ovs, linuxbridge, calico, etc) is used together with fast path vhostuser implementation, some additional information may be needed in the VIFVHostUser object to plug/unplug the interface properly.

Possible solution #1
As suggested by Sean Mooney a possible solution to the described problem would be to enrich the os-vif framework with some specific VHostUserFP[X] classes that will contain all the needed extra fields. With such approach a dedicated os-vif plugin for each of these VHostUserFP[X] classes will be needed.

For example for the ovs (or linuxbridge) + fastpath scenario: @base.VersionedObjectRegistry.register class VIFVHostUserFPBridged(VIFVHostUser, VIFBridge): # For libvirt drivers, this maps to type='vhostuser' # Object to support fast path vhostuser VIF with bridged technologies VERSION = '1.0'

Dependent changes in nova
Nova will consume this object almost as follows:

...   if vif['details'].get(model.VIF_DETAILS_VHOSTUSER_FP_PLUG, False): obj = _get_vif_instance(                                                               vif,                                                                            objects.vif.VIFVHostUserFPBridged,                                                       plugin="vhostuser_fp_bridged",                                                          mode=mode,                                                                      path=path,                vif_name=_get_vif_name(vif)) if vif['details'].get(model.VIF_DETAILS_VHOSTUSER_OVS_PLUG, False): profile = objects.vif.VIFPortProfileOpenVSwitch(                                       interface_id=vif.get('ovs_interfaceid') or vif['id']) obj.port_profile = profile if _is_firewall_required(vif) or vif.is_hybrid_plug_enabled: obj.bridge_name = _get_hybrid_bridge_name(vif) else: if vif["network"]["bridge"] is not None: obj.bridge_name = vif["network"]["bridge"] return obj ...

It will be responsability of the os-vif driver to detect if fast path ovs or linuxbridge is used. For instance by checking the port_profile

Possible solution #2
Condensate all the fast path needs in a single os-vif class VIFVHostUserFP (whose fields could evolve when new mechanism_types are supported): With such approach a single os-vif plugin will be enough

@base.VersionedObjectRegistry.register class VIFVHostUserFP(VIFVHostUser): # For libvirt drivers, this maps to type='vhostuser' # Object to support fast path vhostuser VIF VERSION = '1.0' fields = { # Type of adopted mechanism driver (ovs-fp, lb-fp) 'mechanism_type': fields.Enum, # Name of the fp interface to create 'vif_name': fields.StringField, # Name of the bridge to connect to (br0) 'bridge_name': fields.StringField, }

Dependent changes in nova
Nova will consume this object almost in the same way described before:

...   if vif['details'].get(model.VIF_DETAILS_VHOSTUSER_FP_PLUG, False): obj = _get_vif_instance(                                                               vif,                                                                            objects.vif.VIFVHostUserFP,                                                       plugin="vhostuser_fp",                                                          mode=mode,                                                                      path=path,                vif_name=_get_vif_name(vif)) if vif['details'].get(model.VIF_DETAILS_VHOSTUSER_OVS_PLUG, False): profile = objects.vif.VIFPortProfileOpenVSwitch(                                       interface_id=vif.get('ovs_interfaceid') or vif['id']) obj.port_profile = profile obj.mechanism_type = FP_TYPE_OVS else obj.mechanism_type = FP_TYPE_BRIDGE if _is_firewall_required(vif) or vif.is_hybrid_plug_enabled: obj.bridge_name = _get_hybrid_bridge_name(vif) else: if vif["network"]["bridge"] is not None: obj.bridge_name = vif["network"]["bridge"] return obj ...

Impact
Whatever solution is chosen, the impact is limited to the implementation of _nova_to_osvif_vif_vhostuser in nova

[1] https://github.com/openstack/networking-6wind/tree/master/networking_6wind/ml2_drivers