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
466a8c2dae
|
@ -30,50 +30,86 @@ 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. Either 46 or 64 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 explicitlyi
|
||||
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 a subnetpool and/or address
|
||||
scope for that address family. The existing implicit subnetpool semantics
|
||||
must be amended 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
|
||||
|
||||
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 but no address_scope or subnetpool(s) are provided.
|
||||
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 the given ip_version
|
||||
In this case the implicit subnetpool and its address scope are
|
||||
associated with the l3_policy and any supplied ip_pool or
|
||||
subnet_prefix_length for that address family are ignored.
|
||||
* An implicit subnetpool does not exist for the given 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.
|
||||
|
||||
In both cases, 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 or subnet_prefix_length for that address family are 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 +123,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).
|
||||
|
||||
|
@ -108,13 +144,13 @@ 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.
|
||||
tests), the subnet_prefix_length will be set to the corresponding
|
||||
subnet_prefix_length when only one CIDR is present. If IPv4 subnetpools with
|
||||
different default_prefixlen values are 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.
|
||||
|
||||
|
||||
Data model impact
|
||||
|
@ -204,6 +240,53 @@ extension definition
|
|||
'is_visible': True, 'default': None},
|
||||
},
|
||||
|
||||
In addition, the l3_policy itself needs a modification to support the new value
|
||||
for ip_version:
|
||||
|
||||
::
|
||||
|
||||
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:subnet': 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,
|
||||
# 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
|
||||
---------------
|
||||
|
@ -320,3 +403,4 @@ References
|
|||
==========
|
||||
|
||||
.. [#] http://docs.openstack.org/developer/neutron/devref/address_scopes.html
|
||||
.. [#] https://review.openstack.org/#/c/419315/
|
||||
|
|
Loading…
Reference in New Issue