MechanismDriverContext has an attribute _plugin_context, which carries
the current context with it. This is used by many ml2 drivers, as it is
the only way for them to get the current context. We now make this a
public API by adding a property to MechanismDriverContext that returns
_plugin_context as a read-only attribute.
If subnet is attached to a segment we want to endure that the bind
will happen on it.
Signed-off-by: Sahid Orentino Ferdjaoui <firstname.lastname@example.org>
The base class "MechanismDriver" now has a property called
"connectivity". This patch overrides the default value in the
The method "_check_drivers_connectivity" now uses this property
that is available in all drivers.
Check new segments added to OVN mechanism driver. This mechanism
driver does not inherit from ``SimpleAgentMechanismDriverBase``
because OVN has no agents (NOTE 1). However OVN mechanism driver
requires an OVN controller service in each deployed chassis. This
is how OVN driver knows the hosts using this backend.
The segments, attached to an external network (connected to a
physical network), can be mapped to a host if ther is a chassis (OVN
controller agent) in this host.
NOTE 1: OVN provides agent API compatibility, presenting the
controller and the metadata services as agents. But OVN mechanism
driver has no control or provides any information (via RPC) to
The mechanism driver support VNIC types validation is done now in the
"SimpleAgentMechanismDriverBase" class __init__ method. If a subclass
needs to administratively prohibit any VNIC type supported by default,
"vnic_type_prohibit_list" must be passed to the base class __init__
Provisioning Blocks  was introduced to manage composite
object status. Port object is the one Neutron sets provisioning
block during the port processing life cycle. Here is the compute
port (VM's NIC port) processing procedure:
1. nova creates port
2. the 'openvswitch' mechinism driver inserts provisioning block
for this port
3. nova calls related interface to plug the device
4. L2-agent sets the flows (or rules/devices) for the port and
call update_device_list to neutron-server
5. neutron-server try to set port status to ACTIVE
6. neutron-server notify nova that "vif-plugged" success
This works fine for VM with its ports. But for neutron service port,
like router_gateway, router_interface and dhcp, it is unnecessary.
Because there is no dependency among neutron resources. Neutron
just knows that the ports had been set properly. And another thing
is, for most of these internal service port, there is no need of
DHCP, security group or port security.
So for neutron internal service ports, the procesure can be:
1. neutron L3/DHCP/X related service plugin creates port
2. no provisioning_block
3. L3/DHCP/X related agent plug the port
4. L2-agent sets the flows (or rules/devices) for the port and
call update_device_list to neutron-server
5. neutron-server sets port status to ACTIVE directly, then done!
This patch will set neutron *AgentMechanismDrver (including built-in
drivers: linuxbridge, macvtap, sriov, openvswitch) to skip inserting
the provisioning_block for Neutron internal service ports.
Each mechanism driver loaded in the ML2Plugin can provide what
extensions are supported. By default, any mech driver can support
This extension filtering is done during the plugin initialization.
If any requested extension is not supported, it will be silently
removed from the loaded extensions.
There is no real reason we should be using some of the
terms we do, they're outdated, and we're behind other
open-source projects in this respect. Let's switch to
using more inclusive terms in all possible places.
Added "connectivity" parameter to mech driver vif_details. The default
value is "legacy". The in-tree drivers (Linux Bridge, Open vSwitch, SR-IOV
and MacVTap) have "l2" connectivity.
In patch  there was added usage of context parameter in method
get_vif_type in openvswitch mech_driver.
This exposed that previously "wrong" context was passed to this method
in _update_segmentation_id() method in ml2 plugin and that caused
raising AttributeError as "Context" object didn't have attribute
This patch adds new method "get_supported_vif_type" to mechanism
drivers and this method don't need context to return what vif_types
are supported regarding agent type.
In case of Smart NIC vNIC type neutron should mimic nova-compute
that plug the port to the ovs bridge.
Extend the Neutron OVS mechanism driver and Neutron OVS Agent to bind
the Neutron port for the baremetal host with Smart NIC. This will allow
the Neutron OVS Agent to configure the pipeline of the OVS running on
the Smart NIC and leverage the pipeline features such as: VXLAN,
Security Groups and ARP Responder.
Rehomed provider_network_attribute_updates_supported to
plugins.ml2.api.MechanismDriver, in order to be inherited in other
In the ML2 plugin, allow to update the segmentation ID of a single
A new method in the "SimpleAgentMechanismDriverBase" is added:
"provider_network_attribute_updates_supported". This method returns,
if implemented in the specific agent, which network attributes can
be updated on a live network with ports bound to this network back-end.
By default, an empty list is returned.
Drive the choice of mechanism driver during binding as inferred from
the resource provider allocated by nova and as told to neutron via the
As discussed on a neutron qos irc meeting some time ago
this patch introduces a new assumption on bind_port() implementations.
That is an implementation of bind_port() in any mech driver supporting
Guaranteed Minimum Bandwidth bind_port() must not have a non-idempotent
side effect. Because the last binding level will be redone for a 2nd
time with a narrowed down list of mechanism drivers. And if the 2nd call
does not give the same result as the first all kind of weird things can
See-Also: https://review.openstack.org/502306 (nova spec)
See-Also: https://review.openstack.org/508149 (neutron spec)
neutron-lib contains a number of the plugin related constants from
neutron.plugins.common.constants. This patch consumes those constants
from neutron-lib and removes them from neutron. In addition the notion
of the dummy plugin service type is moved strictly into the test
package of neutron since it's not a real service plugin.
Since Pike log messages should not be translated.
This patch removes calls to i18n _LC, _LI, _LE, _LW from
logging logic throughout the code. Translators definition
from neutron._i18n is removed as well.
This patch also removes log translation verification from
ignore directive in tox.ini.
The ml2 MechanismDriver is now in neutron-lib along with its associated
constants. This patch switches over to the lib versions of those, but
leaves a shim of the MechanismDriver that just ref's the driver from
lib. This shim allows our broad consumer base of the driver to switch
over at their leisure.
This moves the get_vif_type hook point from OVS into the mech agent
base so other mechanism drivers can also return different VIF types
depending on the context of the binding.
This will be used by linux bridge in change
The callback modules have been available in neutron-lib since commit 
and are ready for consumption.
As the callback registry is implemented with a singleton manager
instance, sync complications can arise ensuring all consumers switch to
lib's implementation at the same time. Therefore this consumption has
been broken down:
1) Shim neutron's callbacks using lib's callback system and remove
existing neutron internals related to callbacks (devref, UTs, etc.).
2) Switch all neutron's callback imports over to neutron-lib's.
3) Have all sub-projects using callbacks move their imports over to use
neutron-lib's callbacks implementation.
4) Remove the callback shims in neutron-lib once sub-projects are moved
over to lib's callbacks.
5) Follow-on patches moving our existing uses of callbacks to the new
event payload model provided by neutron-lib.callback.events
This patch implements #2 from above, moving all neutron's callback
imports to use neutron-lib's callbacks.
There are also a few places in the UT code that still patch callbacks,
we can address those in step #4 which may need .
Neutron-lib 1.1.0 is now out and contains the portbindings
API definition (as per commit ). This patch moves neutron
references over to the neutron-lib version.
- Consumers using the public constants within neutron's
portbindings API extension must now use the values
When multiple mech drivers are loaded, it's very common to
have on not find agents on a host, we shouldn't emit a warning
in this condition. The mechanism manager will log an error if
there is an actual failure to bind a port.
Sometimes an object requires multiple disjoint actors to complete
a set of tasks before the status of the object should be transitioned
to ACTIVE. The main example of this is when a port is being created.
The L2 agent has to do its business to wire up the VIF, but at the same
time the DHCP agent has to setup the DHCP reservation. This led to
Nova booting the VM when the L2 agent was done even though the DHCP
agent may have been nowhere near ready.
This patch introduces a provisioning blocks mechansim that allows the
entities to be tracked that need to be involved to make a transition
to ACTIVE happen. See the devref in the dependent patch for a high-level
view of how this works.
The ML2 code is updated to use this new mechanism to prevent updating
the port status to ACTIVE without both the DHCP agent and L2 agent
reporting that the port is ready.
The DHCP RPC API required a version bump to allow the port ready
This also adds a devref doc for the provisioning_blocks
module with a high-level overview of how it works in addition
to a detailed description of how it is used specifically with
ML2, the L2 agents, and the DHCP agents.
When binding a port fails, it's really hard right now to
understand the reasons of the failure, unless the log level
is set to debug. In addition to that many log statement
The goal of this patch is to solve these problems.
Currently neutron DCHP scheduler assumes that that every server running
a dhcp-agent can reach every network. Typically the scheduler can
wrongly schedule a vlan network on a dhcp-agent that has no reachability
to the network it's supposed to serve (ex: network's physical_network
Typically such usecase can append if:
* physical_networks are dedicated to a specific service and we don't
want to mix dnsmasqs related to different services (for
* physical_networks are dedicated to a specific rack (see example
diagram http://i.imgur.com/NTBxRxk.png), the rack interconnection can
be handled outside of neutron or inside when routed-networks will be
This change makes the DHCP scheduler network reachability aware by
querying plugin's filter_hosts_with_network_access method.
This change provides an implementation for ML2 plugin delegating host
filtering to its mechanism drivers: it aggregates the filtering done by
each mechanism or disables filtering if any mechanism doesn't overload
default mechanism implementation (for backward compatibility with
out-of-tree mechanisms). Every in-tree mechanism overloads the default
implementation: OVS/LB/SRIOV mechanisms use their agent mapping to filter
hosts, l2pop/test/logger ones return empty set (they provide to "L2
This change provides a default implementation for other plugins
filtering nothing (for backward compatibility), they can overload it to
provide their own implementation.
Such host filtering has some limitations if a dhcp-agent is on a host
handled by multiple l2 mechanisms with one mechanism claiming network
reachability but not the one handling dhcp-agent ports. Indeed the
host is able to reach the network but not dhcp-agent ports! Such
limitation will be handled in a follow-up change using host+vif_type
Co-Authored-By: Cedric Brandily <email@example.com>
The previous message was misleading because it made it
sound like port binding was being attempted even though
the agent is dead. However, the actual logic is that
binding will be completely skipped if the agent is dead.
This patch updates the message to make that clear and also
provides the port ID as part of the warning so operators
without debugging enabled can see which ports failed.
- This does NOT break other projects that rely on neutron.i18n,
as this change includes a debtcollector shim to maintain those
older entry points, until they can migrate.
- Also updates _i18n.py to the latest pattern defined by oslo_i18n
- Guidance and template are from the reference:
It's mostly a matter of changing imports to a new location.
Non-obvious changes needed:
* pass overwrite= argument to oslo_context since oslo.log reads context
from its thread local store and not local.store from incubator
* don't store context at local.store now that there is no code that
would consume it
* LOG.deprecated() -> versionutils.report_deprecated_feature()
* dropped LOG.audit check from hacking rule since now the method does
* WritableLogger is now located in oslo_log.loggers
Dropped log module from the tree. Also dropped local module that is now
of no use (and obsolete, as per oslo team).
Added versionutils back to openstack-common.conf since now we use the
module directly from neutron code and not just as a dependency of some
other oslo-incubator module.
Note: tempest tests are expected to be broken now, so instead of fixing
all the oslo.log related issues for the subtree in this patch, I only
added TODOs with directions for later fix.
Port binding failure is an error and should be reported as such.
Additionally, if a port binding fails on a host due to missing
bridge mappings, it's currently quite a mystery to find out. This
should be logged instead of requiring users to debug code. Not
everyone enjoys debugging Python, as weird as that is!
I refactored out the common code in check_segment_for_agent
in order to make logging more robust for all agent-based mechanism
drivers. The OVS and LB mech drivers already log due to a bridge
mappings mismatch and the other agent based mech drivers
will now log as well.
The following ML2 driver API changes are required to support
hierarchical port binding:
* Add segments_to_bind PortContext property containing the list of
network segments with which a mechanism driver should try to bind
the port. All mechanism drivers that bind ports should now use this
property in place of network.network_segments, which contains only
the network's static segments.
* Replace several PortContext properties (bound_segment, bound_driver,
original_bound_segment, original_bound_driver) with new properties
(binding_levels, top_bound_segment, bottom_bound_segment,
original_bottom_bound_segment) in order to represent hierarchical
* Add stubbed-out continue_binding() method to PortContext, allowing
mechanism drivers to partially bind the port.
All existing drivers and unit tests are updated accordingly.
The DB schema changes and logic required for hierarchical port binding
will be implemented in dependent patches.
Gerrit Spec: https://review.openstack.org/#/c/139886/
Partially-implements: blueprint ml2-hierarchical-port-binding
Mostly trivial import changes.
- oslo.i18n no longer provide install() method to inject _() into
globals(), so removed all calls to it;
- removed Babel from dependencies (it will now be grabbed by oslo.i18n);
- updated tox.ini to ignore import violations for oslo.i18n.
All the existing LOG.info, LOG.warning, LOG.error and LOG.critical
messages should have _LI, _LW, _LE and _LC respectively.
Also, debug level log shouldn't be translated.
This patch set will cover the ml2 directory under neutron/plugins.
The ML2 plugin now calls the bind_port() operation on the registered
mechanism drivers outside of any enclosing DB transaction. Ports are
created or updated in one transaction, then a binding is established
if possible, and finally a second transaction commits the binding
With [re]binding moved outside the DB transaction that triggered it,
it is now possible that multiple threads or processes will
concurrently try to bind the same port, or that the port will be
updated between transactions. Concurrent attempts to bind the same
port are allowed to proceed, which results are used is resolved in the
second transaction, and binding is retried if necessary.
Improvements to the Cisco Nexus driver and unit tests from Rich Curran
needed due to the binding changes are also included.
The API implemented by ML2 mechanism drivers included three methods
related to port binding that were called within DB transactions, but
that could potentially involve communication with controllers or
devices that should not be done within transactions. A subsequent
patch will move the calls to bind_port() outside of tranactions. This
patch eliminates the other two methods from the MechanismDriver API.
The validate_port_binding() method was previously called on the bound
mechanism driver to check whether an existing binding was still valid,
so that the port could be rebound if something changed. But since nova
has no way to handle changes to binding:vif_type or
binding:vif_details after a port is initially plugged, this turned out
not to be useful, so the method has been removed from the
MechanismDriver API. Now, once a port is successfully bound, the
binding remains until the port is deleted or any of it's
binding:host_id, binding:vnic_type, or binding:profile attribute
values are changed.
The unbind_port() method was previously called on the bound mechanism
driver as an existing binding was removed. This method was not used by
any existing mechanism drivers, and was redundant with the
update_port_precommit() and update_port_postcommit() methods that are
called on all mechanism drivers when an existing binding is removed,
so this method has also been removed from the driver API.
Eliminating the unbind_port() call allows the binding details to be
made available via the PortContext in delete_port_postcommit() calls,
completing the resolution of bug 1276395.