summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--specs/newton/address-scope-subnet-pool-mapping.rst233
1 files changed, 187 insertions, 46 deletions
diff --git a/specs/newton/address-scope-subnet-pool-mapping.rst b/specs/newton/address-scope-subnet-pool-mapping.rst
index 01bcf9e..2569eed 100644
--- a/specs/newton/address-scope-subnet-pool-mapping.rst
+++ b/specs/newton/address-scope-subnet-pool-mapping.rst
@@ -30,50 +30,104 @@ Proposed change
30The current mapping of GBP l3_policy to a list of Neutron routers will be 30The current mapping of GBP l3_policy to a list of Neutron routers will be
31augmented with the mapping to a Neutron address_scope (one each for IPv4 and 31augmented with the mapping to a Neutron address_scope (one each for IPv4 and
32IPv6) and subnetpools. This spec attempts to lay the foundation for the use 32IPv6) and subnetpools. This spec attempts to lay the foundation for the use
33of IPv6, and dual-stack (both IPv4 and IPv6) in the l3_policy. The API and DB 33of IPv6 and dual-stack (both IPv4 and IPv6) in the l3_policy. The API and DB
34model constructs to support this are being addressed in this spec. The details 34model constructs to support this are addressed in this spec.
35for IPv6 implementation are not addresed in this spec and will be laid out in 35
36a forthcoming complementary spec. 36The ip_version attribute of GBP's l3_policy is extended to allow specifying
37 37dual-stack support. Currently allowed values for ip_version are 4 for IPv4
38For each address family (IPv4 and/or IPv6) the l3_policy supports, there will 38and 6 for IPv6. The value 46 may now be used to enable dual-stack support.
39be a 1-1 mapping between GBP l3_policy and the Neutron address_scope, 39
40and 1-many mapping between GBP l3_policy and Neutron subnetpools. The 1-many 40For each address family (IPv4 and/or IPv6) indicated by an l3_policy, there
41will be a 1-1 mapping between GBP l3_policy and a Neutron address_scope,
42and a 1-many mapping between GBP l3_policy and Neutron subnetpools. The 1-many
41mapping allows for use cases where the l3_policy (and address_scope) is shared 43mapping allows for use cases where the l3_policy (and address_scope) is shared
42across tenants, while the subnetpool is created per tenant and not shared. 44across tenants, while the subnetpool is created per tenant and not shared.
43 45
44The subnetpools that are explicitly associated with the l3_policy, need to 46The ip_pool parameter now allows comma-delimited prefixes, as well just a
45belong to the same address_scope that is associated with that l3_policy. GBP 47single prefix. CIDRs from different address families may be used together
48in the same ip_pool parameter. The ip_pool parameter may also be None,
49which is intended for use with the default subnetpool Neutron extension.
50
51The default subnetpool Neutron extension is used to control the desired behavior
52when an implicit workflow is used on L3 policies with mapping drivers [#]_.
53Default subnetpools are only used when the ip_version requests a given address
54family (IPv4 or IPv6) and the user hasn't explicitly provided any CIDRs for
55that address family (e.g. via the ip_pool parameter or a subnetpool).
56
57Within each indicated address family, the subnetpools that are explicitly
58associated with the l3_policy must all belong to the same address_scope. GBP
46will allocate subnets only from the subnetpools that are associated with the 59will allocate subnets only from the subnetpools that are associated with the
47corresponding l3_policy. The list of subnets associated with the l3_policy can 60corresponding l3_policy. The list of subnets associated with the l3_policy can
48be updated by adding or removing subnetpools (subnetpools which are currently 61be updated by adding or removing subnetpools (subnetpools which are currently
49being used cannot be removed). 62being used cannot be removed), or by updating the prefixes attribute of
63subnetpools already associated with the l3_policy
64
65The definition of the subnet_prefix_length is modified to refine it's use.
66The subnet_prefix_length now only applies to IPv4 prefixes. It also is
67used as the default subnet prefix length for all subnets allocated from
68IPv4 subnetpools for the given l3_policy. In order to help backward-
69compatibilty, values longer than 30 will now be ignored. IPv6 subnets
70that are allocated will always use a prefix length of 64.
71
72Two properties of address scopes are address namespace and routability.
73Address namespace simply means that addresses are guaranteed to be unique
74within an address scope. Routability means that a neutron router may only
75forward between interfaces that have subnets which were allocated from
76subnetpools with the same address scope (note: forwarding is still possible
77via NAT when they aren't in the same scope). It's worth pointing out that
78since address scopes can span multiple l3_policies, the address uniqueness is
79applied across the l3_policies. However, even though sharing a common address
80scope implies routability across l3_policies, actual connectivity between
81l3_policies is not implied because each l3_policy maps to a distinct neutron
82router. In GBP, connectivity between l3_policies remains subject to a PTG
83providing a PRS that is consumed by an external_policy and a PTG in the
84other l3_policy consuming that external_policy.
50 85
51Let's consider the various combinations that are possible based on the choice 86Let's consider the various combinations that are possible based on the choice
52of implicit and explicit arguments. 87of implicit and explicit arguments.
53 88
54#. A l3_policy is created with an ip_pool, ip_version, and 89#. A l3_policy is created with an ip_pool, ip_version, and
55 subnet_prefix_length but no address_scope or subnetpool(s) are provided. In 90 subnet_prefix_length but no address_scope or subnetpool(s) are provided. In
56 this case an address_scope with the address family of the ip_version will be 91 this case an address_scope for each address family specified by ip_version
57 created implicitly, and a subnetpool with the ip_pool CIDR will be created 92 is created, and a subnetpool with prefixes for each CIDR for that address
58 in that address_scope. If the l3_policy is shared, the implcitily create 93 family found in ip_pool is created in that address_scope. If the l3_policy
59 address_scope and subnetpool will also be shared. The ip_version of the 94 is shared, the implcitily created address_scope and subnetpool will also be
60 l3_policy will be used for the address_scope and the subnetpool. The 95 shared. The default_prefixlen for IPv4 subnetpools will be set to the
61 default_prefixlen, will be set to the subnet_prefix_length of the l3_policy. 96 subnet_prefix_length of the l3_policy, and for IPv6 subnetpools it will be
62 (The min_prefixlen, and max_prefixlen of the subnetpool will default to 8 97 set to 64 (the min_prefixlen and max_prefixlen of the IPv4 subnetpool will
63 and 32 as defined in Neutron.) 98 default to 8 and 32, and to 64 and 128 for the IPv6 subnetpool, as defined
64 99 in Neutron).
65#. A l3_policy is created with an ip_pool, ip_version, subnet_prefix_length, 100
66 and address_scope, but no subnetpools are provided. In this case the 101#. A l3_policy is created with an ip_version and subnet_prefix_length
67 ip_version of the l3_policy is ignored, and the subnetpool is created in 102 (IPv4 only), but no address_scope, subnetpool(s), or prefix in ip_pool
68 this address_scope as before. If both, v4 and v6, address_scopes are 103 are provided for that address family. There are two possibilities in this
69 provided, a subnetpool will be created for each family. If a subnetpool 104 scenario:
70 already exists in this address_scope, and overlaps with the CIDR of the 105
71 ip_pool, an exception will be raised. 106 * A default subnetpool (defined in neutron) exists for an address family
72 107 indicated by ip_version. In this case the default subnetpool and its
73#. A l3_policy is created with an address_scope, and subnetpool(s). Since the 108 address scope are associated with the l3_policy.
74 ip_version is already defined for the address_scope and the CIDR and prefix 109
75 lengths are defined for the subnetpool(s), the ip_version, ip_pool and 110 * A default subnetpool does not exist for an address family indicated
76 subnet_prefix_length of the l3_policy will be ignored if provided. 111 by ip_version. In this case, an exception is raised.
112
113#. A l3_policy is created with an address_scope of the indicated address
114 family, but no subnetpools of that address family are provided. If there
115 are CIDRs in ip_pool from the same address family, then they are used as
116 prefixes to create a new subnetpool within the specified address scope.
117 If a subnetpool already exists in this address_scope, and overlaps with
118 the CIDR of the ip_pool, an exception will be raised. If no CIDRs from the
119 same address family are found, a check is made to see if a default
120 subnetpool sharing the same address scope exists. If it does, then that
121 subnetpool is associated with the l3_policy. If none exists, then an
122 exception is raised.
123
124#. A l3_policy is created with an address_scope and subnetpool(s). Since the
125 supplied subnetpool(s) define how subnets will be allocated, any supplied
126 ip_pool for that address family is ignored. The ip_pool value returned
127 from any l3_policy API call will contain the set of prefixes used for
128 allocating subnets for all address families specified in ip_version. In
129 this case, that will be the aggregate prefixes from the explicitly
130 passed subnetpools.
77 131
78#. A l3_policy is created with one or more subnetpools. The address_scope 132#. A l3_policy is created with one or more subnetpools. The address_scope
79 associated with the subnetpool(s) is associated with the l3_policy. If 133 associated with the subnetpool(s) is associated with the l3_policy. If
@@ -87,9 +141,9 @@ In all of the above cases, if subnetpools are associated with an address_scope
87that is associated with a l3_policy, they will be considered for subnet 141that is associated with a l3_policy, they will be considered for subnet
88allocation only if they are explicitly associated with the l3_policy. 142allocation only if they are explicitly associated with the l3_policy.
89 143
90A minor variation of all the above cases is the one where either or all of 144A minor variation of all the above cases is the one where either or both of
91ip_pool, ip_version, and subnet_prefix_length are not provided. In such cases 145the ip_pool and subnet_prefix_length are not provided. In such cases the GBP
92the GBP defaults for these attributes will be used (but overridden by the 146defaults for these attributes will be used (but overridden by the
93corresponding attributes in the address_scope and subnetpools if any of those 147corresponding attributes in the address_scope and subnetpools if any of those
94are explicitly provided). 148are explicitly provided).
95 149
@@ -105,16 +159,8 @@ subnetpool was implicitly created by GBP.
105It should be noted that the ip_pool, subnet_prefix_length, and ip_version 159It should be noted that the ip_pool, subnet_prefix_length, and ip_version
106attributes of the l3_policy may only have effect at the l3_policy creation 160attributes of the l3_policy may only have effect at the l3_policy creation
107time. In the body of response for GET l3_policy call, the ip_pool will be set 161time. In the body of response for GET l3_policy call, the ip_pool will be set
108to a comma separated string consisting of a list of CIDRs corresponding to each 162to a comma delimited string consisting of a list of CIDRs made up of the
109subnetpool currently present in the address_scope. To preserve API backward 163prefixes attribute values of all subnetpools associated with the l3_policy.
110compatibility (i.e. to not immediately break existing clients and integration
111tests), the subnet_prefix_length and ip_version will be set to the
112corresponding subnet_prefix_length and ip_version when only one CIDR is
113present. If more than one CIDR is present, these will be set to null. In the
114case where multiple CIDRs are present, more details like the prefix length of
115the subnets that are drawn from the subnetpools corresponding to these CIDRs
116can be obtained by navigating the resource relationship from l3_policy to
117address_scope to subnetpool.
118 164
119 165
120Data model impact 166Data model impact
@@ -152,7 +198,7 @@ backward incompatible DB change and a script will be provided to migrate data
152from existing deployments to this new structure. The script will essentially 198from existing deployments to this new structure. The script will essentially
153create an address_scope and subnetpool for each existing l3_policy. 199create an address_scope and subnetpool for each existing l3_policy.
154 200
155In addition, additional tables will be added to track the Neutron address_scope 201Additional tables will be added to track the Neutron address_scope
156and subnetpool resources created by GBP. 202and subnetpool resources created by GBP.
157 203
158:: 204::
@@ -177,6 +223,43 @@ and subnetpool resources created by GBP.
177 nullable=False, primary_key=True) 223 nullable=False, primary_key=True)
178 224
179 225
226The size of the ip_pool column in the L3Policy table is increased from
22764 to 256 in order to account for more than a single prefix. Once all
228policy drivers use subnetpools, this column could be removed from
229the DB.
230
231::
232
233 class L3Policy(model_base.BASEV2, BaseSharedGbpResource):
234 """Represents a L3 Policy with a non-overlapping IP address space."""
235 __tablename__ = 'gp_l3_policies'
236 type = sa.Column(sa.String(15))
237 __mapper_args__ = {
238 'polymorphic_on': type,
239 'polymorphic_identity': 'base'
240 }
241 ip_version = sa.Column(sa.Integer, nullable=False)
242 ip_pool = sa.Column(sa.String(256))
243 subnet_prefix_length = sa.Column(sa.Integer)
244 l2_policies = orm.relationship(L2Policy, backref='l3_policy')
245 external_segments = orm.relationship(
246 ESToL3PAssociation, backref='l3_policies',
247 cascade='all, delete-orphan')
248
249A similar increase (64 to 256) is needed to the proxy_ip_pool parameter in the
250DB for that extension, as well as the ability to make the field nullable:
251
252::
253
254 class ProxyIPPoolMapping(model_base.BASEV2):
255 __tablename__ = 'gp_proxy_ip_pool_mapping'
256
257 l3_policy_id = sa.Column(
258 sa.String(36), sa.ForeignKey('gp_l3_policies.id', ondelete="CASCADE"),
259 primary_key=True)
260 proxy_ip_pool = sa.Column(sa.String(256), nullable=True)
261 proxy_subnet_prefix_length = sa.Column(sa.Integer, nullable=False)
262
180REST API impact 263REST API impact
181--------------- 264---------------
182 265
@@ -204,6 +287,63 @@ extension definition
204 'is_visible': True, 'default': None}, 287 'is_visible': True, 'default': None},
205 }, 288 },
206 289
290In addition, the l3_policy itself needs modifications to support:
291
292 * the new value 46 for ip_version:
293 * a type change for ip_pool (subnet to string)
294
295the defaultt value for ip_pool is defined in a new config file
296variable. The variable has the same value as the old default, which
297ensures backwards-compatibility, but also allows for the default
298value to be something else (e.g. dual-stack prefixes, empty prefix,
299IPv6 prefix only, etc.).
300
301::
302
303 L3_POLICIES: {
304 'id': {'allow_post': False, 'allow_put': False,
305 'validate': {'type:uuid': None}, 'is_visible': True,
306 'primary_key': True},
307 'name': {'allow_post': True, 'allow_put': True,
308 'validate': {'type:gbp_resource_name': None},
309 'default': '', 'is_visible': True},
310 'description': {'allow_post': True, 'allow_put': True,
311 'validate': {'type:string': None},
312 'is_visible': True, 'default': ''},
313 'tenant_id': {'allow_post': True, 'allow_put': False,
314 'validate': {'type:string': None},
315 'required_by_policy': True, 'is_visible': True},
316 'status': {'allow_post': False, 'allow_put': False,
317 'is_visible': True},
318 'status_details': {'allow_post': False, 'allow_put': False,
319 'is_visible': True},
320 'ip_version': {'allow_post': True, 'allow_put': False,
321 'convert_to': conv.convert_to_int,
322 'validate': {'type:values': [4, 6, 46]},
323 'default': 4, 'is_visible': True},
324 'ip_pool': {'allow_post': True, 'allow_put': False,
325 'validate': {'type:string_or_none': None},
326 'default': GBP_CONF.default_ip_pool, 'is_visible': True},
327 'subnet_prefix_length': {'allow_post': True, 'allow_put': True,
328 'convert_to': conv.convert_to_int,
329 # This parameter only applies to ipv4
330 # prefixes. For IPv4 legal values are
331 # 2 to 30. For ipv6, this parameter
332 # is ignored
333 'default': 24, 'is_visible': True},
334 'l2_policies': {'allow_post': False, 'allow_put': False,
335 'validate': {'type:uuid_list': None},
336 'convert_to': conv.convert_none_to_empty_list,
337 'default': None, 'is_visible': True},
338 attr.SHARED: {'allow_post': True, 'allow_put': True,
339 'default': False, 'convert_to': conv.convert_to_boolean,
340 'is_visible': True, 'required_by_policy': True,
341 'enforce_policy': True},
342 'external_segments': {
343 'allow_post': True, 'allow_put': True, 'default': None,
344 'validate': {'type:external_dict': None},
345 'convert_to': conv.convert_none_to_empty_dict, 'is_visible': True},
346 },
207 347
208Security impact 348Security impact
209--------------- 349---------------
@@ -320,3 +460,4 @@ References
320========== 460==========
321 461
322.. [#] http://docs.openstack.org/developer/neutron/devref/address_scopes.html 462.. [#] http://docs.openstack.org/developer/neutron/devref/address_scopes.html
463.. [#] https://review.openstack.org/#/c/282021/