[neutron] Network segment ranges feature

Nate Johnston nate.johnston at redhat.com
Fri Feb 21 20:41:31 UTC 2020

On Fri, Feb 21, 2020 at 05:23:54PM +0000, Rodolfo Alonso wrote:
> Hello Neutrinos:
> First of all, a reference: https://bugs.launchpad.net/neutron/+bug/1863423
> I detected some problems with this feature. The service plugin, when enabled and according to the
> spec [1], should segregate the segmentation range in several ranges. Each one (or many) of those
> ranges could be assigned to a project. When a network is created in a specific project, should
> receive a segmentation ID from the project network segment ranges. In case of not having any range
> assigned, a segmentation ID from a default range will be provided.
> How the current implementation actually works: When a driver is loaded (VLAN, VXLAN, GRE or Geneve),
> it creates a default network segment range, based on the static configuration provided in the plugin
> ("network_vlan_ranges", "vni_ranges", etc). Then the admin can create project specific network
> segment ranges (remember: always per driver type). Those project specific ranges cannot overlap but
> the project specific ranges CAN overlap the default one. A valid state could be:
>   - Default:  100:1000
>   - Project1: 100:200
>   - Project2: 200:300
> When assigning segmentation IDs to new networks, the driver will query [2]:
> - The existing ranges per project.
> - The default range (always present).
> The result is that, if the project network segment range runs out of segment IDs, it will retrieve
> those ones from the default range. That will lead, eventually, to a clash between ranges. Project 1
> will be able to allocate a network with a segmentation ID from Project 2 range. E.g.: [3]
> The problem is how the queries are done: [4] --> select one of each commented line to reproduce
> "query_project_id" and "query_shared" in [2].
> Now we know the feature is not properly working, my question is what the proper behaviour should be.
> Some alternatives:
> 1) If a project has one or more network segment ranges, the segmentation ID should be retrieved ONLY
> from those ranges. If a project does not have any range, then it will retrieve from the shared pool
> BUT NEVER selecting a segment ID belonging to other project ID (ufff this query is going to be
> complex).  --> IMO, the best solution.

I like this.  I would say that we should maintain a state of all parts of the
range that have already been assigned.  We load that into memory at process
start and then we compare against it before we allow any other range requests to
be implemented.

My inclination would be to, at start, load all ranges up into a bit vector array
that indicates what sections of the default range are in use.  Also comvert the
request into a bit vector array. 

- Assuming 1 is available and 0 is allocated
- If there are any zero bits in "defaultrange | rangerequest" then you are
  allocating a used range
- Adding a range as marked off in the bit vector is as simple as "defaultrange &

So I think this will not be difficult to implement, and can be done in a way
that avoids nasty SQL.

> 2) If a project has one or more network segment ranges, the segmentation ID should be retrieved
> first from those ranges and then from the shared one, BUT NEVER selecting a segment ID belonging to
> other project ID. Same for range-less projects.  --> IMO, if the administrator has assigned a range
> for a project, the project should ONLY use this pool. This is not a good solution.
> Can I have your feedback?
> Regards.
> [1]
> https://specs.openstack.org/openstack/neutron-specs/specs/stein/network-segment-range-management.html
> [2]https://github.com/openstack/neutron/blob/master/neutron/plugins/ml2/drivers/helpers.py#L89-L121
> [3]http://paste.openstack.org/show/789872/
> [4]http://paste.openstack.org/show/789873/

More information about the openstack-discuss mailing list