Dual-stack L3-Policy mapping
The initial spec for address scope and subnetpool support mentioned support for dual-stack. This commit extends the existing spec to define that support. Change-Id: I0966d200c75c1d571a15687062020528e97648da Partially-implements: blueprint address-scope-mapping
This commit is contained in:
parent
449643f905
commit
c200c8997f
|
@ -30,50 +30,94 @@ Proposed change
|
|||
The current mapping of GBP l3_policy to a list of Neutron routers will be
|
||||
augmented with the mapping to a Neutron address_scope (one each for IPv4 and
|
||||
IPv6) and subnetpools. This spec attempts to lay the foundation for the use
|
||||
of IPv6, and dual-stack (both IPv4 and IPv6) in the l3_policy. The API and DB
|
||||
model constructs to support this are being addressed in this spec. The details
|
||||
for IPv6 implementation are not addresed in this spec and will be laid out in
|
||||
a forthcoming complementary spec.
|
||||
of IPv6 and dual-stack (both IPv4 and IPv6) in the l3_policy. The API and DB
|
||||
model constructs to support this are addressed in this spec.
|
||||
|
||||
For each address family (IPv4 and/or IPv6) the l3_policy supports, there will
|
||||
be a 1-1 mapping between GBP l3_policy and the Neutron address_scope,
|
||||
and 1-many mapping between GBP l3_policy and Neutron subnetpools. The 1-many
|
||||
The ip_version attribute of GBP's l3_policy is extended to allow specifying
|
||||
dual-stack support. Currently allowed values for ip_version are 4 for IPv4
|
||||
and 6 for IPv6. The value 46 may now be used to enable dual-stack support.
|
||||
|
||||
For each address family (IPv4 and/or IPv6) enabled by an l3_policy, there
|
||||
will be a 1-1 mapping between GBP l3_policy and a Neutron address_scope,
|
||||
and a 1-many mapping between GBP l3_policy and Neutron subnetpools. The 1-many
|
||||
mapping allows for use cases where the l3_policy (and address_scope) is shared
|
||||
across tenants, while the subnetpool is created per tenant and not shared.
|
||||
|
||||
The subnetpools that are explicitly associated with the l3_policy, need to
|
||||
belong to the same address_scope that is associated with that l3_policy. GBP
|
||||
Within each enabled address family, the subnetpools that are explicitly
|
||||
associated with the l3_policy must all belong to the same address_scope. GBP
|
||||
will allocate subnets only from the subnetpools that are associated with the
|
||||
corresponding l3_policy. The list of subnets associated with the l3_policy can
|
||||
be updated by adding or removing subnetpools (subnetpools which are currently
|
||||
being used cannot be removed).
|
||||
being used cannot be removed), or by updating the prefixes attribute of
|
||||
subnetpools already associated with the l3_policy
|
||||
|
||||
The implicit subnetpools extension is used to control the desired behavior
|
||||
when an implicit workflow is used with L3 policies [#]_. Implicit subnetpools
|
||||
are only used when the ip_version requests a given address family (IPv4 or
|
||||
IPv6) and the user hasn't explicitly provided any CIDRs for that address
|
||||
family (e.g. via the ip_pool parameter, or a subnetpool and/or address scope).
|
||||
The current implicit subnetpool semantics do not account for different address
|
||||
families. Therefore, the semantics must be amended as follows to account for a
|
||||
subnetpool per address family:
|
||||
|
||||
- Only one implicit subnetpool *per address family* can exist *per tenant*
|
||||
(if not shared)
|
||||
- Only one shared implicit subnetpool *per address family* can exist in the
|
||||
whole system. This doesn't affect private implicit subnetpools
|
||||
|
||||
The subnet_prefix_length is now allowed to be None. The point of adding
|
||||
the None value is for use with explicit subnetpools, where the default prefix
|
||||
length should be determined by each pool, rather than by this parameter. It
|
||||
also is limited to use with v4 subnetpools, as the only v6 default prefix
|
||||
supported by the L3 Policy is /64.
|
||||
|
||||
Two properties of address scopes are address namespace and routability.
|
||||
Address namespace simply means that addresses are guaranteed to be unique
|
||||
within an address scope. Routability means that a neutron router may only
|
||||
forward between interfaces that have subnets which were allocated from
|
||||
subnetpools with the same address scope (note: forwarding is still possible
|
||||
via NAT when they aren't in the same scope). It's worth pointing out that
|
||||
since address scopes can span multiple l3_policies, the address uniqueness is
|
||||
applied across the l3_policies. However, even though sharing a common address
|
||||
scope implies routability across l3_policies, actual connectivity between
|
||||
l3_policies is not implied because each l3_policy maps to a distinct router.
|
||||
In GBP, connectivity between l3_policies remains subject to a PTG providing
|
||||
a PRS that is consumed by an external_policy.
|
||||
|
||||
Let's consider the various combinations that are possible based on the choice
|
||||
of implicit and explicit arguments.
|
||||
|
||||
#. A l3_policy is created with an ip_pool, ip_version, and
|
||||
subnet_prefix_length but no address_scope or subnetpool(s) are provided. In
|
||||
this case an address_scope with the address family of the ip_version will be
|
||||
created implicitly, and a subnetpool with the ip_pool CIDR will be created
|
||||
in that address_scope. If the l3_policy is shared, the implcitily create
|
||||
address_scope and subnetpool will also be shared. The ip_version of the
|
||||
l3_policy will be used for the address_scope and the subnetpool. The
|
||||
default_prefixlen, will be set to the subnet_prefix_length of the l3_policy.
|
||||
(The min_prefixlen, and max_prefixlen of the subnetpool will default to 8
|
||||
and 32 as defined in Neutron.)
|
||||
subnet_prefix_length (IPv4 only), but no address_scope or subnetpool(s)
|
||||
are provided for that address family. There are two possibilities in this
|
||||
scenario:
|
||||
|
||||
#. A l3_policy is created with an ip_pool, ip_version, subnet_prefix_length,
|
||||
and address_scope, but no subnetpools are provided. In this case the
|
||||
ip_version of the l3_policy is ignored, and the subnetpool is created in
|
||||
this address_scope as before. If both, v4 and v6, address_scopes are
|
||||
provided, a subnetpool will be created for each family. If a subnetpool
|
||||
already exists in this address_scope, and overlaps with the CIDR of the
|
||||
ip_pool, an exception will be raised.
|
||||
* An implicit subnetpool exists for an address family enabled by
|
||||
ip_version. In this case the implicit subnetpool and its address
|
||||
scope are associated with the l3_policy and any supplied ip_pool
|
||||
is ignored.
|
||||
* An implicit subnetpool does not exist for an address family enabled
|
||||
by ip_version. In this case an address_scope with the address family
|
||||
enabled by the ip_version will be created, and a subnetpool with the
|
||||
CIDRs of that address family found in the ip_pool value will be
|
||||
created in that address_scope. If no CIDRs for the address family
|
||||
are found in ip_pool, an exception is raised. If the l3_policy is
|
||||
shared, the implicitly created address_scope and subnetpool will
|
||||
also be shared. For IPv4, the default_prefixlen of the subnetpool
|
||||
will be set to the subnet_prefix_length of the l3_policy, the
|
||||
min_prefixlen will be set to 8, and the max_prefixlen will be be
|
||||
set to 32. For IPv6, the default_prefixlen, min_prefixlen, and
|
||||
max_prefixlen of the subnetpool will all be set to 64.
|
||||
|
||||
#. An l3_policy is created with an address_scope of the enabled address
|
||||
family, but no subnetpools of that address family are provided. In this
|
||||
case the subnetpool is created in this address_scope as before. If a
|
||||
subnetpool already exists in this address_scope, and overlaps with the
|
||||
CIDR of the ip_pool, an exception will be raised.
|
||||
|
||||
#. A l3_policy is created with an address_scope, and subnetpool(s). Since the
|
||||
ip_version is already defined for the address_scope and the CIDR and prefix
|
||||
lengths are defined for the subnetpool(s), the ip_version, ip_pool and
|
||||
subnet_prefix_length of the l3_policy will be ignored if provided.
|
||||
supplied subnetpool(s) define how subnets will be allocated, any supplied
|
||||
ip_pool for that address family is ignored.
|
||||
|
||||
#. A l3_policy is created with one or more subnetpools. The address_scope
|
||||
associated with the subnetpool(s) is associated with the l3_policy. If
|
||||
|
@ -87,9 +131,9 @@ In all of the above cases, if subnetpools are associated with an address_scope
|
|||
that is associated with a l3_policy, they will be considered for subnet
|
||||
allocation only if they are explicitly associated with the l3_policy.
|
||||
|
||||
A minor variation of all the above cases is the one where either or all of
|
||||
ip_pool, ip_version, and subnet_prefix_length are not provided. In such cases
|
||||
the GBP defaults for these attributes will be used (but overridden by the
|
||||
A minor variation of all the above cases is the one where either or both of
|
||||
the ip_pool and subnet_prefix_length are not provided. In such cases the GBP
|
||||
defaults for these attributes will be used (but overridden by the
|
||||
corresponding attributes in the address_scope and subnetpools if any of those
|
||||
are explicitly provided).
|
||||
|
||||
|
@ -106,15 +150,7 @@ It should be noted that the ip_pool, subnet_prefix_length, and ip_version
|
|||
attributes of the l3_policy may only have effect at the l3_policy creation
|
||||
time. In the body of response for GET l3_policy call, the ip_pool will be set
|
||||
to a comma separated string consisting of a list of CIDRs corresponding to each
|
||||
subnetpool currently present in the address_scope. To preserve API backward
|
||||
compatibility (i.e. to not immediately break existing clients and integration
|
||||
tests), the subnet_prefix_length and ip_version will be set to the
|
||||
corresponding subnet_prefix_length and ip_version when only one CIDR is
|
||||
present. If more than one CIDR is present, these will be set to null. In the
|
||||
case where multiple CIDRs are present, more details like the prefix length of
|
||||
the subnets that are drawn from the subnetpools corresponding to these CIDRs
|
||||
can be obtained by navigating the resource relationship from l3_policy to
|
||||
address_scope to subnetpool.
|
||||
subnetpool currently present in the address_scope.
|
||||
|
||||
|
||||
Data model impact
|
||||
|
@ -204,6 +240,56 @@ extension definition
|
|||
'is_visible': True, 'default': None},
|
||||
},
|
||||
|
||||
In addition, the l3_policy itself needs modifications to support:
|
||||
|
||||
* the new value 46 for ip_version:
|
||||
* a type change for ip_pool (subnet to string)
|
||||
* change to the conversion for subnet_prefix_length to allow None
|
||||
|
||||
::
|
||||
|
||||
L3_POLICIES: {
|
||||
'id': {'allow_post': False, 'allow_put': False,
|
||||
'validate': {'type:uuid': None}, 'is_visible': True,
|
||||
'primary_key': True},
|
||||
'name': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:gbp_resource_name': None},
|
||||
'default': '', 'is_visible': True},
|
||||
'description': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:string': None},
|
||||
'is_visible': True, 'default': ''},
|
||||
'tenant_id': {'allow_post': True, 'allow_put': False,
|
||||
'validate': {'type:string': None},
|
||||
'required_by_policy': True, 'is_visible': True},
|
||||
'status': {'allow_post': False, 'allow_put': False,
|
||||
'is_visible': True},
|
||||
'status_details': {'allow_post': False, 'allow_put': False,
|
||||
'is_visible': True},
|
||||
'ip_version': {'allow_post': True, 'allow_put': False,
|
||||
'convert_to': conv.convert_to_int,
|
||||
'validate': {'type:values': [4, 6, 46]},
|
||||
'default': 4, 'is_visible': True},
|
||||
'ip_pool': {'allow_post': True, 'allow_put': False,
|
||||
'validate': {'type:string': None},
|
||||
'default': '10.0.0.0/8', 'is_visible': True},
|
||||
'subnet_prefix_length': {'allow_post': True, 'allow_put': True,
|
||||
'convert_to': conv.convert_to_int_if_not_none,
|
||||
# for ipv4 legal values are 2 to 30
|
||||
# for ipv6 legal values are 2 to 127
|
||||
'default': 24, 'is_visible': True},
|
||||
'l2_policies': {'allow_post': False, 'allow_put': False,
|
||||
'validate': {'type:uuid_list': None},
|
||||
'convert_to': conv.convert_none_to_empty_list,
|
||||
'default': None, 'is_visible': True},
|
||||
attr.SHARED: {'allow_post': True, 'allow_put': True,
|
||||
'default': False, 'convert_to': conv.convert_to_boolean,
|
||||
'is_visible': True, 'required_by_policy': True,
|
||||
'enforce_policy': True},
|
||||
'external_segments': {
|
||||
'allow_post': True, 'allow_put': True, 'default': None,
|
||||
'validate': {'type:external_dict': None},
|
||||
'convert_to': conv.convert_none_to_empty_dict, 'is_visible': True},
|
||||
},
|
||||
|
||||
Security impact
|
||||
---------------
|
||||
|
@ -271,7 +357,9 @@ snaiksat + GBP team
|
|||
Work items
|
||||
----------
|
||||
|
||||
API, DB, and driver layer updates to GBP Resources.
|
||||
API, DB, and driver layer updates to GBP Resources. Also work on the CLI and
|
||||
python client to handle either a list or single element for the ip_pool
|
||||
parameter.
|
||||
|
||||
Dependencies
|
||||
============
|
||||
|
@ -320,3 +408,4 @@ References
|
|||
==========
|
||||
|
||||
.. [#] http://docs.openstack.org/developer/neutron/devref/address_scopes.html
|
||||
.. [#] https://review.openstack.org/#/c/419315/
|
||||
|
|
Loading…
Reference in New Issue