[neutron] Network segment ranges feature

Rodolfo Alonso ralonsoh at redhat.com
Sat Feb 22 20:06:47 UTC 2020


Hello

On Fri, 2020-02-21 at 15:41 -0500, Nate Johnston wrote:
> 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:
> > 
> > VLAN:
> >   - 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 &
>   rangerequest"
> 
> So I think this will not be difficult to implement, and can be done in a way
> that avoids nasty SQL.
> 
> Nate
> 

That's a good idea and originally I designed a solution based on a cached mapping. But then I
realized that, every time we use some kind of shortcut to the DB mapping any resource in a
controller, then we have plenty of problems with HA. The DB is, IMO, the best resource for sync
resources in HA. There is a way to do this in two steps:
- Retrieve the ranges assigned to other projects. Those ranges, by definition, do no overlap. Then
join if possible those ranges to have the minimum set of gaps. E.g.: 0-100,120-500,720-1000.
- The second DB call will be very similar to the current one, but using those ranges in the opposite
way, to filter out those segment IDs within them but belonging to the default one.

Regardless of the implementation, what I would like is to have is an idea of how the feature should
work. IMO, (1) is the desirable way: if a project has segment ranges, use them (and only those
segments). If not, use the default range but never a segment ID belonging to another project range.

>  
> > 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