Jump to: navigation, search

VIFVHostUserFP

Revision as of 13:55, 28 September 2016 by Francesco.santoro (talk | contribs) (Impact)

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.

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