Deep Dive into Neutron

Neutron ML2

The Modular Layer2 (ml2) plugin is a framework allowing OpenStack Networking to simultaneusly utilze the variety of layer2 networking technology found in complex real-world data centres.

It currently works with the existing

  • openvswitch
  • linuxbridge
  • hyperv

like:

     [ Neutron Server {ML2 Plugin} ]

      |_ [ Host A {linuxbridge agent} ] 

      |_ [ Host B{hyperv agent} ]

      |_ [ Host C{openvswitch agent} ]

      |_ [ Host D{openvswitch agent} ]

       * Exsiting ML2 Plugin works with existing agents

       * Separate agents for linuxbridge, openvswitch, and hyperv.

L2 agents, and is intended to

  • replace
  • deprecate

like:

     [ Neutron Server {ML2 Plugin} ]

      |_ [ Host A {modular agent} ]

      |_ [ Host B {modular agent} ]

      |_ [ Host C {modular agent} ]

      |_ [ Host D {modular agent} ]

       * Combine open source agents

       * Have a single agent which can support linuxbridge and openvswitch

       * Pluggable drivers for additional vswitches, infiniband, sr-iov, etc

The monolithic plugins associated with those L2 agents. The ml2 framework is also intended to greatly simplify adding support for new L2 networking technologies, requiring much less intial and ongoing effort than would be required to add a new monolithic core plugin. A modular agent may be developed as a follow-on effort.

Architecture

 ML2 Plugin {

     TypeDriver {

        VLAN, GRE, VXLAN, Flat

    },

    MechanismDriver {

        OpenvSwitch, Hyper-V, OpenDaylight, Arista, Cisco Nexus

    }

    ExtensionDriver

}

TypeDriver

Each available network type is managed by an ml2 TypeDriver. TypeDrivers maintain any needed type-specific network state, and perform provider network validation and tenant network allocation.

The ml2 plugin currently includes drivers for:

// ./neutron/plugins/ml2/driver_api.py

  38 class TypeDriver(object):

    ....

  56     def get_type(self):

Get driver's network type.

    ....

  64     def initialize(self):

Perform driver initialization

    ....

  74     def is_partial_segment(self, segment):

Return true if segment is a patially specified segment

    ....

  82     def validate_provider_segment(self, segment):

Validate attributes of a provider network segment

     ....

 102     def reserve_provider_segment(self, session, segment):

Reeserve resource associated with a provider network segment

    ....

 117     def allocate_tenant_segment(self, session):

Allocate resource for a new tenant network segment

    ....

 133     def release_segment(self, session, segment):

Release network segment

    ....

 147     def get_mtu(self, physical):

Get driver's network MTU

Mechanism Drivers

Each networking mechanism is managed by an mll2 MechanismDrivers. The MechanismDriver is responsible for taking the information established by the TypeDriver and ensuring that it is properly applied given the specific networking mechanisms that have been enabled.

The MechanismDriver interface currently supports the:

  • creatin
  • update
  • deletion

of network and port resources. For every action that can be taken on a resource, the mechanism driver exposes two methods:

  • ACTION_RESOURCE_percommit
  • ACTION_RESOURCE_postcommit

The precommit method:

 Used by mechanism drivers to validate the action being taken and make any required changes to the mechanism driver's private database.

 Should not block, and therefore cannot communicate with anything outside of Neutron.

The postcommit method:

 Is responsible for appropriately pushing the change to the resource to the entity responsible for applying that change.

// ./neutron/plugins/ml2/driver_api.py

  548 class MechanismDriver(object):

    ....

  570     def initialize(self):

Perform driver initialization

    ....

  579     def create_network_precommit(self, context):

Allocate resources for a new network

    .... 

  592     def create_network_postcommit(self, context):

Create a network

    ....

  605     def update_network_precommit(self, context):

Update resources of a network

    ....

  623     def update_network_postcommit(self, context):

Update a network

    ....

  641     def delete_network_precommit(self, context):

Delete resources for a network

    ....

  655     def delete_network_postcommit(self, context):

Delete a network

    ....

  669     def create_subnet_precommit(self, context):

Allocate resources for a new subnet

    ....

  682     def create_subnet_postcommit(self, context):

Create a subnet

    ....

  695     def update_subnet_precommit(self, context):

Update resources of a subnet

    ....

  713     def update_subnet_postcommit(self, context):

Update a subnet

    ....

  731     def delete_subnet_precommit(self, context):

Delete resources for a subnet

    ....

  745     def delete_subnet_postcommit(self, context):

Delete a subnet

    ....

  759     def create_port_precommit(self, context):

Allocate resources for a new port

    ....

  771     def create_port_postcommit(self, context):

Create a port

    ....

  783     def update_port_precommit(self, context):

Update resources of a port

    ....

  800     def update_port_postcommit(self, context):

Update a port

    ....

  818     def delete_port_precommit(self, context):

Delete resources of a port

    ....

  830     def delete_port_postcommit(self, context):

Delete a port

    ....

  844     def bind_port(self, context):

Attempt to bind a port

    ....

  882     def check_vlan_transparency(self, context):

 Check if the network supports vlan transparency

 ExtensionDriver

An extension driver extends the core resources implemented by the ML2 plugin with additional atributes.

// ./neutron/plugins/ml2/driver_api.py

  893 class ExtensionDriver(object):

    ....

  905     def initialize(self):

Perform driver initialization

    ....

  915     def extension_alias(self):

Supported extension alias

    ....

  923     def process_create_network(self, plugin_context, data, result):

Process extended attributes for create network

    ....

  937     def process_create_subnet(self, plugin_context, data, result):

Process extended attributes for create subnet

    ....

  951     def process_create_port(self, plugin_context, data, result):

Process extended attributes for create port

    ....

  965     def process_update_network(self, plugin_context, data, result):

Process extended attributes for update network

    ....

  979     def process_update_subnet(self, plugin_context, data, result):

Process extended attributes for update subnet

    ....

  993     def process_update_port(self, plugin_context, data, result):

Process extended attributes for update port

    ....

 1007     def extend_network_dict(self, session, base_model, result):

Add extended attributes to network dictionary

    ....

 1021     def extend_subnet_dict(self, session, base_model, result):

Add extened attributes to subnet dictionary

    ....

 1035     def extend_port_dict(self, session, base_model, result):

Add extended attributes to subnet dictionary

How Plugin Loaded?

// ./neutron/plugins/ml2/managers.py

 In TypeManager class, each function in driver_api.py is called:

 39 class TypeManager(stevedore.named.NamedExtensionManager):

 53     self._check_tenant_network_types(cfg.CONF.ml2.tenant_network_types)
 54     self._check_external_network_type(cfg.CONF.ml2.external_network_type)

 58     network_type = ext.obj.get_type()

170    driver.obj.initialize()

204    return driver.obj.is_partial_segment(segment)

213    driver.obj.validate_provider_segment(segment)

221    return driver.obj.reserve_provider_segment(session, segment)

225    return driver.obj.allocate_tenant_segment(session)

249    driver.obj.release_segment(session, segment)

In MechanismManager class, each function in driver_api.py is called:

284 class MechanismManager(stevedore.named.NamedExtensionManager):

318    driver.obj.initialize()

364     def create_network_precommit(self, context):

378     def create_network_postcommit(self, context):

392     def update_network_precommit(self, context):

405     def update_network_postcommit(self, context):

419     def delete_network_precommit(self, context):

490     def update_subnet_postcommit(self, context):

504     def delete_subnet_precommit(self, context):

517     def delete_subnet_postcommit(self, context):

535     def create_port_precommit(self, context):

562     def update_port_precommit(self, context):

589     def delete_port_precommit(self, context):

602     def delete_port_postcommit(self, context):

620     def bind_port(self, context):

Let's focus on TypeManager class.

                                                                                                                             To be continued...