Add tap-as-a-service spec
Taken from https://review.openstack.org/#/c/96149/8 . Co-authored-by: YAMAMOTO Takashi <yamamoto@midokura.com> Co-authored-by: Fawad Khaliq <fawad@plumgrid.com> Change-Id: I703902f08e8d788d10f2bdbc68db500fd26ce60b
This commit is contained in:
parent
1d58d20ede
commit
e3833c5611
473
specs/mitaka/tap-as-a-service.rst
Normal file
473
specs/mitaka/tap-as-a-service.rst
Normal file
@ -0,0 +1,473 @@
|
|||||||
|
..
|
||||||
|
This work is licensed under a Creative Commons Attribution 3.0 Unported
|
||||||
|
License.
|
||||||
|
|
||||||
|
http://creativecommons.org/licenses/by/3.0/legalcode
|
||||||
|
|
||||||
|
============================
|
||||||
|
Tap-as-a-Service for Neutron
|
||||||
|
============================
|
||||||
|
|
||||||
|
|
||||||
|
Launchpad blueprint:
|
||||||
|
|
||||||
|
https://blueprints.launchpad.net/neutron/+spec/tap-as-a-service
|
||||||
|
|
||||||
|
This spec explains an extension for the port mirroring functionality. Port
|
||||||
|
mirroring involves sending a copy of packets ingressing and/or egressing one
|
||||||
|
port (where ingress means entering a VM and egress means leaving a VM) to
|
||||||
|
another port, (usually different from the packet’s original destination).
|
||||||
|
A port could be attached to a VM or a networking resource like router.
|
||||||
|
|
||||||
|
While the blueprint describes the functionality of mirroring Neutron ports as
|
||||||
|
an extension to the port object, the spec proposes to offer port mirroring as a
|
||||||
|
service, which will enable more advanced use-cases (e.g. intrusion detection)
|
||||||
|
to be deployed.
|
||||||
|
|
||||||
|
The proposed port mirroring capability shall be introduced in Neutron as a
|
||||||
|
service called "Tap-as-a-Service".
|
||||||
|
|
||||||
|
Problem description
|
||||||
|
===================
|
||||||
|
|
||||||
|
Neutron currently does not support the functionality of port mirroring for
|
||||||
|
tenant networks. This feature will greatly benefit tenants and admins, who
|
||||||
|
want to debug their virtual networks and gain visibility into their VMs by
|
||||||
|
monitoring and analyzing the network traffic associated with them (e.g. IDS).
|
||||||
|
|
||||||
|
This spec focuses on mirroring traffic from one Neutron port to another;
|
||||||
|
future versions may address mirroring from a Neutron port to an arbitrary
|
||||||
|
interface (not managed by Neutron) on a compute host or the network controller.
|
||||||
|
|
||||||
|
Different usage scenarios for the service are listed below:
|
||||||
|
|
||||||
|
1. Tapping/mirroring network traffic ingressing and/or egressing a particular
|
||||||
|
Neutron port.
|
||||||
|
2. Tapping/mirroring all network traffic on a tenant network.
|
||||||
|
3. Tenant or admin be able to do tap/traffic mirroring based on a policy rule
|
||||||
|
and set destination as a Neutron port, which can be linked to a virtual
|
||||||
|
machine as normal Nova operations or to a physical machine via
|
||||||
|
l2-gateway functionality.
|
||||||
|
4. Admin would be able to do packet level network debugging for the virtual network.
|
||||||
|
5. Provide a way for real time analytics based on different criteria, like tenants,
|
||||||
|
ports, traffic types (policy) etc.
|
||||||
|
|
||||||
|
Note that some of the above use-cases are not covered by this proposal, at
|
||||||
|
least for the first step.
|
||||||
|
|
||||||
|
|
||||||
|
Proposed change
|
||||||
|
===============
|
||||||
|
|
||||||
|
The proposal is to introduce a new Neutron service plugin, called
|
||||||
|
‘Tap-as-a-Service’,
|
||||||
|
which provides tapping (port-mirroring) capability for Neutron networks;
|
||||||
|
tenant or provider networks. This service will be modeled similar to other
|
||||||
|
Neutron services such as the firewall, load-balancer, L3-router etc.
|
||||||
|
|
||||||
|
The proposed service will allow the tenants to create a tap service instance
|
||||||
|
to which they can add Neutron ports that need to be mirrored by creating tap
|
||||||
|
flows. The tap service itself will be a Neutron port, which will be the
|
||||||
|
destination port for the mirrored traffic.
|
||||||
|
|
||||||
|
The destination Tap-as-a-Service Neutron port should be created beforehand on
|
||||||
|
a network owned by the tenant who is requesting the service. The ports to be
|
||||||
|
mirrored that are added to the service must be owned by the same tenant who
|
||||||
|
created the tap service instance. Even on a shared network, a tenant will only
|
||||||
|
be allowed to mirror the traffic from ports that they own on the shared
|
||||||
|
network and not traffic from ports that they do not own on the shared network.
|
||||||
|
|
||||||
|
The ports owned by the tenant that are mirrored can be on networks other
|
||||||
|
than the network on which tap service port is created. This allows the tenant
|
||||||
|
to mirror traffic from any port it owns on a network on to the same
|
||||||
|
Tap-as-a-Service Neutron port.
|
||||||
|
|
||||||
|
The tenant can launch a VM specifying the tap destination port for the VM
|
||||||
|
interface (--nic port-id=tap_port_uuid), thus receiving mirrored traffic for
|
||||||
|
further processing (dependent on use case) on that VM.
|
||||||
|
|
||||||
|
The following would be the work flow for using this service from a tenant's
|
||||||
|
point of view
|
||||||
|
|
||||||
|
0. Create a Neutron port which will be used as the destination port.
|
||||||
|
This can be a part of ordinary VM launch.
|
||||||
|
|
||||||
|
1. Create a tap service instance, specifying the Neutron port.
|
||||||
|
|
||||||
|
2. If you haven't yet, launch a monitoring or traffic analysis VM and
|
||||||
|
connect it to the destination port for the tap service instance.
|
||||||
|
|
||||||
|
3. Associate Neutron ports with a tap service instance if/when they need to be
|
||||||
|
monitored.
|
||||||
|
|
||||||
|
4. Disassociate Neutron ports from a tap service instance if/when they no
|
||||||
|
longer need to be monitored.
|
||||||
|
|
||||||
|
5. Destroy a tap-service instance when it is no longer needed.
|
||||||
|
|
||||||
|
6. Delete the destination port when it is no longer neeeded.
|
||||||
|
|
||||||
|
Please note that the normal work flow of launching a VM is not affected while
|
||||||
|
using TaaS.
|
||||||
|
|
||||||
|
|
||||||
|
Alternatives
|
||||||
|
------------
|
||||||
|
|
||||||
|
As an alternative to introducing port mirroring functionality under Neutron
|
||||||
|
services, it could be added as an extension to the existing Neutron v2 APIs.
|
||||||
|
|
||||||
|
|
||||||
|
Data model impact
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Tap-as-a-Service introduces the following data models into Neutron as database
|
||||||
|
schemas.
|
||||||
|
|
||||||
|
1. tap_service
|
||||||
|
|
||||||
|
+-------------+--------+----------+-----------+---------------+-------------------------+
|
||||||
|
| Attribute | Type | Access | Default | Validation/ | Description |
|
||||||
|
| Name | | (CRUD) | Value | Conversion | |
|
||||||
|
+=============+========+==========+===========+===============+=========================+
|
||||||
|
| id | UUID | R, all | generated | N/A | UUID of the tap |
|
||||||
|
| | | | | | service inst. |
|
||||||
|
+-------------+--------+----------+-----------+---------------+-------------------------+
|
||||||
|
| project_id | String | CR, all | Requester | N/A | ID of the |
|
||||||
|
| | | | | | project creating |
|
||||||
|
| | | | | | the service |
|
||||||
|
+-------------+--------+----------+-----------+---------------+-------------------------+
|
||||||
|
| name | String | CRU, all | Empty | N/A | Name for the service |
|
||||||
|
| | | | | | inst. |
|
||||||
|
+-------------+--------+----------+-----------+---------------+-------------------------+
|
||||||
|
| description | String | CRU, all | Empty | N/A | Description of the |
|
||||||
|
| | | | | | service inst. |
|
||||||
|
+-------------+--------+----------+-----------+---------------+-------------------------+
|
||||||
|
| port_id | UUID | CR, all | N/A | UUID of a | An existing Neutron port|
|
||||||
|
| | | | | valid Neutron | to which traffic will |
|
||||||
|
| | | | | port | be mirrored |
|
||||||
|
+-------------+--------+----------+-----------+---------------+-------------------------+
|
||||||
|
| status | String | R, all | N/A | N/A | The operation status of |
|
||||||
|
| | | | | | the resource |
|
||||||
|
| | | | | | (ACTIVE, PENDING_foo, |
|
||||||
|
| | | | | | ERROR, ...) |
|
||||||
|
+-------------+--------+----------+-----------+---------------+-------------------------+
|
||||||
|
|
||||||
|
2. tap_flow
|
||||||
|
|
||||||
|
+----------------+--------+----------+-----------+---------------+-------------------------+
|
||||||
|
| Attribute | Type | Access | Default | Validation/ | Description |
|
||||||
|
| Name | | (CRUD) | Value | Conversion | |
|
||||||
|
+================+========+==========+===========+===============+=========================+
|
||||||
|
| id | UUID | R, all | generated | N/A | UUID of the |
|
||||||
|
| | | | | | tap flow instance. |
|
||||||
|
+----------------+--------+----------+-----------+---------------+-------------------------+
|
||||||
|
| name | String | CRU, all | Empty | N/A | Name for the tap flow |
|
||||||
|
| | | | | | inst. |
|
||||||
|
+----------------+--------+----------+-----------+---------------+-------------------------+
|
||||||
|
| description | String | CRU, all | Empty | N/A | Description of the |
|
||||||
|
| | | | | | tap flow inst. |
|
||||||
|
+----------------+--------+----------+-----------+---------------+-------------------------+
|
||||||
|
| tap_service_id | UUID | CR, all | N/A | Valid tap | UUID of the tap |
|
||||||
|
| | | | | service UUID | service instance. |
|
||||||
|
+----------------+--------+----------+-----------+---------------+-------------------------+
|
||||||
|
| source_port | UUID | CR, all | N/A | UUID of a | UUID of the Neutron |
|
||||||
|
| | | | | valid Neutron | port that needed to be |
|
||||||
|
| | | | | port | mirrored |
|
||||||
|
+----------------+--------+----------+-----------+---------------+-------------------------+
|
||||||
|
| direction | ENUM | CR, all | BOTH | | Whether to mirror the |
|
||||||
|
| | (IN, | | | | traffic leaving or |
|
||||||
|
| | OUT, | | | | arriving at the |
|
||||||
|
| | BOTH) | | | | source port |
|
||||||
|
| | | | | | IN: Network -> VM |
|
||||||
|
| | | | | | OUT: VM -> Network |
|
||||||
|
+----------------+--------+----------+-----------+---------------+-------------------------+
|
||||||
|
| status | String | R, all | N/A | N/A | The operation status of |
|
||||||
|
| | | | | | the resource |
|
||||||
|
| | | | | | (ACTIVE, PENDING_foo, |
|
||||||
|
| | | | | | ERROR, ...) |
|
||||||
|
+----------------+--------+----------+-----------+---------------+-------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
REST API impact
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Tap-as-a-Service shall be offered over the RESTFull API interface under
|
||||||
|
the following namespace:
|
||||||
|
|
||||||
|
http://wiki.openstack.org/Neutron/TaaS/API_1.0
|
||||||
|
|
||||||
|
The resource attribute map for TaaS is provided below:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
direction_enum = ['IN', 'OUT', 'BOTH']
|
||||||
|
|
||||||
|
RESOURCE_ATTRIBUTE_MAP = {
|
||||||
|
'tap_service': {
|
||||||
|
'id': {'allow_post': False, 'allow_put': False,
|
||||||
|
'validate': {'type:uuid': None}, 'is_visible': True,
|
||||||
|
'primary_key': True},
|
||||||
|
'project_id': {'allow_post': True, 'allow_put': False,
|
||||||
|
'validate': {'type:string': None},
|
||||||
|
'required_by_policy': True, 'is_visible': True},
|
||||||
|
'name': {'allow_post': True, 'allow_put': True,
|
||||||
|
'validate': {'type:string': None},
|
||||||
|
'is_visible': True, 'default': ''},
|
||||||
|
'description': {'allow_post': True, 'allow_put': True,
|
||||||
|
'validate': {'type:string': None},
|
||||||
|
'is_visible': True, 'default': ''},
|
||||||
|
'port_id': {'allow_post': True, 'allow_put': False,
|
||||||
|
'validate': {'type:uuid': None},
|
||||||
|
'is_visible': True},
|
||||||
|
'status': {'allow_post': False, 'allow_put': False,
|
||||||
|
'is_visible': True},
|
||||||
|
},
|
||||||
|
'tap_flow': {
|
||||||
|
'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:string': None},
|
||||||
|
'is_visible': True, 'default': ''},
|
||||||
|
'description': {'allow_post': True, 'allow_put': True,
|
||||||
|
'validate': {'type:string': None},
|
||||||
|
'is_visible': True, 'default': ''},
|
||||||
|
'tap_service_id': {'allow_post': True, 'allow_put': False,
|
||||||
|
'validate': {'type:uuid': None},
|
||||||
|
'required_by_policy': True, 'is_visible': True},
|
||||||
|
'source_port': {'allow_post': True, 'allow_put': False,
|
||||||
|
'validate': {'type:uuid': None},
|
||||||
|
'required_by_policy': True, 'is_visible': True},
|
||||||
|
'direction': {'allow_post': True, 'allow_put': False,
|
||||||
|
'validate': {'type:string': direction_enum},
|
||||||
|
'is_visible': True},
|
||||||
|
'status': {'allow_post': False, 'allow_put': False,
|
||||||
|
'is_visible': True},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Security impact
|
||||||
|
---------------
|
||||||
|
|
||||||
|
A TaaS instance comprises a collection of source Neutron ports (whose
|
||||||
|
ingress and/or egress traffic are being mirrored) and a destination Neutron
|
||||||
|
port (where the mirrored traffic is received). Security Groups will be
|
||||||
|
handled differently for these two classes of ports, as described below:
|
||||||
|
|
||||||
|
Destination Side:
|
||||||
|
|
||||||
|
Ingress Security Group filters, including the filter that prevents MAC-address
|
||||||
|
spoofing, will be disabled for the destination Neutron port. This will ensure
|
||||||
|
that all of the mirrored packets received at this port are able to reach the
|
||||||
|
monitoring VM attached to it.
|
||||||
|
|
||||||
|
Source Side:
|
||||||
|
|
||||||
|
Ideally it would be nice to mirror all packets entering and/or leaving the
|
||||||
|
virtual NICs associated with the VMs that are being monitored. This means
|
||||||
|
capturing ingress traffic after it passes the inbound Security Group filters
|
||||||
|
and capturing egress traffic before it passes the outbound Security Group
|
||||||
|
filters.
|
||||||
|
|
||||||
|
However, due to the manner in which Security Groups are currently implemented
|
||||||
|
in OpenStack (i.e. north of the Open vSwitch ports, using Linux IP Tables) this
|
||||||
|
is not possible because port mirroring support resides inside Open vSwitch.
|
||||||
|
Therefore, in the first version of TaaS, Security Groups will be ignored for
|
||||||
|
the source Neutron ports; this effectively translates into capturing ingress
|
||||||
|
traffic before it passes the inbound Security Group filters and capturing
|
||||||
|
egress traffic after it passes the outbound Security Group filters. In other
|
||||||
|
words, port mirroring will be implemented for all packets entering and/or
|
||||||
|
leaving the Open vSwitch ports associated with the respective virtual NICs of
|
||||||
|
the VMs that are being monitored.
|
||||||
|
|
||||||
|
There is a separate effort that has been initiated to implement Security Groups
|
||||||
|
within OpenvSwitch. A later version of TaaS may make use of this feature, if
|
||||||
|
and when it is available, so that we can realize the ideal behavior described
|
||||||
|
above. It should be noted that such an enhancement should not require a change
|
||||||
|
to the TaaS data model.
|
||||||
|
|
||||||
|
Keeping data privacy aspects in mind and preventing the data center admin
|
||||||
|
from snooping on tenant's network traffic without their knowledge, the admin
|
||||||
|
shall not be allowed to mirror traffic from any ports that belong to tenants.
|
||||||
|
Hence creation of 'Tap_Flow' is only permitted on ports that are owned by the
|
||||||
|
creating tenant.
|
||||||
|
|
||||||
|
If an admin wants to monitor tenant's traffic, the admin will have to join that
|
||||||
|
tenant as a member. This will ensure that the tenant is aware that the admin
|
||||||
|
might be monitoring their traffic.
|
||||||
|
|
||||||
|
|
||||||
|
Notifications impact
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
A set of new RPC calls for communication between the TaaS server and agents
|
||||||
|
are required and will be put in place as part of the reference implementation.
|
||||||
|
|
||||||
|
|
||||||
|
IPv6 impact
|
||||||
|
--------------------
|
||||||
|
None
|
||||||
|
|
||||||
|
|
||||||
|
Other end user impact
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Users will be able to invoke and access the TaaS APIs through
|
||||||
|
python-neutronclient.
|
||||||
|
|
||||||
|
|
||||||
|
Performance Impact
|
||||||
|
------------------
|
||||||
|
|
||||||
|
The performance impact of mirroring traffic needs to be examined and
|
||||||
|
quantified. The impact of a tenant potentially mirroring all traffic from
|
||||||
|
all ports could be large and needs more examination.
|
||||||
|
|
||||||
|
Some alternatives to reduce the amount of mirrored traffic are listed below.
|
||||||
|
|
||||||
|
1. Rate limiting on the ports being mirrored.
|
||||||
|
2. Filters to select certain flows ingressing/egressing a port to be
|
||||||
|
mirrored.
|
||||||
|
3. Having a quota on the number of TaaS Flows that can be defined by the
|
||||||
|
tenant.
|
||||||
|
|
||||||
|
|
||||||
|
Other deployer impact
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Configurations for the service plugin will be added later.
|
||||||
|
|
||||||
|
A new bridge (br-tap) mentioned in Implementation section.
|
||||||
|
|
||||||
|
|
||||||
|
Developer impact
|
||||||
|
----------------
|
||||||
|
This will be a new extension API, and will not affect the existing API.
|
||||||
|
|
||||||
|
|
||||||
|
Community impact
|
||||||
|
----------------
|
||||||
|
None
|
||||||
|
|
||||||
|
|
||||||
|
Follow up work
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Going forward, TaaS would be incorporated with Service Insertion [2]_ similar
|
||||||
|
to other existing services like FWaaS, LBaaS, and VPNaaS.
|
||||||
|
|
||||||
|
While integrating Tap-as-a-Service with Service Insertion the key changes to
|
||||||
|
the data model needed would be the removal of 'network_id' and 'port_id' from
|
||||||
|
the 'Tap_Service' data model.
|
||||||
|
|
||||||
|
Some policy based filtering rules would help alleviate the potential performance
|
||||||
|
issues.
|
||||||
|
|
||||||
|
We might want to ensure exclusive use of the destination port.
|
||||||
|
|
||||||
|
We might want to create the destination port automatically on tap-service
|
||||||
|
creation, rather than specifying an existing port. In that case, network_id
|
||||||
|
should be taken as a parameter for tap-service creation, instead of port_id.
|
||||||
|
|
||||||
|
We might want to allow the destination port be used for purposes other than
|
||||||
|
just launching a VM on it, for example the port could be used as an
|
||||||
|
'external-port' [1]_ to get the mirrored data out from the tenant virtual
|
||||||
|
network on a device or network not managed by openstack.
|
||||||
|
|
||||||
|
We might want to introduce a way to tap a whole traffic for the specified
|
||||||
|
network.
|
||||||
|
|
||||||
|
We need a mechanism to coordinate usage of various resources with other
|
||||||
|
agent extensions. E.g. OVS flows, tunnel IDs, VLAN IDs.
|
||||||
|
|
||||||
|
|
||||||
|
Implementation
|
||||||
|
==============
|
||||||
|
|
||||||
|
The reference implementation for TaaS will be based on Open vSwitch. In
|
||||||
|
addition to the existing integration (br-int) and tunnel (br-tun) bridges, a
|
||||||
|
separate tap bridge (br-tap) will be used. The tap bridge provides nice
|
||||||
|
isolation for supporting more complex TaaS features (e.g. filtering mirrored
|
||||||
|
packets) in the future.
|
||||||
|
|
||||||
|
The tapping operation will be realized by adding higher priority flows in
|
||||||
|
br-int, which duplicate the ingress and/or egress packets associated with
|
||||||
|
specific ports (belonging to the VMs being monitored) and send the copies to
|
||||||
|
br-tap. Packets sent to br-tap will also be tagged with an appropriate VLAN id
|
||||||
|
corresponding to the associated TaaS instance (in the initial release these
|
||||||
|
VLAN ids may be reserved from highest to lowest; in later releases it should be
|
||||||
|
coordinated with the Neutron service). The original packets will continue to be
|
||||||
|
processed normally, so as not to affect the traffic patterns of the VMs being
|
||||||
|
monitored.
|
||||||
|
|
||||||
|
Flows will be placed in br-tap to determine if the mirrored traffic should be
|
||||||
|
sent to br-tun or not. If the destination port of a Tap-aaS instance happens to
|
||||||
|
reside on the same host as a source port, packets from that source port will be
|
||||||
|
returned to br-int; otherwise they will be forwarded to br-tun for delivery to
|
||||||
|
a remote node.
|
||||||
|
|
||||||
|
Packets arriving at br-tun from br-tap will get routed to the destination ports
|
||||||
|
of appropriate TaaS instances using the same GRE or VXLAN tunnel network that
|
||||||
|
is used to pass regular traffic between hosts. Separate tunnel IDs will be used
|
||||||
|
to isolate different TaaS instances from one another and from the normal
|
||||||
|
(non-mirrored) traffic passing through the bridge. This will ensure that proper
|
||||||
|
action can be taken on the receiving end of a tunnel so that mirrored traffic
|
||||||
|
is sent to br-tap instead of br-int. Special flows will be used in br-tun to
|
||||||
|
automatically learn about the location of the destination ports of TaaS
|
||||||
|
instances.
|
||||||
|
|
||||||
|
Packets entering br-tap from br-tun will be forwarded to br-int only if the
|
||||||
|
destination port of the corresponding TaaS instance resides on the same host.
|
||||||
|
Finally, packets entering br-int from br-tap will be delivered to the
|
||||||
|
appropriate destination port after the TaaS instance VLAN id is replaced with
|
||||||
|
the VLAN id for the port.
|
||||||
|
|
||||||
|
|
||||||
|
Assignee(s)
|
||||||
|
-----------
|
||||||
|
|
||||||
|
* Vinay Yadhav
|
||||||
|
|
||||||
|
|
||||||
|
Work Items
|
||||||
|
----------
|
||||||
|
|
||||||
|
* TaaS API and data model implementation.
|
||||||
|
* TaaS OVS driver.
|
||||||
|
* OVS agent changes for port mirroring.
|
||||||
|
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
============
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
|
||||||
|
Testing
|
||||||
|
=======
|
||||||
|
|
||||||
|
* Unit Tests to be added.
|
||||||
|
* Functional tests in tempest to be added.
|
||||||
|
* API Tests in Tempest to be added.
|
||||||
|
|
||||||
|
|
||||||
|
Documentation Impact
|
||||||
|
====================
|
||||||
|
|
||||||
|
* User Documentation needs to be updated
|
||||||
|
* Developer Documentation needs to be updated
|
||||||
|
|
||||||
|
|
||||||
|
References
|
||||||
|
==========
|
||||||
|
|
||||||
|
.. [1] External port
|
||||||
|
https://review.openstack.org/#/c/87825
|
||||||
|
|
||||||
|
.. [2] Service base and insertion
|
||||||
|
https://review.openstack.org/#/c/93128
|
||||||
|
|
||||||
|
.. [3] NFV unaddressed interfaces
|
||||||
|
https://review.openstack.org/#/c/97715/
|
Loading…
Reference in New Issue
Block a user