summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReedip <reedip.banerjee@nectechnologies.in>2017-06-03 06:07:38 +0000
committerZhaoBo <zhaobo6@huawei.com>2018-01-18 08:25:40 +0800
commit66eb7e172912acbeb7670d7154a9686bb0726c47 (patch)
treebe0d4b3ce3c6509280b181c650f62a47c4cf7e2b
parent28f2a4357b6f562a003db9f860cbb956905bdeab (diff)
Spec for Port Forwarding
The following spec specifies the Port Forwarding extension for Floating IPs. And intro a new sub resource into floatingip for port forwarding support. Depends-On: If40305044c9dfe0024b64bd3921232bb0a6c9372 Change-Id: Ib2c47b585538bbc067a488e34fd0fc8097314f98 Partial-Bug: #1491317
Notes
Notes (review): Code-Review+2: Slawek Kaplonski <slawek@kaplonski.pl> Code-Review+2: Miguel Lavalle <miguel.lavalle@huawei.com> Code-Review+2: Brian Haley <haleyb.dev@gmail.com> Workflow+1: Miguel Lavalle <miguel.lavalle@huawei.com> Code-Review+1: yanpeifei <yanpeifei@gohighsec.com> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Thu, 01 Mar 2018 10:27:49 +0000 Reviewed-on: https://review.openstack.org/470596 Project: openstack/neutron-specs Branch: refs/heads/master
-rw-r--r--specs/queens/port-forwarding.rst567
1 files changed, 567 insertions, 0 deletions
diff --git a/specs/queens/port-forwarding.rst b/specs/queens/port-forwarding.rst
new file mode 100644
index 0000000..ee26b1e
--- /dev/null
+++ b/specs/queens/port-forwarding.rst
@@ -0,0 +1,567 @@
1..
2 This work is licensed under a Creative Commons Attribution 3.0 Unported
3 License.
4
5 http://creativecommons.org/licenses/by/3.0/legalcode
6
7===================
8Port Forwarding API
9===================
10
11https://blueprints.launchpad.net/neutron/+spec/port-forwarding
12
13Port forwarding is a common feature in networking and more specifically in PaaS
14and SaaS cloud systems which aim at reusing the same public IP for different
15clients that use different VMs for their services.
16
17This is especially relevant for deployments which lack a large number of public
18IPs they can assign.
19
20Common use case for this feature is a client requesting a specific service,
21where the serving platform (PaaS, SaaS) allocates a VM to run the service and
22then allocates a client port to access this service.
23This means that various clients use the same public IP, but the TCP/UDP
24destination port is used to distinguish between the end point VMs.
25
26Example, a mapping for web servers:
27
28* client1 172.24.4.2:4001 TCP => maps to 10.0.0.2 port 80 TCP (VM1)
29* client2 172.24.4.2:4002 TCP => maps to 10.0.0.3 port 80 TCP (VM2)
30
31This spec will focus on port forwarding based on Floating IPs. A future spec
32will be submitted for port forwarding based on routers external gateway
33interface.
34
35
36Problem Description
37===================
38
39* In environments constrained with limited IPs, operators would like
40 to reuse public IPs instead of assigning to each VM its own public
41 IP (Floating IP).
42
43* Docker supports a port-mapping feature and hence a big eco-system of
44 automation orchestration and management plugins leverage it.
45 We would like to make Neutron compatible for these tools and systems
46 and provide a similar API [#foot1]_.
47
48
49Proposed Change
50===============
51Introduce port forwarding API and implementation to Floating IPs.
52
53The user can define various port forwarding rules on the Floating IPs
54containing the internal/client port and the external/destination port,
55connected with the VM they want to expose. And users would be allowed to create
56port forwarding rules only on a "free" Floating IP, i.e. a Floating IP which is
57not directly associated with a Fixed IP of a tenant's VM.
58
59We will have four deployment variants:
60
61a) Legacy Router: For the generic Router deployment, the port forwarding rules
62would be installed in the Router namespace on the network node and forwarding
63functions would be performed.
64
65b) HA Router: For the HA Router deployment, the port forwarding rule will be
66installed in both the ACTIVE and the BACKUP Router namespaces on the network
67nodes they are located on.
68
69c) DVR: As [#foot2]_ has been merged, we now have the ability to create
70centralized Floating IPs in a DVR supported deployment.
71This helps in mapping the Compute nodes where the destination VM is present
72with the centralized FIP for Port forwarding. This mechanism will centralize
73a floating IP not only when it is associated with a port bound to a host with
74the ``dvr_no_external`` option enabled, but also when port forwarding
75attributes are added to it.
76
77d) DVR + HA: If the created router is not an HA router, then we can proceed
78with option (c). While if the router is an HA router, then we will use the
79centralized HA router to install the port forwarding rules.
80
81In all deployment variants, the port forwarding entry NATs a specific
82Floating IP:Port and protocol to a specific Neutron port (and a private IP that
83is attached to this port). That means it will maintain a mapping like
84"FIP:extport protocol" to "Neutron Port Fixed IP:intport protocol". So if a
85Neutron Port contains multiple Fixed IPs, then it will be allowed to create
86multiple port forwarding entries for a particular Neutron port, with different
87external ports, such as:
88
89* FIPX:EXTPORTX PROTOCOLA => Neutron PortQ Fixed IPA:INTPORTA PROTOCOLA (VM1)
90* FIPX:EXTPORTY PROTOCOLA => Neutron PortQ Fixed IPB:INTPORTA PROTOCOLA (VM1)
91
92However, the same Fixed IP:intport socket cannot be mapped with different
93protocols.
94
95If the Neutron port is deleted, the port forwarding entries that match this
96port are also deleted. Same is applicable in case the Floating IP is deleted.
97
98
99Data Model Impact
100-----------------
101
102The following new table is added as part of the port forwarding feature::
103
104 CREATE TABLE port_forwarding (
105 id CHAR(36) NOT NULL PRI KEY,
106 floating_ip_id VARCHAR(36) NOT NULL,
107 external_port INT NOT NULL,
108 internal_neutron_port_id VARCHAR(36) NOT NULL FOREIGN KEY,
109 protocol CHAR(4) NOT NULL,
110 socket VARCHAR(20) NOT NULL,
111 CONSTRAINT floating_ip_id_external_port_constraint UNIQUE (floating_ip_id, external_port),
112 CONSTRAINT internal_neutron_port_id_socket_constraint UNIQUE (
113 internal_neutron_port_id, socket)
114 );
115
116The ``socket`` column will store the string like 'Fixed IP:Port'.
117
118.. note:: This table lacks ``project_id``, as the owner of this
119 ``port_forwarding`` must be the owner of associated Floating IP. So
120 there is a project_id check for preventing association of
121 Floating IP to internal Neutron Port if their ``project_id`` are
122 different. Also, allow the association that Floating IP/internal
123 Neutron Port exists on a shared network for admin users in different
124 project_id cases, such as FloatingIP from a shared public network
125 created by a admin user and a Neutron Port from a particular
126 internal tenant network created by the tenant user, then admin user
127 want a association of them which have different project_ids. For
128 general users, there is only the same project_id case.
129
130Sub Resource Extension
131----------------------
132
133Neutron ``floatingips`` will be extended with a sub resource
134``port_forwarding``, it will contain some fields to expose the
135``port_forwarding`` assigned to the ``floatingip`` resource.
136
137For this new feature, a new service plugin will be introduced, and the
138following methods will be added:
139
140* 'create_floatingip_port_forwarding()'
141* 'delete_floatingip_port_forwarding()'
142* 'get_floatingip_port_forwarding()'
143* 'get_floatingip_port_forwardings()'
144
145For update operation, we will extend the function in the future if possible.
146But for now, we will just support create/delete/get functions.
147
148So the attributes map of new sub resource would be like:
149
150.. code-block:: python
151
152 SUB_RESOURCE_ATTRIBUTE_MAP = {
153 'port_forwarding': {
154 'parent': {'collection_name': 'floatingips',
155 'member_name': 'floatingip'},
156 'parameters': {
157 'external_port': {'allow_post': True, 'allow_put': False,
158 'convert_to':
159 convert_validate_port_value,
160 'is_visible': True},
161 'internal_port': {'allow_post': True, 'allow_put': False,
162 'convert_to':
163 convert_validate_port_value,
164 'is_visible': True},
165 'internal_ip_address': {'allow_post': True,
166 'allow_put': False,
167 'validate': {
168 'type:ip_address_or_none': None},
169 'is_visible': True},
170 'protocol': {'allow_post': True, 'allow_put': False,
171 'validate': {
172 'type:values': constants.IPTABLES_PROTOCOL_MAP.keys()},
173 'is_visible': True,
174 'convert_to': converters.convert_to_protocol},
175 'internal_port_id': {'allow_post': True,
176 'allow_put': False,
177 'validate': {'type:int':None},
178 'is_visible': True},
179 }
180 }
181 }
182
183REST API Impact
184---------------
185
186The idea is to extend the Floating IP Rest API with a new extension
187``floating_ip_port_forwarding`` with the below defined attributes.
188
189.. list-table:: Floating IP extension
190
191 * - Attribute Name
192 - Type
193 - CRUD
194 - Default Value
195 - Description
196 * - port_forwardings
197 - List
198 - R
199 - None
200 - The associated 'port-forwarding' sub resource with the particular
201 Floating IP resource.
202
203The Floating IP extension definition would be expanded as :
204
205.. code-block:: python
206
207 RESOURCE_ATTRIBUTE_MAP = {
208 'floatingips': {
209 'port_forwardings': {'allow_post': False,
210 'allow_put': False,
211 'is_visible': True, 'default': None}
212 }
213 }
214
215This new field will be exposed in the response during GET/POST/PUT requests of
216Floating IP resource. That means users can not change the forwarding resources
217through CRU FloatingIP, only can create the forwardings one by one with the new
218port forwarding API which will be introduced below.
219
220For example, GET a Floating IP:
221
222GET /v2.0/floatingips/<floatingip-uuid>
223
224::
225
226 {
227 "floatingip": {
228 "floating_network_id": "376da547-b977-4cfe-9cba-275c80debf57",
229 "router_id": "d23abc8d-2991-4a55-ba98-2aaea84cc72f",
230 "fixed_ip_address": "",
231 "floating_ip_address": "172.24.4.228",
232 "project_id": "4969c491a3c74ee4af974e6d800c62de",
233 "tenant_id": "4969c491a3c74ee4af974e6d800c62de",
234 "status": "ACTIVE",
235 "port_id": "",
236 "id": "2f245a7b-796b-4f26-9cf9-9e82d248fda7",
237 "port_forwardings": [
238 {
239 "internal_ip_address": "10.0.0.3",
240 "protocol": "tcp",
241 "internal_port": "22",
242 "external_port": "7001"
243 },
244 {
245 "internal_ip_address": "192.168.4.32",
246 "protocol": "tcp",
247 "internal_port": "22",
248 "external_port": "7002"
249 }
250 ]
251 }
252 }
253
254For the new sub resource 'port_forwarding', a new url will be introduced:
255
256* /v2.0/floatingips/<floatingip-uuid>/port_forwardings
257
258List Port Forwardings
259~~~~~~~~~~~~~~~~~~~~~
260
261GET /v2.0/floatingips/<floatingip-uuid>/port_forwardings
262
263::
264
265 {
266 "port_forwardings": [
267 {
268 "id": "ae34051f-aa6c-4c75-abf5-50dc9ac99ef3",
269 "external_port": "7003",
270 "internal_port": "22",
271 "internal_ip_address": "10.0.0.10",
272 "protocol": "tcp",
273 "internal_port_id": "b930d7f6-ceb7-40a0-8b81-a425dd994ccf"
274 },
275 {
276 "id": "915a14a6-867b-4af7-83d1-70efceb146f9",
277 "external_port": "7004",
278 "internal_port": "22",
279 "internal_ip_address": "10.0.0.11",
280 "protocol": "tcp",
281 "internal_port_id": "0c56df5d-ace5-46c8-8f4c-45fa4e334d18"
282 }
283 ]
284 }
285
286.. list-table:: Response Parameters
287 :header-rows: 1
288
289 * - Parameter
290 - Style
291 - Type
292 - Description
293 * - port_forwardings
294 - plain
295 - xsd:list
296 - A list of *port_forwarding* objects
297
298More parameters see :ref:`show_port_forwarding`
299
300.. _show_port_forwarding:
301
302Show Port Forwarding
303~~~~~~~~~~~~~~~~~~~~
304
305GET /v2.0/floatingips/<floatingip-uuid>/port_forwardings/<port-forwarding-id>
306
307::
308
309 {
310 "port_forwarding": {
311 "id": "ae34051f-aa6c-4c75-abf5-50dc9ac99ef3",
312 "external_port": "7003",
313 "internal_port": "22",
314 "internal_ip_address": "10.0.0.10",
315 "protocol": "tcp",
316 "internal_port_id": "b930d7f6-ceb7-40a0-8b81-a425dd994ccf"
317 }
318 }
319
320.. list-table:: Response Parameters
321 :header-rows: 1
322
323 * - Parameter
324 - Style
325 - Type
326 - Description
327 * - port_forwarding
328 - plain
329 - xsd:dict
330 - A *port_forwarding* object
331 * - id
332 - plain
333 - xsd:string
334 - The ID of *port_forwarding* object
335 * - external_port
336 - plain
337 - xsd:string
338 - The exposed external protocol port number
339 * - internal_port
340 - plain
341 - xsd:string
342 - The port forwarding mapped internal protocol port number
343 * - internal_ip_address
344 - plain
345 - xsd:string
346 - The IP Address from the fixed ips of a particular port
347 * - protocol
348 - plain
349 - xsd:string
350 - The traffic protocol type, such as TCP or UDP. Default value is 'TCP'.
351 * - internal_port_id
352 - plain
353 - xsd:string
354 - The Neutron internal Port ID.
355
356Create Port Forwarding
357~~~~~~~~~~~~~~~~~~~~~~
358
359POST /v2.0/floatingips/<floatingip-uuid>/port_forwardings
360
361.. list-table::Request Parameters
362 :header-rows: 1
363
364 * - Parameter
365 - Style
366 - Type
367 - Description
368 * - port_forwarding
369 - plain
370 - xsd:dict
371 - A *port_forwarding* Object
372 * - external_port (mandatory)
373 - plain
374 - xsd:string
375 - The exposed external protocol port number
376 * - internal_port (mandatory)
377 - plain
378 - xsd:string
379 - The port forwarding mapped internal protocol port number
380 * - protocol (optional, default = 'TCP')
381 - plain
382 - xsd:string
383 - The traffic protocol type, such as TCP or UDP. Default value is 'TCP'.
384 * - internal_port_id (mandatory)
385 - plain
386 - xsd:string
387 - The Neutron internal Port ID.
388 * - internal_ip_address (optional, default = The first fixed ip address of
389 port)
390 - plain
391 - xsd:string
392 - The IP Address from the fixed ips of a particular port
393
394::
395
396 {
397 "port_forwarding": {
398 "external_port": "7233",
399 "internal_port": "22",
400 "internal_port_id": "b930d7f6-ceb7-40a0-8b81-a425dd994ccf"
401 }
402 }
403
404Response parameters
405
406see :ref:`show_port_forwarding`
407
408::
409
410 {
411 "port_forwarding": {
412 "id": "f8a44de0-fc8e-45df-93c7-f79bf3b01c95",
413 "external_port": "7233",
414 "internal_port": "22",
415 "internal_ip_address": "192.168.43.33",
416 "protocol": "tcp",
417 "internal_port_id": "b930d7f6-ceb7-40a0-8b81-a425dd994ccf"
418 }
419 }
420
421Delete Port Forwarding
422~~~~~~~~~~~~~~~~~~~~~~
423
424DELETE /v2.0/floatingips/<floatingip-uuid>/port_forwardings/<port-forwarding-id>
425
426This operation does not accept a request body and does not return a response
427body.
428
429Effects on Existing Floating IP APIs
430------------------------------------
431
432Slight adjustment to existing Floating IP APIs:
433
434* Create a Floating IP just the same with current behavior.
435
436* Associate a Neutron internal port with a Floating IP, if the requested url
437 is the same as previous, the Floating IP will work as 1:1 DNAT like current
438 behavior. If the request with the new url, that means the request needs a
439 port-forwarding function towards the Floating IP.
440
441* Get a Floating IP resource will be the same as before if the Floating IP
442 resource had already associated with a neutron port for 1:1 DNAT. If a
443 Floating IP resource contains more than 1 port-forwarding sub resource, it is
444 better to show the ``port-forwardings`` summary in the Floating IP response
445 body to distinguish which Floating IP resource is available for different
446 requirements, such as 1:1 DNAT, port-forwarding.
447
448Command Line Client Impact
449--------------------------
450Openstack Client would have additional options ``portforwarding`` for
451Floating IP CLI, which would define the port-forwarding characteristics.
452
453Security Impact
454---------------
455Port forwarding is similar in nature to centralized DNAT, so should not pose
456additional security implications. But if users actually want to use Port
457forwarding, they must make sure to allow the associated ingress Security Group
458towards the internal ip which is used by the neutron port of their VMs.
459
460Notifications Impact
461--------------------
462Depends on the implementation spec
463
464Other End User Impact
465---------------------
466None
467
468Performance Impact
469------------------
470Performance testing must be conducted to see what is the overhead
471of enabling this feature, of course that if the feature is
472disabled no performance impact should be noticed.
473
474IPv6 Impact
475-----------
476IPv6 is not supported
477
478Other Deployer Impact
479---------------------
480Deployer will be able to leverage port forwarding for a unique way to reach a
481private VM/Container without wasting new public IPs
482
483Developer Impact
484----------------
485Future SNAT distribution plans should take port forwarding into consideration.
486Kuryr can leverage port forwarding for feature compatibility with Docker port
487mapping.
488
489Alternatives
490------------
491Users can use an external VM that provide this NAT capability or assign a new
492Floating IP for each VM.
493
494
495Implementation
496==============
497
498Assignee(s)
499-----------
500
501Primary assignees:
502 reedip <reedip.banerjee@nectechnologies.in>
503
504Other contributors:
505 gal-sagie <gal.sagie@gmail.com>
506
507 tian-mingming <tian.mingming@h3c.com>
508
509 zhaobo <zhaobo6@huawei.com>
510
511Work Items
512----------
513
5141) API Implementation
5152) DB Implementation
5163) Reference implementation
5174) Tests
5185) Documentation
519
520
521Dependencies
522============
523None
524
525
526Testing
527=======
528
529Tempest Tests
530-------------
531Need to add tempest tests
532
533Functional Tests
534----------------
535Need to add functional tests
536
537API Tests
538---------
539Need to add API tests
540
541Fullstack Tests
542---------------
543Need to add Fullstack tests.
544
545
546Documentation Impact
547====================
548
549User Documentation
550------------------
551Needs user documentation
552
553Developer Documentation
554-----------------------
555Needs devref documentation
556
557
558References
559==========
560
561.. [#foot1] https://docs.docker.com/engine/userguide/networking/default_network/binding/
562.. [#foot2] https://review.openstack.org/#/c/485333/20
563.. [#foot3] https://ask.openstack.org/en/question/75190/neutron-port-forwarding-qrouter-vms/
564.. [#foot4] http://www.gossamer-threads.com/lists/openstack/dev/34307
565.. [#foot5] http://openstack.10931.n7.nabble.com/Neutron-port-forwarding-for-router-td46639.html
566.. [#foot6] http://openstack.10931.n7.nabble.com/Neutron-port-forwarding-from-gateway-to-internal-hosts-td32410.html
567.. [#foot7] https://blueprints.launchpad.net/neutron/+spec/neutron-ovs-dvr