<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0"><channel><title>neutron-specs</title><link>https://specs.openstack.org/openstack/neutron-specs</link><description /><language>en</language><copyright>2026, OpenStack Neutron Team</copyright><item><title>Example Spec - The title of your RFE</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2026.2/placeholder.html</link><description>

&lt;p&gt;Include the URL of your launchpad RFE:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/example-id"&gt;https://bugs.launchpad.net/neutron/+bug/example-id&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Introduction paragraph – why are we doing this feature? A single paragraph of
prose that &lt;strong&gt;deployers, and developers, and operators&lt;/strong&gt; can understand.&lt;/p&gt;
&lt;p&gt;Do you even need to file a spec? Most features can be done by filing an RFE bug
and moving on with life. In most cases, filing an RFE and documenting your
design in the devref folder of neutron docs is sufficient. If the feature
seems very large or contentious, then the drivers team may request a spec, or
you can always file one if desired.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;A detailed description of the problem:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;For a new feature this should be a list of use cases. Ensure that you are clear
about the actors in each use case: End User vs Deployer. Ensure that you identify
which area of the core is being affected; for something completely new, it
should be clear why you are considering it being part of the core.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For a major reworking of something existing it would describe the
problems in that feature that are being addressed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that the RFE filed for this feature will have a description already. This
section is not meant to simply duplicate that; you can simply refer to that
description if it is sufficient, and use this space to capture changes to
the description based on bug comments or feedback on the spec.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;How do you propose to solve this problem?&lt;/p&gt;
&lt;p&gt;This section is optional, and provides an area to discuss your high-level
design at the same time as use cases, if desired.  Note that by high-level,
we mean the “view from orbit” rough cut at how things will happen.&lt;/p&gt;
&lt;p&gt;This section should ‘scope’ the effort from a feature standpoint: how is the
‘neutron end-to-end system’ going to look like after this change? What Neutron
areas do you intend to touch and how do you intend to work on them? The list
below is not meant to be a template to fill in, but rather a jumpstart on the
sorts of areas to consider in your proposed change description.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Am I going to see new CLI commands?
* Is OpenStack CLI covered in addition to neutronclient?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How do you intend to support or affect aspects like:
* Address Management, e.g. IPv6, DHCP
* Routing, e.g. DVR/HA
* Plugins, ML2 Drivers, e.g. OVS, LinuxBridge
* Agents, e.g. metadata
* High level services, e.g. *-aas.
* Scheduling, quota, and policy management, e.g. admin vs user rights
* API and extensions
* Clients
* Impact on services or out-of-tree plugins/drivers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What do you intend to not support in the initial release?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You do not need to detail API or data model changes. Details at that level of
granularity belong in the neutron devref docs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Please add any useful references here. You are not required to have any
reference. Moreover, this specification should still make sense when your
references are unavailable.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 12 Mar 2026 00:00:00 </pubDate></item><item><title>PVLAN Semantics for Provider Networks</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2026.1/pvlan-semantics-for-provider-networks.html</link><description>

&lt;p&gt;RFE: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/2138746"&gt;https://bugs.launchpad.net/neutron/+bug/2138746&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Private VLAN (PVLAN) &lt;a class="footnote-reference brackets" href="#id6" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; is a device isolation mechanism through the
application of special Layer 2 forwarding constraints.&lt;/p&gt;
&lt;p&gt;This spec describes how to implement the PVLAN mechanism by creating a service
plugin on Neutron, that can be extensible to any ML2 mechanism driver, but that
will be mainly focused on the implementation of the ML2/OVN logic.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Current implementations of Security Groups or other networking isolation tools
do not comply with this security-focused approach to device isolation.  PVLAN
is an established mechanism [1] that has well-defined boundaries and rules for
consistent networking management. There is currently not a straight-forward
way of replicating these boundaries and rules to achieve a consistent
implementation of PVLAN in Neutron with existing plugins and/or extensions. A
mix of security groups and security group rules could make a certain
replication but it would not be flexible or robust enough compared to
implementing its own mechanism.&lt;/p&gt;
&lt;p&gt;What PVLAN proposes is a consistent semantic model &lt;a class="footnote-reference brackets" href="#id7" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id8" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; to enforce port
isolation rules:&lt;/p&gt;
&lt;section id="network-attributes"&gt;
&lt;h3&gt;Network attributes&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;pvlan&lt;/strong&gt; &lt;cite&gt;{{enabled | disabled}}&lt;/cite&gt;: enable PVLAN semantics for a network.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="port-attributes"&gt;
&lt;h3&gt;Port attributes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Roles&lt;/strong&gt; for ports (Enforced label if pvlan is enabled):&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Promiscuous:&lt;/strong&gt; Can reach any other port.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Community:&lt;/strong&gt; Can reach only ports within their community + promiscuous.
One port can only be part of one community.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Isolated:&lt;/strong&gt; Can only reach promiscuous, if any.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Community label&lt;/strong&gt; (if applies) &lt;cite&gt;{{ string }}&lt;/cite&gt;: To subgroup community ports&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the following diagram taken from the OVN proof-of-concept &lt;a class="footnote-reference brackets" href="#id9" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; we can
understand how the different VMs would be configured depending on their role.&lt;/p&gt;
&lt;div class="highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;┌────────────────────────────────────────────────────────────────────────┐
│                                                                        │
│                      ┌─────────────────────┐                           │
│                      │   Promiscuous       │ ← Can communicate with    │
│                      │   192.168.1.30      │   ALL ports               │
│                      └──────────┬──────────┘                           │
│                                 │                                      │
│           ┌─────────────────────┼──────────────────────┐               │
│           │                     │                      │               │
│           ▼                     ▼                      ▼               │
│    ┌──────────────────┐ ┌──────────────────┐    ┌──────────────────┐   │
│    │  Isolated        │ │  Community-1     │    │  Community-2     │   │
│    │                  │ │                  │    │                  │   │
│    │  ┌────┐  ┌────┐  │ │  ┌────┐  ┌────┐  │    │  ┌────┐  ┌────┐  │   │
│    │  │iso1│  │iso2│  │ │  │1-c1│◄►│2-c1│  │    │  │1-c2│◄►│2-c2│  │   │
│    │  │.1  │  │.2  │  │ │  │.10 │  │.11 │  │    │  │.20 │  │.21 │  │   │
│    │  └────┘  └────┘  │ │  └────┘  └────┘  │    │  └────┘  └────┘  │   │
│    │                  │ │                  │    │                  │   │
│    └──────────────────┘ └──────────────────┘    └──────────────────┘   │
│   (Can only talk          (Members can talk     (Members can talk      │
│    to Promiscuous)         within community      within community      │
│                            + Promiscuous)        + Promiscuous)        │
│                                                                        │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;A new service plugin of Neutron that will implement new API extension and will
be extensible by the various backend drivers.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The scope of this spec is to complete the driver implementation of
ML2/OVN. Any interested contributor is welcomed to implement the ML2/OVS
backend.&lt;/p&gt;
&lt;/div&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;As described before, there are new attributes present on both networks and
ports.&lt;/p&gt;
&lt;p&gt;New table &lt;strong&gt;networkpvlan&lt;/strong&gt; extending networks:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network_id&lt;/span&gt;&lt;/code&gt; - &lt;cite&gt;UUID type&lt;/cite&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pvlan&lt;/span&gt;&lt;/code&gt; - &lt;cite&gt;boolean type&lt;/cite&gt;. True if PVLAN is enabled. Default: False.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;network_id&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;pvlan&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;2c1b70d6-1ffb-43e8-8069-53f5597c446e&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;networks&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"network"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"pvlan-net-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"admin_state_up"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"pvlan"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="s2"&gt;"network"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"a9254bdb-2613-4a13-ac4c-adc581fba50d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"pvlan-net-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="s2"&gt;"subnets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
     &lt;span class="s2"&gt;"admin_state_up"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"fb0e16da8ce7435c8a444647738e2166"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="s2"&gt;"pvlan"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"fb0e16da8ce7"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;New table &lt;strong&gt;portpvlan&lt;/strong&gt; extending ports:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port_id&lt;/span&gt;&lt;/code&gt; - &lt;cite&gt;UUID type&lt;/cite&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pvlan_type&lt;/span&gt;&lt;/code&gt; - &lt;cite&gt;string type&lt;/cite&gt;. Allowed values: “isolated”, “community”,
“promiscuous”. Default: Promiscuous.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pvlan_community&lt;/span&gt;&lt;/code&gt; - &lt;cite&gt;string type&lt;/cite&gt;. Allowed values: Any string that complies
with Port Group name restriction notes in OVN &lt;a class="footnote-reference brackets" href="#id10" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; — Names are ASCII and must
match &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[a-zA-Z_.][a-zA-Z_.0-9]*&lt;/span&gt;&lt;/code&gt;. Default: None.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;port_id&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;pvlan_type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;pvlan_community&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;7abca15f-a19a-4f4d-a27c-b695ca1ec44b&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;community&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;community_1&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;e66abfad-a681-4a90-a6f7-8efe5e4bd2ae&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;isolated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;NONE&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"pvlan-port-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"network_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"03848825-c4fc-44c1-b510-fc6bf64cc8ef"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"pvlan_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"community"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"pvlan_community"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"community_1"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"e66abfad-a681-4a90-a6f7-8efe5e4bd2ae"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"port_2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"network_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"03848825-c4fc-44c1-b510-fc6bf64cc8ef"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"mac_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"fa:16:3e:a8:70:16"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DOWN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"device_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"f51da0f6-f1e2-48cb-b46d-d37a262f383e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"pvlan_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"community"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"fb0e16da8ce7435c8a444647738e2166"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"pvlan_community"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"community_1"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="sub-resource-extension"&gt;
&lt;h3&gt;Sub Resource Extension&lt;/h3&gt;
&lt;p&gt;It will be created as an extension that extends the parameters for network and
for port:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;COLLECTION_NAME&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;pvlan_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PVLAN_MODE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'enforce_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:boolean'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;converters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_boolean&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;COLLECTION_NAME&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;pvlan_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PVLAN_TYPE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pvlan_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PROMISCUOUS_TYPE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pvlan_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PVLAN_TYPES&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;pvlan_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PVLAN_COMMUNITY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'enforce_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s1"&gt;'type:regex_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pvlan_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;COMMUNITY_NAME_REGEX&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="service-plugin"&gt;
&lt;h3&gt;Service Plugin&lt;/h3&gt;
&lt;p&gt;The new service plugin &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pvlan&lt;/span&gt;&lt;/code&gt; will implement the API extension and will
extend Neutron resources with the attributes needed for port and network. It
will also define the new DB objects and will call the backend driver for the
attribute operations (create / update / delete) implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ml2-ovn-driver-implementation-details"&gt;
&lt;h3&gt;ML2/OVN Driver Implementation details&lt;/h3&gt;
&lt;p&gt;The backend driver needs to implement the operations by consuming Neutron
notifications about creation, deletion and update of the Networks and Ports.&lt;/p&gt;
&lt;p&gt;The operations to be implemented are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Network create (enable pvlan)&lt;/strong&gt; -&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Create &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pvlan_drop_all&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pvlan_isolated&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pvlan_promiscuous&lt;/span&gt;&lt;/code&gt; Port Groups for the network (Logical Switch).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create ACLs for those Port Groups.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Port Group example:&lt;/p&gt;
&lt;div class="highlight-sh notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;_uuid&lt;span class="w"&gt;               &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;6dfac905-892c-44f6-880c-7168399e7240
acls&lt;span class="w"&gt;                &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;f21e358d-ce0b-4741-80bf-a13abeefc221,&lt;span class="w"&gt; &lt;/span&gt;41cfb444-c744-4d4f-be2f-706f17bab37e&lt;span class="o"&gt;]&lt;/span&gt;
external_ids&lt;span class="w"&gt;        &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"neutron:network"&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"cb33079f-9309-4312-bd0f-9d57d20c8c0a"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
name&lt;span class="w"&gt;                &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;pg_pvlan_community_1
ports&lt;span class="w"&gt;               &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;e9c40083-d420-47c9-86ec-d4de363d8c1b&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;ACL example:&lt;/p&gt;
&lt;div class="highlight-sh notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;_uuid&lt;span class="w"&gt;               &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;f21e358d-ce0b-4741-80bf-a13abeefc221
action&lt;span class="w"&gt;              &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;allow-stateless
direction&lt;span class="w"&gt;           &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;to-lport
external_ids&lt;span class="w"&gt;        &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;
label&lt;span class="w"&gt;               &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
log&lt;span class="w"&gt;                 &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;
match&lt;span class="w"&gt;               &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"outport == @pg_pvlan_community_1 &amp;amp;&amp;amp; inport == @pg_pvlan_community_1 &amp;amp;&amp;amp; (ip || arp)"&lt;/span&gt;
meter&lt;span class="w"&gt;               &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;
name&lt;span class="w"&gt;                &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;
options&lt;span class="w"&gt;             &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{}&lt;/span&gt;
priority&lt;span class="w"&gt;            &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1010&lt;/span&gt;
severity&lt;span class="w"&gt;            &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;
tier&lt;span class="w"&gt;                &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Network delete (disable pvlan)&lt;/strong&gt; - delete
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pvlan_drop_all&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pvlan_isolated&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pvlan_promiscuous&lt;/span&gt;&lt;/code&gt; Port Groups
for the network (Logical Switch), delete ACLs created for those Port Groups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Port create&lt;/strong&gt; -&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If &lt;strong&gt;pvlan_type=isolated&lt;/strong&gt; or &lt;strong&gt;pvlan_type=promiscuous&lt;/strong&gt; - add port to
the specific port group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If &lt;strong&gt;pvlan_type=community&lt;/strong&gt; - ensure that Port Group and ACLs for that
Port Group are created and add port to that Port Group.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Port update&lt;/strong&gt; - Depending on the updated value, remove port from one Port
Group and add to another.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Port delete&lt;/strong&gt; - Delete port from the corresponding Port Group.  If
&lt;strong&gt;pvlan_type=community&lt;/strong&gt; and it is the last port in the Port Group
corresponding to that community name, &lt;strong&gt;remove that Port Group as well&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In ML2/OVN Port Groups can serve as a tool for defining Communities within a
PVLAN domain. In this implementation there would also be a specific Port group
for ports from isolated VMs, and another one for ports from promiscuous VMs.
Each Port group will be then associated with ACLs that will define their
behaviour.&lt;/p&gt;
&lt;p&gt;Since ACLs have a priority parameter, we can tune them so that they will
interact as intended e.g. right now the ‘neutron_pg_drop’ related ACLs have
lower priority than the security group ACLs. With PVLAN the pg_drop_group would
still exist (or we would create a similar one just for PVLAN logic, depending
on what is best). This Port group would have the lowest priority. Security
group rules could coexist with PVLAN by placing on PVLAN a higher priority on
its ACLS, making the PVLAN ACLs be the ones to be used if they exist.&lt;/p&gt;
&lt;p&gt;We don’t need to track state of the connection so ACLs actions will be
stateless, which is better in terms of the performance in some cases.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Ports with disabled port security in the network will be forbidden if
pvlan is enabled, as there is no a better solution that we can think of for
its coexistence.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonition warning"&gt;
&lt;p class="admonition-title"&gt;Warning&lt;/p&gt;
&lt;p&gt;Since the implementation in ML2/OVN uses ACLs, there is
no compatibility with external PVLAN networks.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="remaining-questions-on-implementation"&gt;
&lt;h3&gt;Remaining questions on Implementation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Should we disable arp_responder for LSP to be able to block that traffic too?
Or maybe it is possible to configure OVN to respond to ARP traffic
“selectively”?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Would pg_drop_group be different to the general drop port group of PVLAN or
can we use the same one?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="upgrading"&gt;
&lt;h3&gt;Upgrading&lt;/h3&gt;
&lt;p&gt;This feature does not affect how current components work, so no extra effort
should be done regarding upgrades.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Slawek Kaplonski&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Elvira García&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;API Definition&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Service implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ML2/OVN logic implementation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit/functional tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scenario test in neutron tempest.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;User Documentation: How to set up PVLAN in Neutron with ML2/OVN&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://datatracker.ietf.org/doc/html/rfc5517"&gt;https://datatracker.ietf.org/doc/html/rfc5517&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.cisco.com/c/en/us/support/docs/lan-switching/private-vlans-pvlans-promiscuous-isolated-community/40781-194.html"&gt;https://www.cisco.com/c/en/us/support/docs/lan-switching/private-vlans-pvlans-promiscuous-isolated-community/40781-194.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.cisco.com/c/en/us/td/docs/switches/datacenter/nexus5000/sw/layer2/503_n2_1/503_n2_1nw/Cisco_n5k_layer2_config_gd_rel_503_N2_1_chapter5.pdf"&gt;https://www.cisco.com/c/en/us/td/docs/switches/datacenter/nexus5000/sw/layer2/503_n2_1/503_n2_1nw/Cisco_n5k_layer2_config_gd_rel_503_N2_1_chapter5.pdf&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id9" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://gist.githubusercontent.com/gprocunier/91ad630db6e573b966ed4008dfa79bb8/raw/0e4ce3243eba7679c6a6093414a9286808bdf40d/pvlan_poc.sh"&gt;https://gist.githubusercontent.com/gprocunier/91ad630db6e573b966ed4008dfa79bb8/raw/0e4ce3243eba7679c6a6093414a9286808bdf40d/pvlan_poc.sh&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.ovn.org/support/dist-docs/ovn-nb.5.html"&gt;https://www.ovn.org/support/dist-docs/ovn-nb.5.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Fri, 30 Jan 2026 00:00:00 </pubDate></item><item><title>Routed Provider Networks with Multiple Segments per Host for ML2/OVN</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2026.1/multiple-segments-per-host-routed-net-ovn.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/2130453"&gt;https://bugs.launchpad.net/neutron/+bug/2130453&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As implemented by the ML2/OVN driver, routed provider networks are limited to
one segment per host &lt;a class="footnote-reference brackets" href="#id4" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id5" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. This specification proposes to remove such
limitation, enabling multiple segments per host per network.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Originally, all Neutron networks were single L2 broadcast domains. In such
networks, performance degrades as traffic grows as a result of an increasing
number of active VMs/ports. Routed provider networks were implemented to
overcome this limitation and enable users to create “large networks”, where a
large number of VMs/ports can be connected without incuring the performance
penalty of large single L2 broadcast domains. As shown in the following
diagram, routed provider networks are constituted by several L2 segments
(broadcast domains) stitched together by a router into one L3 “large network”.
In this arrangement, each individual segment handles only a portion of the
total network traffic, improving overall performance. The router is not part
of Neutron; it is provided by the underlying networking infrastructure &lt;a class="footnote-reference brackets" href="#id6" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;figure class="align-default"&gt;
&lt;a class="reference external image-reference" href="../../_images/routed-networks.jpg"&gt;&lt;img alt="../../_images/routed-networks.jpg" src="../../_images/routed-networks.jpg"/&gt;
&lt;/a&gt;
&lt;/figure&gt;
&lt;p&gt;In routed provider networks each segment is connected to a group of hosts (a
Nova aggregate), as shown in the following diagram. In the optimal situation,
the network traffic generated by the workload running in the hosts doesn’t
exceed the capacity of the corresponding segment.&lt;/p&gt;
&lt;figure class="align-default"&gt;
&lt;a class="reference external image-reference" href="../../_images/routed-networks-aggregates.jpg"&gt;&lt;img alt="../../_images/routed-networks-aggregates.jpg" src="../../_images/routed-networks-aggregates.jpg"/&gt;
&lt;/a&gt;
&lt;/figure&gt;
&lt;p&gt;Recently, though, some operators have found this not to be the case. They can
comfortably accomodate in the hosts workloads that generate network traffic
that exceeds their segment capacity. In such situations, more than one segment
per host is necessary if the deployers are going to fully utilize their compute
resources, while at the same time achieving the benefits of the routed provider
networks, by effectively limiting the size of the individual L2 broadcast
domains. This is shown in the following diagram.&lt;/p&gt;
&lt;figure class="align-default"&gt;
&lt;a class="reference external image-reference" href="../../_images/routed-networks-aggregates-plus.jpg"&gt;&lt;img alt="../../_images/routed-networks-aggregates-plus.jpg" src="../../_images/routed-networks-aggregates-plus.jpg"/&gt;
&lt;/a&gt;
&lt;/figure&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This specification proposes to implement each segment in a routed provider
network as an OVN Logical Switch. Each one of these logical switches will be
associated with a Logical Switch Port of type localnet, that will map the
segment to a physical network in the hosts connected to it. As a consequence,
for routed provider networks, the one-to-one mapping between a Neutron network
and an OVN Logical Switch will no longer be true. The following diagram
summarizes the proposed approach, using a Neutron network named &lt;cite&gt;public&lt;/cite&gt; and
segments with &lt;cite&gt;vlan-ids&lt;/cite&gt; 42, 43 and 44 as examples:&lt;/p&gt;
&lt;figure class="align-default"&gt;
&lt;a class="reference external image-reference" href="../../_images/routed-networks-n-segments-per-host-NBDB.jpg"&gt;&lt;img alt="../../_images/routed-networks-n-segments-per-host-NBDB.jpg" src="../../_images/routed-networks-n-segments-per-host-NBDB.jpg"/&gt;
&lt;/a&gt;
&lt;/figure&gt;
&lt;p&gt;At the chassis level, this design will be implemented as depicted in the
following diagram:&lt;/p&gt;
&lt;figure class="align-default"&gt;
&lt;a class="reference external image-reference" href="../../_images/routed-networks-n-segments-per-host.jpg"&gt;&lt;img alt="../../_images/routed-networks-n-segments-per-host.jpg" src="../../_images/routed-networks-n-segments-per-host.jpg"/&gt;
&lt;/a&gt;
&lt;/figure&gt;
&lt;p&gt;In this diagram, the key features of the proposed design are:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The four bridges &lt;cite&gt;br-ex*&lt;/cite&gt; represent the routed provider network named
&lt;cite&gt;public&lt;/cite&gt; depicted in the previous diagram with its three segments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each of the bridges &lt;cite&gt;br-ex-42&lt;/cite&gt;, &lt;cite&gt;br-ex-43&lt;/cite&gt; and &lt;cite&gt;br-ex-44&lt;/cite&gt; represents one of
the segments in the routed provider network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For each segment, there will be a key-value pair in OVS’s
&lt;cite&gt;external_ids:ovn-bridge-mappings&lt;/cite&gt;. In the &lt;cite&gt;public&lt;/cite&gt; network example we are
using in this specification, for the physnet identified as &lt;cite&gt;physnet-43&lt;/cite&gt;, the
corresponding mapping is &lt;cite&gt;physnet-43:br-ex-43&lt;/cite&gt;. It is the presence of these
mappings that triggers the &lt;cite&gt;ovn-controller&lt;/cite&gt; to configure the patch ports on
the &lt;cite&gt;br-int&lt;/cite&gt; side of the segment bridges. It is important to note that
&lt;cite&gt;br-ex&lt;/cite&gt; is not part of &lt;cite&gt;external_ids:ovn-bridge-mappings&lt;/cite&gt;. The
&lt;cite&gt;ovn-controller&lt;/cite&gt; doesn’t interact with that bridge.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are two alternatives for the creation of the &lt;cite&gt;br-ex*&lt;/cite&gt; bridges and the
configuration of the &lt;cite&gt;br-ex&lt;/cite&gt; side of the patch ports. They can be created
automatically by Neutron or they can be created as a result of system
administration activities. To select from these two alternatives, a large
user of routed provider networks with the ML2/OVS driver was asked how
frequently they have added segments to their hosts. They responded that they
add segments every month. Based on this information, this specification
proposes to develop an agent that will create bridges and configure them. It
is important to note that since &lt;cite&gt;br-ex&lt;/cite&gt; provides connectivity to the
underlay network, it will still be created by the cloud
operator.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To implement the proposed new functionality, the following changes to the code
are expected:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;When a segment is created for a routed provider network, an associated
Logical Switch and Logical Switch Port of type &lt;cite&gt;localnet&lt;/cite&gt; will need to be
created in the OVN NBDB. Correspondingly, these OVN resources will have to
be removed when the segment is deleted.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When a port is created for a routed provider network, the creation of the
associated Logical Switch Port will have to be deferred until the moment
when the segment to which it is bound is known. Correspondingly, when a port
is deleted, its associated Logical Switch Port will have to be removed from
the correct Logical Switch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The OVN maintenance and DB synchronization periodic jobs must be updated to
account for the changes described in the previous two points.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For routed provider networks, the logical switch associated to each segment
will have its own localport to serve metadata to VMs. This means that the
metadata agent will be updated to provision the datapath in each chassis for
localports associated to segments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A &lt;cite&gt;neutron-ovn-agent&lt;/cite&gt; extension will be developed that will be responsible
for creating and configuring the bridges that represent the routed provider
network segments at the chassis level. When a segment is added, the
extension will add the corresponding bridge and add it to the OVS
OpenvSwitch table &lt;cite&gt;ovn-bridge-mappings&lt;/cite&gt; attribute. Patch ports will be
created between the new bridge and &lt;cite&gt;br-int&lt;/cite&gt; and &lt;cite&gt;br-ex&lt;/cite&gt;. The &lt;cite&gt;br-ex&lt;/cite&gt; side of
the patch port will be configured with the correct &lt;cite&gt;tag&lt;/cite&gt; and &lt;cite&gt;trunk&lt;/cite&gt;
attributes. When a segment is removed, these steps will be undone.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The implementation will be carried out in two phases. In the first phase, the
core functionality described in the first four points above will be
implemented. In the second phase, the &lt;cite&gt;neutron-ovn-agent&lt;/cite&gt; extension to manage
the segment bridges at the chassis level will be developed. This approach will
allow us to start testing the core funcionality as soon as possible while
giving us more time to develop the &lt;cite&gt;neutron-ovn-agent&lt;/cite&gt; extension.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1865889"&gt;https://bugs.launchpad.net/neutron/+bug/1865889&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/admin/ovn/routed_provider_networks.html"&gt;https://docs.openstack.org/neutron/latest/admin/ovn/routed_provider_networks.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/admin/config-routed-networks.html"&gt;https://docs.openstack.org/neutron/latest/admin/config-routed-networks.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Wed, 05 Nov 2025 00:00:00 </pubDate></item><item><title>Core OVN BGP integration</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2025.2/ovn-bgp-integration.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/2111276"&gt;https://bugs.launchpad.net/neutron/+bug/2111276&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;OVN 25.03 introduces BGP-related capabilities that provide parity with the
current ovn-bgp-agent underlay exposing method.
This spec is to introduce a design using the OVN capabilities integrated with
Neutron to replace the ovn-bgp-agent.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The ovn-bgp-agent is another process running on compute and network nodes.
There is a lot of processing happening when new workloads are created or moved
around because the agent needs to pay attention to these changes and rewire
configuration on the node as needed. As OVN is well aware of the locality of its
resources we can leave all the processing up to OVN and only manage underlying
BGP OVN topology in Neutron and still use the pure L3 spine-and-leaf topology
for the dataplane traffic.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="acronyms-used-in-this-spec"&gt;
&lt;h2&gt;Acronyms used in this spec&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;BGP: Border Gateway Protocol&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ECMP: Equal-Cost Multi-Path&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LRP: Logical Router Port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LSP: Logical Switch Port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LS: Logical Switch&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LR: Logical Router&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VRF: Virtual Routing and Forwarding&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FRR: Free Range Routing (&lt;a class="reference external" href="https://github.com/FRRouting/frr"&gt;https://github.com/FRRouting/frr&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This spec proposes to introduce a new Neutron service plugin that manages the
underlying BGP topology in OVN. Its main purpose is to make sure the OVN
resources related to BGP are correctly configured at all times by being a
reconciler over those resources. Additionally it takes care of scaling in and
out the compute nodes because every compute node needs to have their own bound
resources, such as a router and a logical switch with a localnet port.&lt;/p&gt;
&lt;p&gt;There is no need to make any changes to API or database models. However, there
is a need to modify Neutron OVN DB sync scripts to not monitor the underlying
BGP resources. Possibly this was already planned to exist in Neutron with the
spec at &lt;a class="footnote-reference brackets" href="#id4" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; so we need to revive the work. That can be achieved by setting an
explicit tag in the external_ids column of the BGP managed resources that
Neutron would not touch.  Also, we need to make sure on the presentation layer
that all the underlying BGP resources are not exposed to the users through an
API. For example, a router list command must not return the BGP routers.&lt;/p&gt;
&lt;p&gt;Each compute node requires a running FRR instance that monitors the local VRF
and advertises the routes to the BGP peers. It is the installer’s responsibility
to configure the FRR instance to use the correct BGP parameters and to connect
to the correct BGP peers.&lt;/p&gt;
&lt;p&gt;As it is easier to understand the topology visually than through description,
the following diagram shows the underlying BGP logical topology in OVN. For
better resolution, it is recommended to open the image in a new tab.&lt;/p&gt;
&lt;figure class="align-default"&gt;
&lt;a class="reference external image-reference" href="../../_images/ovn-bgp-topology.jpg"&gt;&lt;img alt="../../_images/ovn-bgp-topology.jpg" src="../../_images/ovn-bgp-topology.jpg"/&gt;
&lt;/a&gt;
&lt;/figure&gt;
&lt;p&gt;OVN BGP Logical Topology (click for full resolution)&lt;/p&gt;
&lt;section id="bgp-distributed-logical-router"&gt;
&lt;h3&gt;BGP distributed logical router&lt;/h3&gt;
&lt;p&gt;A new router with the OVN BGP enabled capabilities is introduced, the router is
named “BGP distributed router” in the diagram above, with dynamic routing flag
enabled. The router is connected to the provider logical switch with a dummy
connection. This connection is not used for any traffic and serves only to
logically connect the logical switch and the BGP router so the northd can create
entries in the Advertised_Route table in the Southbound DB for the IPs that need
to be advertised.&lt;/p&gt;
&lt;p&gt;The router also connects to a LS with a localnet port. This LS is connected to
the provider bridge br-bgp that needs to be configured on every chassis since
the traffic here is distributed and can happen on any node. This bridge connects
to the ls-public LS through the localnet port created by Neutron. This LS is
what typically connects the physical network in the traditional deployments. We
need to have localnet ports to avoid OVN sending traffic over the geneve tunnel
to the node hosting the logical router gateway.&lt;/p&gt;
&lt;p&gt;The BGP distributed router is connected to the per-chassis logical routers
through peered LRPs and bound to the corresponding chassis. The LRs per chassis
are described in the next section. Because the BGP router is distributed we need
to pick the right LRP so the traffic is not forwarded to a different chassis.
For example, if there is egress traffic coming from a tenant LSP on chassis A,
the BGP distributed router needs to route the traffic to the LRP on chassis A.
For this we will use logical routing policy and the is_chassis_resident match.
An example of the logical routing policy is shown below:&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;action              : reroute
bfd_sessions        : []
chain               : []
external_ids        : {}
jump_chain          : []
match               : "inport==\"lrp-bgp-main-router-to-ls-interconnect\" &amp;amp;&amp;amp; is_chassis_resident(\"cr-lrp-bgp-main-router-to-bgp-router-r0-compute-0\")"
nexthop             : []
nexthops            : ["169.254.0.1"]
options             : {}
priority            : 10
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The nexthop in this case is the LRP on the chassis A and for now must be an IPv4
as OVN currently contains a bug that prevents the use of IPv6 LLAs as nexthops,
reported at &lt;a class="footnote-reference brackets" href="#id5" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.  The policy is implemented only on the chassis defined in
is_chassis_resident and hence the traffic will always remain local to the
chassis. Because the policy is at a later stage in the LR pipeline we need to
create a logical router static route in order to pass the routing phase. Hence
the BGP distributed logical router needs to contain two static routes. One to
route ingress traffic to the provider network and one unused route that serves
only to pass the routing stage in the pipeline until the reroute policy is hit.&lt;/p&gt;
&lt;p&gt;The first static route can look like this:&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;bfd                 : []
external_ids        : {}
ip_prefix           : "192.168.111.0/24"
nexthop             : "192.168.111.30"
options             : {}
output_port         : lrp-bgp-main-router-to-ls-interconnect
policy              : []
route_table         : ""
selection_fields    : []
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;where the ip_prefix is the provider network prefix and the output_port is the
LRP connecting to the provider LS. The nexthop is the LRP of the Neutron router
port that serves as a gateway.&lt;/p&gt;
&lt;p&gt;The second static route is unused and can look like this:&lt;/p&gt;
&lt;div class="highlight-text notranslate" id="fake-static-route"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;bfd                 : []
external_ids        : {}
ip_prefix           : "0.0.0.0/0"
nexthop             : "192.168.111.30"
options             : {}
output_port         : []
policy              : []
route_table         : ""
selection_fields    : []
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The route needs to match all traffic and the nexthop doesn’t matter because it
will be determined by the reroute policies based on the chassis locality. The
ingress logical router pipeline with the route implemented looks like this:&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;... the other routes are here but none matches 0.0.0.0/0 ...
table=15(lr_in_ip_routing   ), priority=4    , match=(reg7 == 0 &amp;amp;&amp;amp; ip4.dst == 0.0.0.0/0), action=(ip.ttl--; reg8[0..15] = 0; reg0 = 192.168.111.30; reg5 = 192.168.111.30; eth.src = 00:de:ad:10:00:00; outport = "lrp-bgp-main-router-to-ls-interconnect"; flags.loopback = 1; reg9[9] = 1; next;)
table=15(lr_in_ip_routing   ), priority=0    , match=(1), action=(drop;)
table=16(lr_in_ip_routing_ecmp), priority=150  , match=(reg8[0..15] == 0), action=(next;)
table=16(lr_in_ip_routing_ecmp), priority=0    , match=(1), action=(drop;)
table=17(lr_in_policy       ), priority=10   , match=(inport=="lrp-bgp-main-router-to-ls-interconnect" &amp;amp;&amp;amp; is_chassis_resident("cr-lrp-bgp-main-router-to-bgp-router-r0-compute-0")), action=(reg0 = 169.254.0.1; reg5 = 169.254.0.2; eth.src = 00:de:ad:00:10:00; outport = "lrp-bgp-main-router-to-bgp-router-r0-compute-0"; flags.loopback = 1; reg8[0..15] = 0; reg9[9] = 1; next;)
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As we need to get to the stage where the reroute policy is hit, we need to pass
the lr_in_ip_routing stage first and this stage is implemented with a static
route. That means we match the 0.0.0.0/0 prefix using the first rule and then
later we change the output_port with the last rule with its reroute action. If
the static route would not be present, the traffic would be dropped with the
second rule containing the drop action.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="per-chassis-logical-routers"&gt;
&lt;h3&gt;Per-chassis logical routers&lt;/h3&gt;
&lt;p&gt;There is also a logical router created and bound to each chassis. These routers
serve to learn ECMP routes from the BGP peers and to forward traffic between the
provider bridges and the BGP distributed router.&lt;/p&gt;
&lt;p&gt;For cases where the compute nodes share data plane and control plane traffic
over the same spine-and-leaf topology, there is a need to maintain openflow
rules on the provider bridge that differentiate traffic between control plane,
and hence forward traffic to the host, and the dataplane traffic that needs to
go to the OVN overlay. The following openflow rules could be used to achieve
this:&lt;/p&gt;
&lt;div class="highlight-text notranslate" id="openflow-rules"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;priority=10,ip,in_port=eth0,nw_dst=&amp;lt;host IPs&amp;gt; actions=NORMAL
priority=10,ipv6,in_port=eth0,ipv6_dst=&amp;lt;host IPv6s&amp;gt; actions=NORMAL
priority=10,arp actions=NORMAL
priority=10,icmp6,icmp_type=133 actions=NORMAL
priority=10,icmp6,icmp_type=134 actions=NORMAL
priority=10,icmp6,icmp_type=135 actions=NORMAL
priority=10,icmp6,icmp_type=136 actions=NORMAL
priority=10,ipv6,in_port=eth0,ipv6_dst=fe80::/64 actions=NORMAL
priority=8,in_port=eth0 actions=mod_dl_dst:&amp;lt;LRP MAC&amp;gt;,output:&amp;lt;patch_port_to_ovn&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Those rules match traffic that is destined to the host and forward it to the
host. Everything else is forwarded to the OVN overlay. The patch_port_to_ovn is
a patch port that ovn-controller created based on the ovn-bridge-mappings
configuration.&lt;/p&gt;
&lt;p&gt;The router itself needs to implement routes for traffic coming from the provider
network and for traffic coming from the OVN overlay. For ingress provider
network traffic, the routes can look as follows:&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;bfd                 : []
external_ids        : {}
ip_prefix           : "192.168.111.0/24"
nexthop             : "169.254.0.2"
options             : {}
output_port         : lrp-bgp-router-r0-compute-0-to-bgp-main-router
policy              : []
route_table         : ""
selection_fields    : []
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;where ip_prefix matches the subnet of the provider network and the nexthop is
set to the address of the LRP attached to the BGP distributed router and the
output_port is set to its peer LRP.&lt;/p&gt;
&lt;p&gt;The egress traffic from the OVN overlay needs to be routed with ECMP to the BGP
network. This can be achieved with the following static routes for each BGP
peer:&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;bfd                 : []
external_ids        : {}
ip_prefix           : "0.0.0.0/0"
nexthop             : "100.64.0.1"
options             : {}
output_port         : lrp-bgp-router-r0-compute-0-to-ls-r0-compute-0-eth0
policy              : []
route_table         : ""
selection_fields    : []

bfd                 : []
external_ids        : {}
ip_prefix           : "0.0.0.0/0"
nexthop             : "100.65.0.1"
options             : {}
output_port         : lrp-bgp-router-r0-compute-0-to-ls-r0-compute-0-eth1
policy              : []
route_table         : ""
selection_fields    : []
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="traffic-flow"&gt;
&lt;h2&gt;Traffic flow&lt;/h2&gt;
&lt;p&gt;This section describes the traffic flow from and to a LSP hosted on a chassis.&lt;/p&gt;
&lt;section id="an-example-of-the-traffic-from-the-external-network-to-a-vm-with-a-floating-ip-on-chassis-1"&gt;
&lt;h3&gt;An example of the traffic from the external network to a VM with a Floating IP on chassis 1&lt;/h3&gt;
&lt;p&gt;Because of the dummy connection between the ls-public LS and the BGP distributed
router, OVN creates an Advertised_Route entry for the Floating IP.  Because the
associated logical port is bound to the chassis 1, OVN populates the local VRF
on the chassis 1 with the route to the Floating IP and the local FRR instance
advertises the route to the BGP peers.&lt;/p&gt;
&lt;p&gt;The fabric learns the route to the Floating IP from the BGP peers and forwards
the traffic to the chassis 1 to either eth0 or eth1 because of the ECMP routes.&lt;/p&gt;
&lt;p&gt;The traffic does not match any of the higher priority &lt;a class="reference internal" href="#openflow-rules"&gt;&lt;span class="std std-ref"&gt;openflow rules&lt;/span&gt;&lt;/a&gt; on the provider bridge and matches the last rule. The rule
changes the destination MAC to the LRP MAC address of the per-chassis router
associated with the NIC and the traffic is forwarded to OVN. The traffic enters
the per chassis logical router that has Logical_Static_Route configured to
forward the traffic to the distributed BGP router. The BGP distributed router is
configured to forward the traffic to the ls-inter-public switch with a
Logical_Static_Route matching the destination IP with the provider network
subnet and through the br-bgp provider bridge the traffic gets to the ls-public
logical switch. From here the traffic follows the same path as without BGP and
is NAT’ed by the Neutron router.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="an-example-of-the-traffic-from-a-vm-with-a-floating-ip-on-chassis-1-to-the-external-network"&gt;
&lt;h3&gt;An example of the traffic from a VM with a Floating IP on chassis 1 to the external network&lt;/h3&gt;
&lt;p&gt;The egress VM traffic is NAT’ed by the Neutron router and the traffic is
forwarded to the provider network gateway which is connected to the ls-public
LS. Because of the presence of the localnet ports the traffic gets through the
br-bgp bridge to the distributed BGP router where it matches the artificial
&lt;a class="reference internal" href="#fake-static-route"&gt;&lt;span class="std std-ref"&gt;Logical_Router_Static_Route&lt;/span&gt;&lt;/a&gt; to skip the
lr_in_ip_routing stage in the pipeline and will be matched with the BGP router
policy based on the chassis locality. The reroute action of the policy will pick
the right LRP that is connected to the per-chassis router. Here the traffic
matches static routes per peer and with the ECMP is
forwarded to the BGP networks.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Existing tempest tests should provide good regression testing. We can reuse the
existing topology from the ovn-bgp-agent project that peer with VMs simulating a
BGP router.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;The implementation is split into two parts. The first part creates the service
plugin that takes care of the BGP topology in OVN including the configuration of
static routes and router policies.&lt;/p&gt;
&lt;p&gt;The second part is an OVN agent extension &lt;a class="footnote-reference brackets" href="#id6" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; that configures per chassis host
configurations. The OVN agent itself is orthogonal to the BGP service plugin and
can be replaced with any third-party tool that takes care of the node dynamic
configuration. The OVN agent extension is responsible for steering the traffic
to the OVN and for configuring the per chassis host configurations such as
adding ovn-bridge-mappings per the BGP peer, and for implementing local openflow
rules to differentiate traffic between the control plane and the dataplane. It
also monitors patch ports on the br-bgp and creates direct connection between
the localnet ports to avoid any FDB learning on the bridge.
An example of the simple openflow rules is shown below:&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;priority=10,in_port=2, actions=output:3
priority=10,in_port=3, actions=output:2
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;where 2 is the patch port to the logical switch connected to the BGP distributed
router and 3 is the patch port connected to the Neutron public switch.&lt;/p&gt;
&lt;p&gt;Where BGP is used with Neutron or not is determined by enabling the service
plugin and the OVN agent extension.&lt;/p&gt;
&lt;p&gt;As it is written in the first paragraph of this spec, the BGP support in OVN
was introduced in 25.03. Therefore the BGP service plugin requires OVN 25.03 or
later.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Jakub Libosvar &amp;lt;&lt;a class="reference external" href="mailto:jlibosva%40redhat.com"&gt;jlibosva&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;p&gt;Deployment guide will be written in describing how to enable the service plugin
and what needs to be configured on the nodes, such as steering traffic to the
OVN or configuration of a BGP speaker advertising the routes to its peer. An
example using FRR configuration will be introduced so the operators have a
reference for the configuration.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/neutron-specs/+/891204"&gt;https://review.opendev.org/c/openstack/neutron-specs/+/891204&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://issues.redhat.com/browse/FDP-1554"&gt;https://issues.redhat.com/browse/FDP-1554&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://opendev.org/openstack/neutron/src/commit/1e6381cbd25f8ab4fc9a3bcaa1ab7af1d605946e/doc/source/ovn/ovn_agent.rst"&gt;https://opendev.org/openstack/neutron/src/commit/1e6381cbd25f8ab4fc9a3bcaa1ab7af1d605946e/doc/source/ovn/ovn_agent.rst&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Wed, 18 Jun 2025 00:00:00 </pubDate></item><item><title>Distributed DNS Forwarder with Openvswitch Agent</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2025.2/distributed-dns-forwarder-ovs.html</link><description>

&lt;p&gt;RFE: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/2112446"&gt;https://bugs.launchpad.net/neutron/+bug/2112446&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron DHCP agents (using dnsmasq) can act as DNS forwarders or
provide DNS resolution for instances by using resolvers configured
on the host where the DHCP agent runs. However, when users deploy Distributed DHCP
alongside the Open vSwitch (OVS) agent, they are responsible for ensuring
that instances can reach DNS servers or for setting up their own forwarding mechanism.&lt;/p&gt;
&lt;p&gt;This spec describes how to implement a DNS forwarder extension for Neutron
openvswitch agent to provide a simple, fully distributed DNS forwarding capability
for virtual machines by leveraging OpenFlow rules and os-ken applications.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DNS plays a critical role in ensuring high availability for services such as databases,
VPN clusters, or any failover scenarios where DNS records are updated dynamically
whether within OpenStack or through external systems. In addition, DNS resolution is essential
in OpenStack environments to allow instances on external or project networks to those services,
even if they don’t have a direct path to DNS servers. For instance, a web server running in
an isolated VXLAN network might need to connect to a database service (provided by the cloud provider)
on the same network using an internal domain name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Distributed DHCP for Openvswitch Agent is good for large-scale deployments, but it lacks
built-in DNS resolution capabilities, unlike the DHCP agent that uses dnsmasq. &lt;a class="footnote-reference brackets" href="#id4" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;A new extension of Neutron openvswitch agent will be added to achieve the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Distributed&lt;/span&gt; &lt;span class="pre"&gt;DNS&lt;/span&gt; &lt;span class="pre"&gt;Forwarder&lt;/span&gt; &lt;span class="pre"&gt;with&lt;/span&gt; &lt;span class="pre"&gt;Openvswitch&lt;/span&gt; &lt;span class="pre"&gt;Agent&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This extension is only for openvswitch agent, other mechanism drivers
will not be considered, because this new extension will rely on the
openflow protocol and principle. For OVN, it has supported similar
DNS resolution mechanism with ovn-controller.&lt;/p&gt;
&lt;/div&gt;
&lt;section id="solution-proposed"&gt;
&lt;h3&gt;Solution Proposed&lt;/h3&gt;
&lt;p&gt;Developing a new OS-Ken application in OVS-agent which will act as an intermediary
between instance and a DNS server, so it can response DNS query to instance without
direct connection to the actual DNS server.&lt;/p&gt;
&lt;p&gt;The basic data pipeline can be described as this:&lt;/p&gt;
&lt;div class="highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                        +--------------+                +---------------------+                +---------------------+
+-------+ DNS Query     |              |    packet-in   |  +----------------+ | DNS Query      |                     |
|  VM   +---------------&amp;gt;  Flows       +----------------&amp;gt;  |   os-ken app   | +----------------&amp;gt;   Local resolvers   |
|       &amp;lt;---------------+ (capture     &amp;lt;----------------+  |                | &amp;lt;----------------+        or           |
+-------+ DNS Answer    | DNS query    |    packet-out  |  | DNS Forwarder  | | DNS Answer     |   Real DNS servers  |
                        |   here)      |                |  +----------------+ |                |                     |
                        |   br-int     |                |      OVS-agent      |                |                     |
                        +--------------+                +---------------------+                +---------------------+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;After this we will have:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Higher level availability than DNS resolution with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dnsmasq&lt;/span&gt;&lt;/code&gt; in DHCP Agent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack with distributed DHCP extension &lt;a class="footnote-reference brackets" href="#id4" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; can now support DNS lookup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Great combination with Distributed metadata datapath for Openvswitch Agent &lt;a class="footnote-reference brackets" href="#id5" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="dns-forwarder"&gt;
&lt;h4&gt;DNS Forwarder&lt;/h4&gt;
&lt;p&gt;We will extract DNS payload from the packet, then send it to upstream DNS server.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="server-side-changes"&gt;
&lt;h4&gt;Server side changes&lt;/h4&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="openvswitch-agent-side-changes"&gt;
&lt;h4&gt;OpenvSwitch Agent side changes&lt;/h4&gt;
&lt;p&gt;For Neutron openvswitch agent, we will add a new agent extension which will
process the basical flow installation for any DNS query.&lt;/p&gt;
&lt;p&gt;There will be some basic flows which will check if the DNS query is matched
with destinations, then submit it to the controller. The default destinations are
&lt;cite&gt;169.254.169.254:53&lt;/cite&gt; and &lt;cite&gt;[fd00::254]:53&lt;/cite&gt;. We will make it configurable.&lt;/p&gt;
&lt;div class="highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;table=60, priority=102,udp,nw_dst=169.254.169.254,tp_dst=53 actions=CONTROLLER:0
table=60, priority=102,udp6,nw_dst=fd00::254,tp_dst=53 actions=CONTROLLER:0
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For the new extension of openvswitch agent, it will register a local
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;packet_in_handler&lt;/span&gt;&lt;/code&gt; which will do the following works:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Listen on the EventOFPPacketIn event&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify each packet if it’s matched above rules&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extract DNS payload from the packet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sent DNS payload to upstream DNS server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assemble the DNS answer response and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;send_msg&lt;/span&gt;&lt;/code&gt; to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;in_port&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The response DNS answer packet structure will be:&lt;/p&gt;
&lt;div class="highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;+------------------------------------------+
|           *Source Mac Address            |
|   169.254.169.254/fd00::254 MAC Address  |
+------------------------------------------+
|       *Destination Mac Address           |
|        Neutron Port Mac Address          |
+------------------------------------------+
|           *Source IP Address             |
|        169.254.169.254/fd00::254         |
+------------------------------------------+
|         *Destination IP address          |
|             Neutron Port IP              |
+------------------------------------------+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Source&lt;/span&gt; &lt;span class="pre"&gt;Mac&lt;/span&gt; &lt;span class="pre"&gt;Address&lt;/span&gt;&lt;/code&gt; will be &lt;cite&gt;169.254.169.254/fd00::254&lt;/cite&gt; MAC Address.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Destination&lt;/span&gt; &lt;span class="pre"&gt;Mac&lt;/span&gt; &lt;span class="pre"&gt;Address&lt;/span&gt;&lt;/code&gt; will be the port’s MAC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Source&lt;/span&gt; &lt;span class="pre"&gt;IP&lt;/span&gt; &lt;span class="pre"&gt;Address&lt;/span&gt;&lt;/code&gt; will be &lt;cite&gt;169.254.169.254/fd00::254&lt;/cite&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Destination&lt;/span&gt; &lt;span class="pre"&gt;IP&lt;/span&gt; &lt;span class="pre"&gt;address&lt;/span&gt;&lt;/code&gt; will be the port IP(v4/v6) address.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Unlike DHCP Request which typically rely on broadcast packets, this solution
works more like the metadata service which is need to have a route
to &lt;cite&gt;169.254.169.254/fd00::254&lt;/cite&gt; via somewhere to sent out DNS query packet.
These packets will then be captured on the br-int bridge.
The necessary route can be provided by the DHCP agent, distributed DHCP, or via cloud-init.
Additionally, the specified next hop must be reachable, meaning the instance
should be able to resolve its MAC address using ARP and in most cases,
this next hop is the default gateway.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="potential-configurations"&gt;
&lt;h4&gt;Potential configurations&lt;/h4&gt;
&lt;p&gt;A new extension alias name &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dns_forwarder&lt;/span&gt;&lt;/code&gt; will be added for neutron
openvswitch agent:&lt;/p&gt;
&lt;div class="highlight-ini notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;[agent]&lt;/span&gt;
&lt;span class="na"&gt;extensions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;...,dns_forwarder&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Config section &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[dns_forwarder]&lt;/span&gt;&lt;/code&gt; will be added for neutron openvswitch agent
and register some common options:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;dns_forwarder_opts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListOpt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'upstream_dns_server_ports'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'1.1.1.1:53'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'[2606:4700:4700::1111]:53'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
              &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Comma-separated list of the Upstream DNS server&lt;/span&gt;
                     &lt;span class="s1"&gt;'in ip:port format which will be used as resolvers.'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntOpt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'upstream_dns_query_timeout'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Query timeout in seconds for each Upstream DNS servers"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListOpt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'client_dns_server_ports'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'169.254.169.254:53'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'[fd00::254]:53'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
              &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Comma-separated list of the Client DNS server&lt;/span&gt;
                     &lt;span class="s1"&gt;'in ip:port format which will be used inside client instances.'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="upgrading"&gt;
&lt;h3&gt;Upgrading&lt;/h3&gt;
&lt;p&gt;This feature does not affect any current features, so we simply enable it to use.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignees:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Dai, Dang Van &amp;lt;&lt;a class="reference external" href="mailto:daikk115%40gmail.com"&gt;daikk115&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement a new DNS Responder OS-Ken application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement some new configuration options.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement relevant unit and functional tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit/functional tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;User Documentation: How to setting up internal DNS resolution with OVS.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/wallaby/distributed_dhcp.html#upgrading"&gt;https://specs.openstack.org/openstack/neutron-specs/specs/wallaby/distributed_dhcp.html#upgrading&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/yoga/distributed-metadata-data-path.html"&gt;https://specs.openstack.org/openstack/neutron-specs/specs/yoga/distributed-metadata-data-path.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 17 Jun 2025 00:00:00 </pubDate></item><item><title>Add more information to network-ip-availabilites response</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2026.1/add-information-to-network-ip-availabilites.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/2107316"&gt;https://bugs.launchpad.net/neutron/+bug/2107316&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This RFE intends to provide detailed information on the number of IPs in the
subnet from the response of GET &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/network-ip-availabilites&lt;/span&gt;&lt;/code&gt; - the
number of available IPs in the subnet cidr and in the allocation pools, used
IPs in the subnet cidr and in the allocation pools.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Now the response of network-ip-availabilites api contains:
(1) total_ips
(2) used_ips&lt;/p&gt;
&lt;p&gt;(1) total_ips
- subnet cidr, when there are no allocation pools in the subnet
- the sum of IPs in each allocation pool, when there are allocation pools in
the subnet&lt;/p&gt;
&lt;p&gt;(2) used_ips
- the number of used IPs in the subnet (does not consider allocation pools)&lt;/p&gt;
&lt;p&gt;We cannot know how many available IPs are in the allocation pools from the
response. There are use cases that we need to know the number of available IPs
in the allocation pools, such as check ip availability before creating a vm in
the network.&lt;/p&gt;
&lt;p&gt;Using IPv4 subnet, total_ips does not show the exact number of available IPs.
total_ips includes .0 and .255, which IPs can’t be used as ports’ ip.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;To solve the problem described above, the proposal is to add a new API
extension &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network-ip-availability-details&lt;/span&gt;&lt;/code&gt; to extend
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network-ip-availability&lt;/span&gt;&lt;/code&gt; resource in Neutron with
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ip_availability_details&lt;/span&gt;&lt;/code&gt; attribute.&lt;/p&gt;
&lt;section id="server-side-changes"&gt;
&lt;h3&gt;Server side changes&lt;/h3&gt;
&lt;p&gt;A new API extension &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network-ip-availability-details&lt;/span&gt;&lt;/code&gt; will be added. The
extension adds a new attribute &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ip_availability_details&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The attribute consists of:
(1) total_ips_in_subnet: the number of available IPs in the subnet cidr
(except .0, .255, in IPv4 subnet)
(2) total_ips_in_allocation_pool: the sum of IPs in each allocation pool, 0 in
case of no allocation pools
(3) used_ips_in_subnet: the sum of used IPs in the subnet (does not consider
allocation pools)
(4) used_ips_in_allocation_pool: the sum of used IPs in each allocation pool,
0 in case of no allocation pools&lt;/p&gt;
&lt;p&gt;Response of GET &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/network-ip-availabilities/{network_id}&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"network_ip_availability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"subnet_ip_availability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"subnet_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"44e70d00-80a2-4fb1-ab59-6190595ceb61"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"subnet_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"private-subnet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"total_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"used_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"ip_availability_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="s2"&gt;"total_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;254&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s2"&gt;"total_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s2"&gt;"used_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s2"&gt;"used_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"subnet_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"a90623df-00e1-4902-a675-40674385d74c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"subnet_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ipv6-private-subnet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"fdbf:ac66:9be8::/64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"total_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"used_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"ip_availability_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="s2"&gt;"total_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551616&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s2"&gt;"total_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s2"&gt;"used_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s2"&gt;"used_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"network_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"6801d9c8-20e6-4b27-945d-62499f00002e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"d56d3b8dd6894a508cf41b96b522328c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"d56d3b8dd6894a508cf41b96b522328c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"network_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"private"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"total_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551856&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"used_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ip_availability_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"total_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551870&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"total_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"used_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"used_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response of GET &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/network-ip-availabilities&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"network_ip_availabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"network_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"4cf895c9-c3d1-489e-b02e-59b5c8976809"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"network_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"subnet_ip_availability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"subnet_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"44e70d00-80a2-4fb1-ab59-6190595ceb61"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"subnet_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"private-subnet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"total_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"used_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"ip_availability_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                      &lt;span class="s2"&gt;"total_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;254&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s2"&gt;"total_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s2"&gt;"used_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s2"&gt;"used_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"subnet_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"a90623df-00e1-4902-a675-40674385d74c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"subnet_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ipv6-private-subnet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"fdbf:ac66:9be8::/64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"total_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"used_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"ip_availability_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                      &lt;span class="s2"&gt;"total_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551616&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s2"&gt;"total_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s2"&gt;"used_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s2"&gt;"used_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"1a02cc95f1734fcc9d3c753818f03002"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"1a02cc95f1734fcc9d3c753818f03002"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"total_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551856&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"used_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"ip_availability_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="s2"&gt;"total_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551870&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"total_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"used_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"used_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"network_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"6801d9c8-20e6-4b27-945d-62499f00002e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"network_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"private"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"subnet_ip_availability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"subnet_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"44e70d00-80a2-4fb1-ab59-6190595ceb61"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"subnet_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"private-subnet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"total_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"used_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"ip_availability_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                      &lt;span class="s2"&gt;"total_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;254&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s2"&gt;"total_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s2"&gt;"used_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s2"&gt;"used_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"fdbf:ac66:9be8::/64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"subnet_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"a90623df-00e1-4902-a675-40674385d74c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"subnet_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ipv6-private-subnet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"total_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"used_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"ip_availability_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                      &lt;span class="s2"&gt;"total_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551614&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s2"&gt;"total_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s2"&gt;"used_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s2"&gt;"used_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"d56d3b8dd6894a508cf41b96b522328c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"total_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551856&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"used_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"ip_availability_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="s2"&gt;"total_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551868&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"total_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18446744073709551600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"used_ips_in_subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"used_ips_in_allocation_pool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="db-impact"&gt;
&lt;h3&gt;DB Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;New API extension: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network-ip-availability-details&lt;/span&gt;&lt;/code&gt; introducing new
attribute &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ip_availability_details&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="client-impact"&gt;
&lt;h3&gt;Client Impact&lt;/h3&gt;
&lt;p&gt;Relevant changes in openstackclient and openstacksdk to add support for new
attribute &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ip_availability_details&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Add new API extension &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network-ip-availability-details&lt;/span&gt;&lt;/code&gt;. This extension
extends network ip availability with field &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ip_availability_details&lt;/span&gt;&lt;/code&gt;
consists of attributes - total_ips_in_subnet, total_ips_in_allocation_pool,
used_ips_in_subnet, and used_ips_in_allocation_pool.&lt;/p&gt;
&lt;p&gt;New class &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;IpAvailabilityDetailsMixin&lt;/span&gt;&lt;/code&gt; will be added for the extension.
The class calculates value of the four attributes, and extends network ip
availability.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;jimin3-shin &amp;lt;&lt;a class="reference external" href="mailto:jimin3.shin%40samsung.com"&gt;jimin3&lt;span&gt;.&lt;/span&gt;shin&lt;span&gt;@&lt;/span&gt;samsung&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New test classes and methods will be added to test
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network-ip-availability-details&lt;/span&gt;&lt;/code&gt; extension.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests in neutron-tempest-plugin.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Tue, 22 Apr 2025 00:00:00 </pubDate></item><item><title>Provide Port Binding Information for Nova Live Migration</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/backlog/pike/portbinding_information_for_nova.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1580880"&gt;https://bugs.launchpad.net/neutron/+bug/1580880&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Nova Live Migration consists of 3 stages:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;pre_live_migration - executed before migration starts; the migration target
is already known, but the instance still resides on the source.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;live_migration_operation - migration itself which consists of 2 substages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;before the VM is running on the migration target compute.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;after VM is running on the destination compute, but migration is still in
progress (post copy migration).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;post_live_migration - executed after migration; source VM does not exist
anymore. Used for finalizing the migration.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Today, port binding occurs on the target compute host during migration,
considered now in the post_live_migration stage.  This, unfortunately, is
too late in the process as there are cases where Nova requires this
information in the pre_live_migration stage.  We simply cannot move the port
binding to the pre_live_migration stage as the original port binding would be
deleted, causing issues due to the instance being active still on the original
host.  Further details are contained in the ‘Alternatives’ section.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;For live migration improvements, it is required that Neutron allows port
binding on the target compute host during the pre_live_migration stage, without
removing the original port binding on the source compute.&lt;/p&gt;
&lt;p&gt;The proposal is to have a port binding on the source AND target compute hosts
where only one port binding is active.  After instance migration is complete,
the target port binding is activated and the source port binding is
deactivated, but not deleted.  The original port binding on the source compute
host is kept for a possible move of the instance back to the source, and will
only be removed during the post_live_migration stage.&lt;/p&gt;
&lt;p&gt;The issues can be divided in 2 categories:&lt;/p&gt;
&lt;p&gt;#1 Keep the source instance running if the port binding on the target fails:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Instance error state when port binding fails:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Today, the port binding is triggered in the post_live_migration stage,
after the migration has completed.  If the port binding fails, the
instance is then stuck in an error state.&lt;/p&gt;
&lt;p&gt;The solution is to move the port binding to the pre_live_migration stage,
where there is an opportunity to fail the port binding earlier.  This would
prevent the instance from being stuck in an errored state after the
migration is complete and fail the migration at a pre_live_migration stage.&lt;/p&gt;
&lt;p&gt;The issue with moving the port binding to the pre_live_migration stage is
that some drivers will shutdown the port binding on the source compute
host, even though the instance is still active.  To achieve a cleaner
migration solution, Neutron needs to be modified to allow a port binding
on both the source and target compute hosts in an active/inactive state.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;#2 Handling the differences in port binding details between hosts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Live migration between hosts running different l2 agents:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Another case to consider is the chance that the migration occurs between
two hosts running different l2 agents.  The requirement here is on Nova
to update the instance definition before the migration is executed. In the
case of libvirt, Nova would update the domain.xml with the target
interface definition.  For more information, refer to &lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/migration-use-target-vif"&gt;[3]&lt;/a&gt; and &lt;a class="reference external" href="https://review.openstack.org/#/c/301090/"&gt;[4]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A special case to consider is where a migration occurs between agents
with differing firewall drivers, i.e. from a host running the ovs
hybrid-fw driver to a host running the new ovs conntrackd firewall driver.&lt;/p&gt;
&lt;p&gt;Such a migration must only be allowed with source and target binding using
the same VNIC type.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Live migration with MacVTap agent when different physnet mappings are used:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;MacVTap today has restrictions with live migration in certain situations
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1550400"&gt;[1]&lt;/a&gt; and requires an update to the instance definition (libvirt
domain.xml) before starting a migration.&lt;/p&gt;
&lt;p&gt;Updating the instance definition occurs during the live_migration_operation
stage, before the instance is running on the target compute host.  Two port
bindings, one active at the source and one inactive at the target
host are required for this operation to succeed.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;For migration, Nova will require the port binding information from the target
compute during the pre_live_migration stage.  This can be achieved by allowing
a compute port to be bound to the migration source and the migration target
host.&lt;/p&gt;
&lt;p&gt;This can be achieved by the following steps:&lt;/p&gt;
&lt;p&gt;#1 Expand upon existing API entities under port, allowing CRUD bindings.&lt;/p&gt;
&lt;p&gt;#2 Update ML2 to support the changes.&lt;/p&gt;
&lt;p&gt;#3 Update the DB to support the changes.&lt;/p&gt;
&lt;section id="usage-by-nova"&gt;
&lt;h3&gt;Usage by Nova&lt;/h3&gt;
&lt;p&gt;Nova will utilize the expanded API, and the potential flow is as follows:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;pre_live_migration: Create the inactive binding for target host.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;live_migration_operation: Use information gathered from the inactive
binding to modify the instance definition.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;live_migration_operation: Once the instance is active, set the inactive
binding to active, and the previous active binding to inactive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;post_live_migration: Remove the inactive binding on the source
compute host.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;img alt="../../../_images/nova-live-migration-flow.png" src="../../../_images/nova-live-migration-flow.png"/&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If rollback is performed after the instance is active on target: From a
Neutron standpoint, if the binding is active on the target host, Nova will
need to set the source binding back to active:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bindings&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;activate&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more details on the Nova implementation , see the related Nova
Blueprint &lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/migration-use-target-vif"&gt;[3]&lt;/a&gt; and its Spec &lt;a class="reference external" href="https://review.openstack.org/#/c/301090/"&gt;[4]&lt;/a&gt;.  Neutron will not dictate the implemented
capabilities of Nova live migration and will support either path, to rollback
or to not rollback.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="binding-api-extension-for-ports"&gt;
&lt;h3&gt;Binding API Extension for Ports&lt;/h3&gt;
&lt;section id="list-bindings"&gt;
&lt;span id="list-binding"/&gt;&lt;h4&gt;List Bindings&lt;/h4&gt;
&lt;p&gt;GET /v2.0/ports/{port_id}/bindings&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"bindings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"host_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"source-host_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"vif_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ovs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"vif_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"port_filter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"ovs_hybrid_plug"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s2"&gt;"profile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
            &lt;span class="s2"&gt;"vnic_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"normal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"active"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"host_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"target-host_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"vif_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"bridge"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"vif_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"port_filter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s2"&gt;"profile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
            &lt;span class="s2"&gt;"vnic_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"normal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"inactive"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default" id="id13"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;Response Parameters&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Parameter&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Style&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;bindings&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:list&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A list of &lt;em&gt;binding&lt;/em&gt; objects&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;More parameters see &lt;a class="reference internal" href="#show-binding"&gt;&lt;span class="std std-ref"&gt;Show Binding&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Important key features of list bindings:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Compute bindings will currently be listed and a request for unsupported
bindings will return ‘NotImplemented’ until the capability is introduced.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All bindings will be listed and pagination will be used when many bindings
are returned.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="show-binding"&gt;
&lt;span id="id1"/&gt;&lt;h4&gt;Show Binding&lt;/h4&gt;
&lt;p&gt;GET /v2.0/ports/{port_id}/bindings/{host_id}&lt;/p&gt;
&lt;table class="docutils align-default" id="id14"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;Response Parameters&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Parameter&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Style&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;binding&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:dict&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A &lt;em&gt;binding&lt;/em&gt; object&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;host_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Hostname where the port is allocated.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;vif_type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The VIF type for this port binding determined during
portbinding&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;vif_details&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:dict&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A dictionary containing additional details for this specific
binding. The details are set by a mechanism driver.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;vnic_type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The VNIC type for this port binding.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;profile&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:dict&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A dictionary holding the vif profile.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;status&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Status of the binding &lt;a class="reference internal" href="#binding-status"&gt;&lt;span class="std std-ref"&gt;Status Usage&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"binding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s2"&gt;"host_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"target-host_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"vif_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"target-vif-type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"vif_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s2"&gt;"port_filter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="p"&gt;},&lt;/span&gt;
         &lt;span class="s2"&gt;"vnic_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'NORMAL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"profile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
         &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"active"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Important key features of show binding:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DVR ports exposed in this resource will show the real vif_type of
‘distributed’ ports as they are stored in DistributedPortBindings, i.e. ovs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="create-binding"&gt;
&lt;span id="id2"/&gt;&lt;h4&gt;Create Binding&lt;/h4&gt;
&lt;p&gt;POST /v2.0/ports/{port_id}/bindings&lt;/p&gt;
&lt;table class="docutils align-default" id="id15"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;Request Parameters&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Parameter&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Style&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;binding&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:dict&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A &lt;em&gt;binding&lt;/em&gt; object&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;host_id (mandatory)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Hostname where the port is allocated.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;vnic_type (optional, default = ‘normal’)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The VNIC type for this port binding.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;profile (optional)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:dict&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A dictionary holding the vif profile.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"binding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"host_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"target-host_id"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response parameters&lt;/p&gt;
&lt;p&gt;see &lt;a class="reference internal" href="#list-binding"&gt;&lt;span class="std std-ref"&gt;List Bindings&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"binding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"host_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"target-host_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"vif_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ovs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"vif_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"port_filter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"ovs_hybrid_plug"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
         &lt;span class="s2"&gt;"vnic_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'NORMAL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"profile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
         &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"active"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If the binding fails, a new return code of 4xx or 5xx should be returned. This
differs from today where a failed binding returns a 2xx response code and the
vif_type is set to “binding_failed”.&lt;/p&gt;
&lt;p&gt;Important key features of update/create binding:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;By default, the status will be active when creating a port binding.  If
a binding is created, doesn’t exist already, and an existing binding is
already active, the binding will default to inactive, requiring the
operator to activate the new binding.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If a binding being added already exists, a 4xx will be returned.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A compute port can only have 1 active binding at a time. This is not an
enforcement by Neutron, but a result of the operation surrounding
PortBinding. This feature expands the capability of having multiple bindings,
but will only allow for 1 active binding for compute ports.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;At this time, creation of a binding will be limited to compute ports.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The existing API is not touched, which will return host_id:{host_id} as the
current active binding.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Activating an inactive compute binding will deactivate the current
active binding.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="update-binding"&gt;
&lt;h4&gt;Update Binding&lt;/h4&gt;
&lt;p&gt;PUT /v2.0/ports/{port_id}/bindings/{host_id}&lt;/p&gt;
&lt;table class="docutils align-default" id="id16"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;Request Parameters&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Parameter&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Style&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;binding&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:dict&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A &lt;em&gt;binding&lt;/em&gt; object&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;All create parameters are valid for update as well. See &lt;a class="reference internal" href="#create-binding"&gt;&lt;span class="std std-ref"&gt;Create Binding&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"binding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"vnic_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'NORMAL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"profile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response parameters&lt;/p&gt;
&lt;p&gt;see &lt;a class="reference internal" href="#show-binding"&gt;&lt;span class="std std-ref"&gt;Show Binding&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"binding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"host_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"target-host_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"vif_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ovs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"vif_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"port_filter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"ovs_hybrid_plug"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"vnic_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'NORMAL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"profile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"bar"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"active"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;On failed binding, a 4xx or 5xx return code should be returned.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="activating-an-inactive-binding"&gt;
&lt;span id="activate-binding"/&gt;&lt;h4&gt;Activating an Inactive Binding&lt;/h4&gt;
&lt;p&gt;PUT /v2.0/ports/{port_id}/bindings/{host_id}/activate&lt;/p&gt;
&lt;p&gt;Response parameters&lt;/p&gt;
&lt;p&gt;see &lt;a class="reference internal" href="#show-binding"&gt;&lt;span class="std std-ref"&gt;Show Binding&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"binding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"host_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"target-host_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"vif_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ovs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"vif_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"port_filter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"ovs_hybrid_plug"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"vnic_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'NORMAL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"profile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"bar"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"active"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Important key features of activate binding:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Activating a compute binding that is inactive will deactivate the existing
active binding, as a compute port can only have 1 binding active at a time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operation will be limited to compute ports.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attempting to activate an existing active binding will return a 4xx.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Returns 5xx if activating the binding fails.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="delete-binding"&gt;
&lt;h4&gt;Delete Binding&lt;/h4&gt;
&lt;p&gt;DELETE /v2.0/ports/{port_id}/bindings/{host_id}&lt;/p&gt;
&lt;p&gt;This operation does not accept a request body and does not return a response
body.&lt;/p&gt;
&lt;p&gt;Important key features of delete binding:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Active/Inactive bindings can be removed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deleting an active compute port binding, where an inactive binding
exists does not activate the binding.  The operator will be required to
explicitly activate the binding.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="overlap-between-existing-vs-new-apis"&gt;
&lt;h4&gt;Overlap Between Existing vs New APIs&lt;/h4&gt;
&lt;p&gt;All the functionality of the existing API will be covered by the new API as
well. This section describes the overlap.&lt;/p&gt;
&lt;table class="docutils align-default" id="id17"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;Overlap existing vs. new API&lt;/span&gt;&lt;/caption&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Existing API&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;New API&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Show port with active binding&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;n/a&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Create port: directly with an active binding&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;n/a&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Update port: add host_id (which adds the active binding)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Add Binding&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Create port: without any binding&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;n/a&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Update port: change host_id (re-trigger port binding for another host)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Update binding&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Update port: set host_id to ‘’(remove the active binding)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Delete active binding&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Delete port: Remove port with all its bindings&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;n/a&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="effects-on-existing-apis"&gt;
&lt;h4&gt;Effects on Existing APIs&lt;/h4&gt;
&lt;p&gt;Slight adjustment to existing APIs:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Show Port will still just show the binding like today. For compute
ports, it would only show the active binding.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create Port will create an unbound binding as before, but with the status of
active.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update Port with host_id will still re-trigger port binding for a host.  The
difference will be &lt;cite&gt;update_port()&lt;/cite&gt; will only action on the active binding.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;vif_type is set to “binding_failed” and http code 2xx is still used
on failed port binding when binding is triggered via the existing
port binding extension.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-visibility"&gt;
&lt;h4&gt;API Visibility&lt;/h4&gt;
&lt;p&gt;A normal user should not be able to trigger any create/update/delete/activate
actions. This should only be possible via some special service user or the
admin role.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="sub-resource-extension"&gt;
&lt;h3&gt;Sub Resource Extension&lt;/h3&gt;
&lt;p&gt;Neutron &lt;cite&gt;ports&lt;/cite&gt; will be extended with a sub resource &lt;cite&gt;bindings&lt;/cite&gt;, having a
member name of &lt;cite&gt;port&lt;/cite&gt; to preserve portbindings and ports extensions.  The new
sub resource extension will be &lt;cite&gt;portbindings_extended.py&lt;/cite&gt; and have a parent
resource of &lt;cite&gt;ports&lt;/cite&gt;.&lt;/p&gt;
&lt;p&gt;The following methods will be added to the newly created service plugin
&lt;cite&gt;bindings_plugin.py&lt;/cite&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;get_port_bindings()&lt;/cite&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;get_port_binding()&lt;/cite&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;create_port_binding()&lt;/cite&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;update_port_binding()&lt;/cite&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;delete_port_binding()&lt;/cite&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;update_port_binding_activate()&lt;/cite&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="ml2-changes"&gt;
&lt;h3&gt;ML2 Changes&lt;/h3&gt;
&lt;p&gt;Existing methods &lt;cite&gt;create_port()&lt;/cite&gt; and &lt;cite&gt;update_port()&lt;/cite&gt; will need to be updated
to support actioning only on &lt;cite&gt;active&lt;/cite&gt; status bindings.  In addition, a new
status of &lt;cite&gt;inactive&lt;/cite&gt; will be introduced to neutron-lib for use in PortBinding.&lt;/p&gt;
&lt;section id="status-usage"&gt;
&lt;span id="binding-status"/&gt;&lt;h4&gt;Status Usage&lt;/h4&gt;
&lt;p&gt;The status column in PortBinding will store an additional state ‘inactive’
where the current states are ‘active’ and ‘down’.  Neutron-lib will
only require the addition of PORT_BINDING_STATUS_ACTIVE and
PORT_BINDING_STATUS_INACTIVE.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;neutron_lib&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;constants&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;const&lt;/span&gt;

&lt;span class="n"&gt;const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PORT_BINDING_STATUS_ACTIVE&lt;/span&gt;
&lt;span class="n"&gt;const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PORT_BINDING_STATUS_INACTIVE&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="create-update-delete-port"&gt;
&lt;h4&gt;Create/Update/Delete Port&lt;/h4&gt;
&lt;p&gt;New methods will be introduced in support of the new sub resource under ports,
but the current &lt;cite&gt;create_port()&lt;/cite&gt;, &lt;cite&gt;update_port()&lt;/cite&gt; and &lt;cite&gt;delete_port()&lt;/cite&gt; will be
modified to only act on &lt;cite&gt;active&lt;/cite&gt; bindings in the PortBinding table.&lt;/p&gt;
&lt;p&gt;Today, &lt;cite&gt;create_port()&lt;/cite&gt; adds an empty unbound binding in PortBinding and the
following changes will be made in support of this spec:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create an unbound binding with status &lt;cite&gt;active&lt;/cite&gt; in the PortBinding table.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition, &lt;cite&gt;update_port()&lt;/cite&gt; will be adjusted for &lt;cite&gt;active&lt;/cite&gt; status with the
following changes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update will only change binding information on the &lt;cite&gt;active&lt;/cite&gt; binding in the
PortBinding table.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, &lt;cite&gt;delete_port()&lt;/cite&gt; will be adjusted for &lt;cite&gt;active&lt;/cite&gt; status with the
following changes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Delete will only act on the &lt;cite&gt;active&lt;/cite&gt; binding in the PortBinding table.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="data-model-changes"&gt;
&lt;h3&gt;Data Model Changes&lt;/h3&gt;
&lt;p&gt;The PortBinding table will expand the primary key to column &lt;cite&gt;host&lt;/cite&gt;, allowing
selection of the binding based on &lt;cite&gt;port_id&lt;/cite&gt; and &lt;cite&gt;host&lt;/cite&gt;.&lt;/p&gt;
&lt;p&gt;In addition, a &lt;cite&gt;status&lt;/cite&gt; column will be introduced in the expansion where states
&lt;cite&gt;active&lt;/cite&gt;, &lt;cite&gt;down&lt;/cite&gt;, and &lt;cite&gt;inactive&lt;/cite&gt; will be values.&lt;/p&gt;
&lt;p&gt;Online upgrades, Blueprint &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/adopt-oslo-versioned-objects-for-db"&gt;[9]&lt;/a&gt;, requires the addition of &lt;cite&gt;host&lt;/cite&gt; to
primary_keys and a new field &lt;cite&gt;status&lt;/cite&gt; for Port Binding OVO. Version of the
object should be bumped if push-notifications, under Blueprint &lt;a class="reference external" href="https://review.openstack.org/#/c/225995/"&gt;[10]&lt;/a&gt;,  will
be merged first, and PortBinding object will be present on the RPC wire.
Defining a default value for the &lt;cite&gt;status&lt;/cite&gt; field would not require online
data migration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="changes-to-mechanism-drivers"&gt;
&lt;h3&gt;Changes to Mechanism Drivers&lt;/h3&gt;
&lt;p&gt;A new mechanism driver method is required to determine if the new way
of binding things is supported. This must be validated for all binding
levels and allow fallback to previous methods.  By default, new method will
return unsupported.&lt;/p&gt;
&lt;p&gt;Besides the in tree mechanism drivers for l2 agents (ovs, lb, sr-iov, macvtap)
the following drivers need to be considered:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;l2pop (however there are ideas to eliminate l2pop)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ironic&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;third party mechanism drivers&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="activate-rpc-port-update-delete"&gt;
&lt;h4&gt;Activate RPC Port Update/Delete&lt;/h4&gt;
&lt;p&gt;The existing &lt;cite&gt;port_update&lt;/cite&gt; and &lt;cite&gt;port_delete&lt;/cite&gt; RPC message will be adjusted to
send, when the agent retrieves device information with
&lt;cite&gt;get_devices_details_list_and_failed_devices&lt;/cite&gt;, specific binding information
for the host regardless of binding state. This will allow the addition of
additional plumbing to occur as follows:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Activate will result in a &lt;cite&gt;port_update&lt;/cite&gt;, which will pass the relative binding
information for the host and dictate the transition from inactive to active
in the &lt;cite&gt;get_devices_details_list_and_failed_devices&lt;/cite&gt; response. This will
allow for a GARP to be sent out, updating the topology to a change in status.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Activate will result in a &lt;cite&gt;port_delete&lt;/cite&gt; rpc call to the source host, removing
the source VIF.  This will need to be accomplished due to Nova not being able
to issue a delete port, as the port still exists on a different host.  The
binding will remain in an &lt;cite&gt;inactive&lt;/cite&gt; state where binding information has
been populated, but the port, from an agent perspective, will not exist.
In addition, the transition from active to inactive will be indicated in the
rpc call, influencing the &lt;cite&gt;update_device_list&lt;/cite&gt; to not update the port state.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;img alt="../../../_images/rpc-portbinding-flow.png" src="../../../_images/rpc-portbinding-flow.png"/&gt;
&lt;p&gt;In the case where push-notifications are implemented for ports under Blueprint
&lt;a class="reference external" href="https://review.openstack.org/#/c/225995/"&gt;[10]&lt;/a&gt; the &lt;cite&gt;get_devices_details_list_and_failed_devices&lt;/cite&gt; would not be adjusted
for transition state.  Instead, the binding transition state would be sent to
the agent as part of the port object.  The remaining actions are the same.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="other-changes"&gt;
&lt;h3&gt;Other changes&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron/Openstack Python Client support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron-Lib support of new constant PORT_STATUS_INACTIVE
see &lt;a class="reference internal" href="#activate-binding"&gt;&lt;span class="std std-ref"&gt;Activating an Inactive Binding&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="command-line-client-impact"&gt;
&lt;h3&gt;Command Line Client Impact&lt;/h3&gt;
&lt;p&gt;Support for port bindings will be needed in OSC.  The following will be added:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ openstack port binding list {ARGS} &amp;lt;port&amp;gt;

$ openstack port binding show {ARGS} &amp;lt;port&amp;gt; &amp;lt;host&amp;gt;

$ openstack port binding create {ARGS} &amp;lt;port&amp;gt;

$ openstack port binding update {ARGS} &amp;lt;port&amp;gt; &amp;lt;host&amp;gt;

$ openstack port binding delete {ARGS} &amp;lt;port&amp;gt; &amp;lt;host&amp;gt;

$ openstack port binding activate {ARGS} &amp;lt;port&amp;gt; &amp;lt;host&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There should be no performance impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Impact to Nova live migration, and is directly in support of their efforts.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;Yes.  This change has been discussed on the ML, in Neutron meetings
(especially ML2), at mid-cycles, and at the design summit.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative is to use the current resources under ports to facilitate this
change to live migration.  The problem is, current dict structures would need
to be expanded to accommodate the ‘bindings’ key.  This may cause some
confusion as the user already receives ‘bindings:profile’ and various other
values.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:
* &lt;a class="reference external" href="https://launchpad.net/~libosvar"&gt;Jakub Libosvar&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Please add your name here and attend the &lt;a class="reference external" href="https://wiki.openstack.org/wiki/Meetings/Neutron-ML2-Subteam"&gt;ML2 Subteam Meeting&lt;/a&gt; if you’d
like to contribute.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Addition of a scenario test, &lt;cite&gt;test_bindings.py&lt;/cite&gt;, to walk through the creation
of a source migration instance, creation of the inactive binding on a secondary
host, creation of a secondary target migration instance, activating the
inactive binding, deactivating the source migration active binding, and then
validating connectivity is still working.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Additional functional tests will be added to &lt;cite&gt;ml2/test_plugin.py&lt;/cite&gt; to expand
on the current port binding tests. This will accommodate for a status check
in the case of adding an inactive binding.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Bindings resource (CRUD)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bindings resource (CRUD) and validation of active binding under current
ports extension.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create detailed explanation of active/inactive binding operation in
&lt;cite&gt;devrefml2_port_bindings.rst&lt;/cite&gt;.  This should detail changes to ml2, and the
extended &lt;cite&gt;ports&lt;/cite&gt; resource.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Wed, 20 Nov 2024 00:00:00 </pubDate></item><item><title>Layer 3 service plugin for the Cisco APIC</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/apic-l3-service-plugin.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/cisco-apic-l3"&gt;https://blueprints.launchpad.net/neutron/+spec/cisco-apic-l3&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint is to implement Layer 3 features in
the network fabric via a L3 router service plugin
using the Cisco APIC.&lt;/p&gt;
&lt;p&gt;Flows&lt;/p&gt;
&lt;img alt="../../_images/cisco-apic-l3-flow.png" src="../../_images/cisco-apic-l3-flow.png"/&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The APIC (Application Policy Infrastructure Controller) together with
Cisco Nexus 9000 switches provides programmable, policy-driven network
control.&lt;/p&gt;
&lt;p&gt;The Service plugin proposed will interact with the APIC to dynamically
configure Layer 3 inter and intra tenant communications in the network fabric.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This proposal is to introduce a new Layer 3 service plugin that communicates
with the APIC.&lt;/p&gt;
&lt;p&gt;The driver implements the following neutron events:
* Add a new router interface
* Delete a router interface&lt;/p&gt;
&lt;p&gt;The plugin will implement Layer 3 communications using a construct called
a contract that provides communications in the fabric between various
end point groups (Neutron networks)&lt;/p&gt;
&lt;p&gt;Events that trigger the creation of end point groups and subnets (i.e.
create_network and create_subnet) will be handled by the APIC ML2 mechanism
driver and id’s will be stored in a database accessed by a common client and
manager class.&lt;/p&gt;
&lt;p&gt;Due to hardware limitations as of this writing this service plugin will
only handle add/remove router_interface (internal gateway) events. The service
plugin may be expanded in the future to also handle all neutron L3 events.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The alternative approach is to use the open source agent based layer 3 router
plugin. The agent based approach does not implement any policies that are
centric to the APIC’s ACI (Application Centric Infrastructure) based design.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;n.a.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;n.a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;n.a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;n.a.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;n.a.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The service plugin is triggered instead of polled, there are no
changes to any existing code patterns. The potential bottleneck
for this plugin would be the link between neutron and the APIC.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;There are no config options specific to the Layer 3 plugin, it relies
on the configuration options of the ML2 apic mechanism driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;n.a.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Arvind Somya &amp;lt;asomya&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Single work item for the L3 APIC service plugin.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Depends on the APIC ML2 blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ml2-cisco-apic-mechanism-driver"&gt;https://blueprints.launchpad.net/neutron/+spec/ml2-cisco-apic-mechanism-driver&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Complete unit test coverage of the code is included.&lt;/p&gt;
&lt;p&gt;For tempest test coverage, third party testing is provided. The Cisco
CI reports on all changes affecting this driver. The testing is run in
a setup with an OpenStack deployment (devstack) connected to a live
APIC and a Cisco Nexus 9000 physical switch.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Deployment documentation on how to configure and deploy this service plugin
will be documented in the Openstack wiki.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.cisco.com/go/apic"&gt;http://www.cisco.com/go/apic&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 20 Nov 2024 00:00:00 </pubDate></item><item><title>Database Migration Refactoring</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/db-migration-refactoring.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/db-migration-refactor"&gt;https://blueprints.launchpad.net/neutron/+spec/db-migration-refactor&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The neutron database schema will be made consistent. It will be independent of
the configured core plugin and service plugins.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The database schema is different based on which core and service plugins are
configured. If a new or different plugin is configured after a deployment is
started, the earlier migrations that correspond with the new configuration will
be missing.&lt;/p&gt;
&lt;p&gt;This means that the migration process is not idempotent, resulting in schema
versions which depend on the current configuration. In other words, when one
environment’s schema is at a specific version it may not be the same as another
environment at the same version. This even happens in the same environment
during a downgrade if the configuration changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Make all migrations unconditional. Make a single point in the migration
timeline where all tables are created and the database schema is the same no
matter which plugins are used.&lt;/p&gt;
&lt;p&gt;This solution will introduce a “healing” migration that will call the DDLs
needed to complete the database schema so that it contains all tables for all
database models. This migration will occur in the timeline between the
&lt;strong&gt;icehouse_release&lt;/strong&gt; version and the &lt;strong&gt;juno_release&lt;/strong&gt; version.&lt;/p&gt;
&lt;p&gt;The refactoring will comprise the following:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Investigation of models and current migrations to establish what is needed
to achieve the complete database schema.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A healing migration that ensures that the database schema is complete and
consistent. The version will be named &lt;strong&gt;db_healing&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All migrations after &lt;strong&gt;db_healing&lt;/strong&gt; will be unconditional. This requires
updating the behavior of the –autogenerate for neutron-db-manage, and
documentation for developers.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The healing migration will work like any other alembic migration, i.e. it will
allow upgrade and downgrade. However, it will be different in the following
aspects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In the upgrade direction the healing migration will introspect the schema and
only add tables that are missing. Therefore it cannot be run in offline
mode. (See also &lt;a class="reference internal" href="#onlinedetails"&gt;&lt;span class="std std-ref"&gt;Online Requirement&lt;/span&gt;&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;Upgrade Notes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;When the healing migration starts, all table schema changes for existing
tables will already be in place (either directly from the model, or from
previous migrations). For each missing table, the healing migration will
add the table by creating its schema from the model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The healing migration may need to alter some existing tables to match its
model. We won’t know for sure until the proposed implementation is tested
in more detail. These alterations, if needed, will be dealt with on a
case-by-case basis. For more details, see the &lt;a class="reference internal" href="#implementation"&gt;&lt;span class="std std-ref"&gt;Implementation&lt;/span&gt;&lt;/a&gt;
section.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the downgrade direction the healing migration will make no schema
changes. This means it will not remove any tables.&lt;/p&gt;
&lt;p&gt;Downgrade Notes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If a deployment is upgraded and then downgraded through the healing
migration, the schema will contain tables that were not present before. In
other words, if a deployment downgrades back to Icehouse or Havana, Neutron
will appear and behave as before, yet if you look at the DB it is not the
old Icehouse or Havana DB but a healed one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If during the upgrade a table was altered to match its model, then the
downgrade will reverse the alteration if needed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="migration-timeline"&gt;
&lt;h3&gt;Migration Timeline&lt;/h3&gt;
&lt;img alt="../../_images/db-migration-timeline.png" src="../../_images/db-migration-timeline.png"/&gt;
&lt;/section&gt;
&lt;section id="online-requirement"&gt;
&lt;span id="onlinedetails"/&gt;&lt;h3&gt;Online Requirement&lt;/h3&gt;
&lt;p&gt;More reasons why we cannot support offline mode for the healing migration:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;We cannot use “create table if not exists” because it is only supported by
specific sql dialects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dependencies between tables (e.g. foreign keys) mean we would need to check
that all tables with dependencies on the current one are already created.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Alembic has no support for conditional DDL.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Instead of a healing migration we could break the migration timeline after
Icehouse and create a new one beginning at Juno that includes all tables. A
manual script could be provided to convert the schema from the old timeline to
the new. This alternative approach has the following disadvantages:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;It would not allow a downgrade via migration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Switching from the old timeline to the new timeline is more a complex process
for the deployer and DB Administrator than a simple migration in one timeline.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We would need to support two migration timelines in neutron until the
Icehouse release is deprecated.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Some database models may need to be updated in order to have non-conflicting
models based on core and service plugins.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;End (non-admin) users should see no impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The healing migration is an online operation that must be run by the DB
Administrator. Thus the deployer must co-ordinate with the DBA when upgrading
or downgrading through Juno.&lt;/p&gt;
&lt;p&gt;The healing migration will be run when migrating from Icehouse or earlier
to Juno. It behaves like a normal migration, but it does not support upgrade in
offline mode.&lt;/p&gt;
&lt;p&gt;Downgrade of the healing migration does nothing. Thus all tables are present in
the schema if downgrading from &lt;strong&gt;db_healing&lt;/strong&gt; to a previous version.&lt;/p&gt;
&lt;p&gt;Note: Greenfield deployment of the Juno release or later will start at the new
migration timeline and therefore no healing will be involved.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;span id="id1"/&gt;&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Most of the work lies in developing a robust healing migration. Alembic will be
used where possible to maximize automation, but some healing may need to be
manually coded.&lt;/p&gt;
&lt;p&gt;Examples of conflicts which may need manual coding to resolve:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If two different migrations for two different plugins add an attribute with
the same name but different type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If an ENUM was modified in an earlier migration but its specification was not
updated for PostgreSQL.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;akamyshnikova&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;libosvar&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;rpodolyaka&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit (and functional?) testing of migrations shall be added. We plan to utilize
the unit test framework from the graduated oslo.db package.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create Release Note for this change.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update Operators Guide for upgrading.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update Developer Documentation for creating migration scripts.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Wed, 20 Nov 2024 00:00:00 </pubDate></item><item><title>Provider Networking - upstream SLAAC Support</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/ipv6-provider-nets-slaac.html</link><description>

&lt;p&gt;It should be possible to create a Provider Network in Neutron, that uses an
upstream switch or router that advertises RA’s - so that instances can use
SLAAC to configure their IPv6 networking, while still utilizing the Neutron
APIs for security group rules.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ipv6-provider-nets-slaac"&gt;https://blueprints.launchpad.net/neutron/+spec/ipv6-provider-nets-slaac&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;A deployer of OpenStack that wishes to use IPv6 and already has
configured IPv6 on northbound networking devices, may wish to
advertise IPv6 routes by having non-OpenStack hardware transmit
ICMPv6 Router Advertisement packets.&lt;/p&gt;
&lt;img alt="../../_images/provider-network-slaac.png" src="../../_images/provider-network-slaac.png"/&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;OpenStack Neutron should support this configuration, and display the
correct IP address for instances, since Neutron has enough information
to generate the EUI-64 address.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The Neutron REST API for IPv6 Subnets allows the following
combinations, as well as disallowing certain combinations. In short,
when &lt;strong&gt;both&lt;/strong&gt; ipv6_ra_mode and ipv6_address_mode are set, they must be
equal. When only one attribute is set, the setting is automatically
valid.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;ipv6_ra_mode&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;ipv6_address_mode&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;valid&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;RA Settings&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;ATTR_NOT_SPECIFIED&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ATTR_NOT_SPECIFIED&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ANY&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;ATTR_NOT_SPECIFIED&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;slaac&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;“A=1,M=0,O=0”&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;ATTR_NOT_SPECIFIED&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dhcpv6-stateful&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;“A=0,M=1,O=1”&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;ATTR_NOT_SPECIFIED&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dhcpv6-stateless&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;“A=1,M=0,O=1”&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;slaac&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ATTR_NOT_SPECIFIED&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;“A=1,M=0,O=0”&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;dhcpv6-stateful&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ATTR_NOT_SPECIFIED&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;“A=0,M=1,O=1”&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;dhcpv6-stateless&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ATTR_NOT_SPECIFIED&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;“A=1,M=0,O=1”&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;slaac&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;slaac&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;“A=1,M=0,O=0”&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;dhcpv6-stateful&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dhcpv6-stateful&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;“A=0,M=1,O=1”&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;dhcpv6-stateless&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dhcpv6-stateless&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;“A=1,M=0,O=1”&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;slaac&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dhcpv6-stateful&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;no&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UNDEF&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;slaac&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dhcpv6-stateless&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;no&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UNDEF&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;dhcpv6-stateful&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;slaac&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;no&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UNDEF&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;dhcpv6-stateful&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dhcpv6-stateless&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;no&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UNDEF&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;dhcpv6-stateless&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;slaac&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;no&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UNDEF&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;dhcpv6-stateless&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dhcpv6-stateful&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;no&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UNDEF&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This blueprint will implement the functionality required to satisfy
IPv6 Subnets that are set with ipv6_address_mode set to ‘slaac’, and
ipv6_ra_mode not set.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This change will require support in python-neutronclient for the two
IPv6 subnet attributes - which &lt;a class="reference external" href="https://review.openstack.org/#/c/75871/"&gt;is currently in review&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This change will change the behavior of Neutron in specific
configurations, when the IPv6 attributes for Subnets are set.
Previously, the attributes were no-ops.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Subnets will be created with the &lt;cite&gt;ipv6_address_mode&lt;/cite&gt; set to &lt;cite&gt;slaac&lt;/cite&gt;
and &lt;cite&gt;ipv6_ra_mode&lt;/cite&gt; &lt;strong&gt;not&lt;/strong&gt; set.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron will calculate the IP address of a port, using the MAC address
and the CIDR.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;scollins&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/86044/"&gt;Support Subnets that are configured by external RAs&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/64578/"&gt;Ensure entries in dnsmasq belong to a subnet using DHCP&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The IPv6 Subnet Attributes must be returned in API calls.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add unit tests to support Subnets created with only the
&lt;cite&gt;ipv6_address_mode&lt;/cite&gt; set.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify that ports with allocations from a subnet with
&lt;cite&gt;ipv6_address_mode&lt;/cite&gt; set are not touched by the DHCP agent.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation about this network configuration will need to be
written.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2014-February/026589.html"&gt;Devstack for IPv6 in the Comcast lab&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 20 Nov 2024 00:00:00 </pubDate></item><item><title>‘security_group_rules_for_devices’ RPC call refactoring</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/security-group-rules-for-devices-rpc-call-refactoring.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/security-group-rules-for-devices-rpc-call-refactor"&gt;https://blueprints.launchpad.net/neutron/+spec/security-group-rules-for-devices-rpc-call-refactor&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Security group rules synchronization from neutron-server to L2 agents scales
poorly for high density clouds, leading to a blocked neutron-server in some
situations.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The security_group_rules_for_devices RPC call from L2 agents to
neutron-server doesn’t scale well because all the security group rule entries
are expanded with each specific IP address (see &lt;a class="footnote-reference brackets" href="#call-results" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;) in a security
group, when that group is referenced in rules like:&lt;/p&gt;
&lt;p&gt;allow all from ‘default’ group for IPv4 and IPv6&lt;/p&gt;
&lt;p&gt;This leads to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;huge AMQP messages (&amp;gt;20-600 MB)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;very long processing time at neutron-server side when we have lots of
instances under the same tenant/security group (&amp;gt;60 seconds)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;neutron-server lockups, when RPC call times out at agent side, and the same
security_group_rules_for_devices call is issued back to neutron.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For a more detailed insight:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;security_group_rules_for_devices is an RPC call from the L2 agents to
neutron-server, see &lt;a class="footnote-reference brackets" href="#call-results" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This call’s arguments are a list of device_ids, device_ids are connected
to ports. Neutron builds a list &lt;a class="footnote-reference brackets" href="#call-results" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; of security group rules and
returns the list of security group rules per device_id&lt;/p&gt;
&lt;p&gt;The message size between neutron-server and L2 agent will grow
according to the following formula:&lt;/p&gt;
&lt;p&gt;MessageSize ~= base + L * Instances_in_host * (Instances_in_security_group-1)&lt;/p&gt;
&lt;p&gt;Where L = len(str(security_group_rule)) ~=440 bytes&lt;/p&gt;
&lt;p&gt;This problem is more likely to happen in big clouds, or denser
ones, but it’s an issue, as nova can scale to 10x instances
without incident: see &lt;a class="footnote-reference brackets" href="#n2nov-scaling" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Refactor the security_group_rules_for_devices into a new call
‘security_group_rules_for_devices_compact’, which instead of returning
&lt;a class="footnote-reference brackets" href="#call-results" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; , returns a more compact result
that can be expanded by the l2 agent.&lt;/p&gt;
&lt;p&gt;The new ‘security_groups_rules_for_devices_compact’ RPC call returns:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'security_groups'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'sg-id1'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'rules'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;{},{},{},{}]}&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="s1"&gt;'security_group_member_ips'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s1"&gt;'sg-id1'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'ipv4'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'192.168.11.2/32'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                                             &lt;span class="s1"&gt;'ipv6'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
                                 &lt;span class="s1"&gt;'sg-id2-referenced-from-id1'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                               &lt;span class="p"&gt;},&lt;/span&gt;

 &lt;span class="s1"&gt;'devices'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'dev-id1'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s1"&gt;'fixed_ips'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'192.168.11.4'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                         &lt;span class="s1"&gt;'security_groups'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'sg-id1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'sg-id2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Security group rules would be passed in a non-expanded way, which implies
that any reference to src or dst security groups in rules would be stored
as security group ids.&lt;/p&gt;
&lt;p&gt;A response like this (old result):&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'dev-id1'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'security_group_rules'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'egress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv6'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s1"&gt;'security_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                             &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'egress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'security_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ingress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'protocol'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'icmp'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'security_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ingress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'remote_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'security_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'source_ip_prefix'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'192.168.11.2/32'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ingress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'remote_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'security_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'source_ip_prefix'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'192.168.11.3/32'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ingress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'remote_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'security_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'source_ip_prefix'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'192.168.11.4/32'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ingress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'remote_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'23138476-4fde-454e-33ad-abc123456782'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'security_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'source_ip_prefix'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'192.168.33.4/32'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                            &lt;span class="p"&gt;]&lt;/span&gt;
 &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="s1"&gt;'dev-id2'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s1"&gt;'security_group_rules'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'egress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv6'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'security_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'egress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'security_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ingress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'protocol'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'icmp'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'security_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ingress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'remote_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'security_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'source_ip_prefix'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'192.168.11.2/32'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ingress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'remote_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'security_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'source_ip_prefix'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'192.168.11.3/32'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ingress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'remote_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'security_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'source_ip_prefix'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'192.168.11.4/32'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ingress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'remote_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'security_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'source_ip_prefix'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'192.168.11.5/32'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ingress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'remote_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'23138476-4fde-454e-33ad-abc123456782'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'security_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'source_ip_prefix'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'192.168.33.4/32'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                            &lt;span class="p"&gt;]&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Would be like this in the new version:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'security_groups'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'rules'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                         &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'egress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv6'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                         &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'egress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv4'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                         &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ingress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="s1"&gt;'protocol'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'icmp'&lt;/span&gt;&lt;span class="p"&gt;,},&lt;/span&gt;
                         &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ingress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="s1"&gt;'remote_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                               &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                         &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ingress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="s1"&gt;'ethertype'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'IPv4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="s1"&gt;'remote_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                               &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'23138476-4fde-454e-33ad-abc123456782'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                        &lt;span class="p"&gt;]&lt;/span&gt;
                       &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="s1"&gt;'security_group_member_ips'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
                                 &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ipv4'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'192.168.11.2/32'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                           &lt;span class="s1"&gt;'192.168.11.3/32'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                           &lt;span class="s1"&gt;'192.169.11.4/32'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                           &lt;span class="s1"&gt;'192.168.11.5/32'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                                  &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ipv6'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
                                 &lt;span class="p"&gt;},&lt;/span&gt;
                                 &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'23138476-4fde-454e-33ad-abc123456782'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
                                 &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ipv4'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'192.168.33.2/32'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                                  &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'ipv6'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
                                 &lt;span class="p"&gt;}&lt;/span&gt;
                               &lt;span class="p"&gt;},&lt;/span&gt;

 &lt;span class="s1"&gt;'devices'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'dev-id1'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s1"&gt;'fixed_ips'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'192.168.11.4'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                         &lt;span class="s1"&gt;'security_groups'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                          &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="s1"&gt;'dev-id2'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s1"&gt;'fixed_ips'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'192.168.11.4'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                         &lt;span class="s1"&gt;'security_groups'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                          &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'1809f907-4b0c-4445-a366-ff28eaab9c2e'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;

             &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;All security groups referenced from devices will be included in the
response.&lt;/p&gt;
&lt;p&gt;All security group members ip addresses from all remote_group_id referenced
groups will be included in the response.&lt;/p&gt;
&lt;p&gt;The old call could be marked as deprecated during this J cycle,
and removed during K cycle.&lt;/p&gt;
&lt;p&gt;Making the refactor into a new call would have the following advantages:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Compatibility during neutron-server upgrade with older agents&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ability to split patches (server/agents) in more steps, as we will have
the ability to address the new call, while keeping the agents calling
the old one, and then refactor the agents in further steps.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The resulting message size would be:&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;MessageSize ~= base +&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;D * Instances_in_host +
L * Referenced_security_groups +
I * Instances_in_referenced_security_groups&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Where L = len(str(compact_security_group_rule)) ~= 220 bytes&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;D = len(str(device_description_including_ips_and_sg_ids))
I = len(str(ip_address + ‘,’)) ~= 17 bytes&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;In the new message format no data is replicated, thus now two variables
become multiplication factors.&lt;/p&gt;
&lt;p&gt;Next steps:&lt;/p&gt;
&lt;p&gt;There is a proposal from Édouard Thuleau to use an RPC topic per security
group &lt;a class="footnote-reference brackets" href="#sec-fanout" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; which would be addressed in a second iteration after
this one.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Instead of including all the security groups in one rpc call, this could
be split to a second call, ‘security_groups_and_referenced_members’, which
would receive a list of security groups ids, and would return a list of
security groups and a list of security group ip addresses.
A full sync would require 2 calls to neutron server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We could have a ‘security_groups’ and a ‘security_groups_members’, which
would provide the security groups, without member IP addresses and,
a list of IPv4 and IPv6 addresses members for each security group.
A full sync would require 3 calls to neutron server. But this approach
would allow separate communication of new members in security groups,
or new rules in security groups, further reducing the information transmited
in those cases. As for the first alternative, reducing the traffic volume
by increasing the number of calls seems like a bad tradeoff due to the
overhead/latency generated by each call.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We could just compact CIDR ranges in rules generation, that wouldn’t
require modifications to the agents, but that would increase the
rpc request processing time.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The performance impact should be very positive in the next situations:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Security group changes: neutron-server load, and AMQP message sizes.
At this moment oslo messaging serializes structures to JSON because of
AMQP version limitations (string sizes for dictionaries is
one of those). Reducing the message size will reduce the dictionary
building time and also the serialization time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creation time for new ports&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Even higher performance impact in packet processing would be achieved
by the optimization at iptables level which is proposed in the ipset spec
&lt;a class="footnote-reference brackets" href="#ipset-spec" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If tranmission times become our bottleneck instead of processing times
we may consider compression if that’s available at the AMQP level.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;I’m unsure if there are proprietary l2-agents talking to the RPC.
We would allow some time for those to be upgraded by introducing
it as a new RPC call instead of modifying the existing one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All the agents that use this RPC call would need to be updated
to the new call before removing the old one.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~mangelajo"&gt;https://launchpad.net/~mangelajo&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="http://launchpad.net/~shihanzhang"&gt;http://launchpad.net/~shihanzhang&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Refactor the rpc call into a new one in neutron-server and
and the matching rpc call at the agent mixin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add functional testing to validate the approach.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upgrade the agents to use the new call, one by one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Analyze db access and file a new spec if improvements can
be made in this area.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Functional testing will validate the approach and make sure
the result that was possible with the old method can be
consistently replicated (only faster) with the new method.
Testing both rpc calls with functional testing will avoid
regressions in both of the code paths, while testing this
in Tempest only allows testing the default rpc call.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="call-results" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;,&lt;a role="doc-backlink" href="#id5"&gt;4&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.fpaste.org/104401/14008522/"&gt;http://www.fpaste.org/104401/14008522/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="n2nov-scaling" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://javacruft.wordpress.com/2014/06/18/168k-instances/"&gt;http://javacruft.wordpress.com/2014/06/18/168k-instances/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="sec-fanout" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2014-June/038374.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2014-June/038374.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ipset-spec" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/100761/"&gt;https://review.openstack.org/#/c/100761/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Wed, 20 Nov 2024 00:00:00 </pubDate></item><item><title>Agent child processes status</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/agent-child-processes-status.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/agent-child-processes-status"&gt;https://blueprints.launchpad.net/neutron/+spec/agent-child-processes-status&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron agents spawn external detached processes which run unmonitored, if
anything happens to those processes neutron won’t take any action,
failing to provide those services reliably.&lt;/p&gt;
&lt;p&gt;We propose monitoring those processes, and taking a configurable action,
making neutron more resilient to external failures.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;When a ns-metadata-proxy dies inside an l3-agent &lt;a class="footnote-reference brackets" href="#liveness-bug" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;,
subnets served by this ns-metadata-proxy will have no metadata until there
are any changes to the router, which will recheck the metadata agent
liveness.&lt;/p&gt;
&lt;p&gt;Same thing happens with the dhcp-agent &lt;a class="footnote-reference brackets" href="#dhcp-agent-bug" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and also
in lbaas and vpnaas agents.&lt;/p&gt;
&lt;p&gt;This is a long known bug, which generally would be triggered
by bugs in dnsmasq, or the ns-metadata-proxy, and specially critical
on big clouds and HA environments.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;I propose to monitor the spawned processes using the
neutron.agent.linux.external_process.ProcessMonitor class, which relies
on the ProcessManager to check liveness periodically.&lt;/p&gt;
&lt;p&gt;If a process that should be active is not, it will be logged, and we
could take any of the following admin configured actions, in the
configuration specified order.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Respawn the process: The failed external process will be respawned.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Exit the agent: for use when an HA service manager is taking care of the
agent and will respawn it, optionally in a different host. During exit
action, all other external processes will be left running as for any
other agent stop. So there is no downtime for the unaffected tenant network
until the HA solution takes care of failing over the agent. In case of
failover, responsibility for cleanup (processes and ports) lies on
neutron-netns-cleanup and neutron-ovs-cleanup.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In future follow ups, we plan to implement a notify action to the process manager
when the corresponding piece lands in oslo &lt;a class="footnote-reference brackets" href="#oslo-service-status" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Examples of configurations could be:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Disabled, external processes are not polled for liveness&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;check_child_processes_period&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Log (implicit) and respawn&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;check_child_processes_action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;respawn&lt;/span&gt;
&lt;span class="n"&gt;check_child_processes_period&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Log (implicit) and notify&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;check_child_processes_action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;notify&lt;/span&gt;
&lt;span class="n"&gt;check_child_processes_period&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Log (implicit), and exit&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;check_child_processes_action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exit&lt;/span&gt;
&lt;span class="n"&gt;check_child_processes_period&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This feature will be enabled by default (60 seconds), and default
action will be ‘respawn’.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Some extra periodic load will be added by checking the underlying
children. Locking of other green threads will be diminished by starting
a green thread pool for checking the children. A semaphore is introduced
to avoid several check cycles from starting concurrently.&lt;/p&gt;
&lt;p&gt;As there were concerns on polling /proc/$pid/cmdline, I implemented a
simplistic benchmark:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10000000&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt;  &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/proc/8125/cmdline'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'r'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;readlines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Please note that the cmdline file is addressed by kernel functions &lt;a class="footnote-reference brackets" href="#kernel-cmdline" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;9&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;
in memory and does not rely on any I/O over a block device, that means there is no
cache speeding up the read of this file which would invalidate this benchmark.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="nd"&gt;@ns316109&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="c1"&gt;# time python test.py&lt;/span&gt;
&lt;span class="n"&gt;real&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;m59&lt;/span&gt;&lt;span class="mf"&gt;.836&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;m23&lt;/span&gt;&lt;span class="mf"&gt;.681&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="n"&gt;sys&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;m35&lt;/span&gt;&lt;span class="mf"&gt;.679&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;That means, 170.000 reads/s using 1 core / 100% CPU on a 7400 bogomips machine.&lt;/p&gt;
&lt;p&gt;If we had to check 1000 children processes we would need 1000/170000 = 0.0059
seconds plus the overhead of the intermediate method calls and the spawning
of greenthreads.&lt;/p&gt;
&lt;p&gt;I believe ~ 6ms CPU usage to check 1000 children is rather acceptable, even
though the check interval is tunable, and it’s disabled by default
to let the deployers balance the performance impact with the failure detection
latency.&lt;/p&gt;
&lt;p&gt;Polling isn’t ideal, but the alternatives aren’t either, and
we need a solution for this problem, specially for HA environments.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;No effect on IPv6 expected here.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;People implementing their own external monitoring of the subprocesses, may
need to migrate into the new solution, taking advantage of the exit method,
or a later notify one when that’s available.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Developers which spawn external processes may start using ProcessMonitor
instead of using ProcessManager directly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change has been discussed several times on the mailing list, IRC,
and previously accepted for Juno, but didn’t make it to the deadline
on time. It’s something desired by the community, as it makes neutron
agents more resilient to external failures.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Use popen to start services in the foreground and wait on SIGCHLD
instead of polling. It wouldn’t be possible to reattach after
we exit or restart an agent because the parent will detach from
the child and it’s not possible to reattach when agent restarts
(without using ptrace which sounds too hackish). This is a
POSIX limitation.
In our design, when an agent exits, all the underlying children
stay alive, detached from the parent and continue to run
to make sure there is no service disruption during upgrades.
When the agent starts again, it will check in /var/neutron/{$resource}/
for the pid of the child that serves each resource, and it’s
configuration, and make sure that it’s running (or restart it
otherwise). This is the point we can’t re-attach, or wait &lt;a class="footnote-reference brackets" href="#waitpid" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;
for an specific non-child PID &lt;a class="footnote-reference brackets" href="#waitpid-non-child" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Changing the restart mechanism of agents to an execve from inside
the agent itself (via signal capture). The execve system call
retains original PID and children PID relationship, thus we
could wait on children pid. But this prevents stop/start capability
of agents which could be handy during maintenance and development.
If we decide to change this in the future, ProcessMonitor implementation
could be easily modified to non-polling-wait on pids without changing
any of it’s API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use a intermediate daemon to start long running processes and
monitor them via SIGCHLD as a workaround for the problems in the first
alternative. This is very similar to the soon-to-be available
functionality in oslo rootwrap daemon, but rootwrap daemon won’t
be supporting long running processes yet, even though the problem
with this alternative is the case when the intermediate process
manager dies or gets killed. In that case we lose control
over the spawn children (that we would be monitoring via SIGCHLD).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instead of periodically checking all children, spread the load
in several batches over time. That would be a more complicated
implementation, which probably could be addressed on a second
round or as a last work item if the initial implementation doesn’t
perform as expected for a high amount of resources (routers, dhcp
services, lbaas..).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Initially, the notification part was planned to be implemented
within neutron itself, but the design has been modularized in
oslo with drivers for different types (systemd, init.d, upstart..).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~mangelajo"&gt;https://launchpad.net/~mangelajo&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~brian-haley"&gt;https://launchpad.net/~brian-haley&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Adding brian-haley as I’m taking a few of his ideas, and reusing
partly his work on &lt;a class="footnote-reference brackets" href="#check-metadata" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;ProcessMonitor, and functional testing: done&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement in dhcp-agent, refactoring the code duplication
with neutron.agent.linux.external_process. &lt;a class="footnote-reference brackets" href="#dhcp-impl" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement in l3-agent &lt;a class="footnote-reference brackets" href="#l3-impl" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement in lbaas-agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement in vpnaas-agent&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Notes: a notify action was planned, but it’s depending on a new oslo feature,
this action can be added later via bug process once the oslo feature is accepted
and implemented.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;The notify action depends on the implementation of &lt;a class="footnote-reference brackets" href="#oslo-service-status" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;,
but all the other features/actions can be acomplished without that.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Tempest tests are not capable of doing arbitrary execution of command
in the network nodes (killing processes for example). So we can’t use
tempest to check this without implementing some sort of fault injection
in tempest.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional testing is used to verify the ProcessMonitor class, in charge
of the core functionality of this spec.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;The new configuration options will have to be documented per agent.&lt;/p&gt;
&lt;p&gt;This are the proposed defaults:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;check_child_processes_action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;respawn&lt;/span&gt;
&lt;span class="n"&gt;check_child_processes_period&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="dhcp-impl" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;DHCP agent implementation:
&lt;a class="reference external" href="https://review.openstack.org/#/c/115935/"&gt;https://review.openstack.org/#/c/115935/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="l3-impl" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;L3 agent implementation:
&lt;a class="reference external" href="https://review.openstack.org/#/c/114931/"&gt;https://review.openstack.org/#/c/114931/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="dhcp-agent-bug" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Dhcp agent dying children bug:
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1257524"&gt;https://bugs.launchpad.net/neutron/+bug/1257524&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="liveness-bug" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;L3 agent dying children bug:
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1257775"&gt;https://bugs.launchpad.net/neutron/+bug/1257775&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="check-metadata" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Brian Haley’s implementation for l3 agent
&lt;a class="reference external" href="https://review.openstack.org/#/c/59997/"&gt;https://review.openstack.org/#/c/59997/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="oslo-service-status" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id3"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id10"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;Oslo service manager status notification spec
&lt;a class="reference external" href="http://docs-draft.openstack.org/48/97748/3/check/gate-oslo-specs-docs/ef96358/doc/build/html/specs/juno/service-status-interface.html"&gt;http://docs-draft.openstack.org/48/97748/3/check/gate-oslo-specs-docs/ef96358/doc/build/html/specs/juno/service-status-interface.html&lt;/a&gt;]&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="waitpid" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://linux.die.net/man/2/waitpid"&gt;http://linux.die.net/man/2/waitpid&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="waitpid-non-child" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://stackoverflow.com/questions/1058047/wait-for-any-process-to-finish"&gt;http://stackoverflow.com/questions/1058047/wait-for-any-process-to-finish&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="kernel-cmdline" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;9&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/torvalds/linux/blob/master/fs/proc/cmdline.c#L8"&gt;https://github.com/torvalds/linux/blob/master/fs/proc/cmdline.c#L8&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Wed, 20 Nov 2024 00:00:00 </pubDate></item><item><title>Add Subnet Allocation to IPAM</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/subnet-allocation.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/subnet-allocation"&gt;https://blueprints.launchpad.net/neutron/+spec/subnet-allocation&lt;/a&gt;&lt;/p&gt;
&lt;dl class="field-list simple"&gt;
&lt;dt class="field-odd"&gt;Author&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-odd"&gt;&lt;p&gt;Carl Baldwin &amp;lt;&lt;a class="reference external" href="mailto:carl.baldwin%40hp.com"&gt;carl&lt;span&gt;.&lt;/span&gt;baldwin&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class="field-even"&gt;Co-Author&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-even"&gt;&lt;p&gt;Ryan Tidwell &amp;lt;&lt;a class="reference external" href="mailto:ryan.tidwell%40hp.com"&gt;ryan&lt;span&gt;.&lt;/span&gt;tidwell&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The current implementation of IPAM does not provide a mechanism to set up an
address space from which subnets can be allocated.  This will be needed in
order to automatically allocate addresses for subnets instead of requiring
subnet details at the time of creation.&lt;/p&gt;
&lt;p&gt;This becomes very important with IPv6 where floating IPs are not implemented.
A tenant may want to create a network with addresses that are routable:  not
just that the addresses are globally unique – because all IPv6 addresses
should be – but that the operator can actually route them.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;IPAM in Neutron cannot allocate subnets.  Subnet details must be specified by
the End User at the time of subnet creation.&lt;/p&gt;
&lt;p&gt;End Users may want to offload the burden of keeping track of subnets and which
addresses are in use.  In this case, the End User should be able to set up a
private address space from which these are automatically allocated.  For IPv4,
this will often be a portion of the RFC1918 address space but doesn’t need to
be.  It might be part of a corporate address space which has been delegated to
the cloud.  For IPv6, the End User may want Neutron to automatically calculate
a useable ULA subnet using a pseudo-random algorithm in harmony with RFC4193
&lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.  This implies that the algorithm for the selection of subnets within the
space is pluggable in some way.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://tools.ietf.org/html/rfc4193"&gt;http://tools.ietf.org/html/rfc4193&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;p&gt;Deployers will set up external networks and may have a chunk of routable
addresses that could be leased or delegated to tenants for use on their
networks.&lt;/p&gt;
&lt;p&gt;Neutron needs an API for creating and managaging address spaces and making them
available to tenants.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="overview"&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
&lt;p&gt;The purpose of this blueprint is to enable creation and management of subnet
allocation pools. This will require changes to the core API and will also require a
modification to subnet creation to allow specifying an address space id and a
prefix length in lieu of actual subnet address details.&lt;/p&gt;
&lt;p&gt;A reference implementation for this new feature will be added to implement this
along with the included reference IPAM implementation.&lt;/p&gt;
&lt;p&gt;A subnet pool can be shared or not shared.  Only admins can create shared pool.&lt;/p&gt;
&lt;p&gt;A quota mechanism will be added for shared pools.  Quotas will be expressed in
terms of the number of minimum atomically allocatable address units.  To keep
the math simple, the unit size will be hard-coded at /32 for IPv4 and /64 for
IPv6.  Counting the total number of addresses with IPv6 will make things
cumbersome since even an unsigned 64 bit integer is not sufficient to express
numbers this large.  It would also require extra complexity around presentation
in order to present these numbers to a user in a way that makes any sense at
all.  The implementation will share code between IP versions.  The only
difference will be the prefix size constant.&lt;/p&gt;
&lt;p&gt;The resource quotas are applied to is not the SubnetPool, but rather IP
addresses.  As such, the current quota engine is not able to perform this
operation so management and enforcement should occur in a custom fashion.&lt;/p&gt;
&lt;p&gt;Operators may want to charge for allocations (hopefully not with IPv6) but the
mechanism by which they can do this is beyond this bp’s scope.&lt;/p&gt;
&lt;p&gt;A quota mechanism will be used for the number of SubnetPools which can be
created per tenant just to avoid excessive abuse of the API.&lt;/p&gt;
&lt;section id="address-scoping"&gt;
&lt;h4&gt;Address Scoping&lt;/h4&gt;
&lt;p&gt;There should be one SubnetPool for each address scope.  The pool simply tells
us what addresses are available within the scope for allocation. It is out of
this bp’s scope to implement anything more.  However, in the future, there may
be more use cases for allowing routing across scopes.  For example:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;NAT may be used in IPv4 even without external networks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Two scope owners may agree that routing should be allowed.  This might
be useful when RBAC is implemented to allow tenants to cross-plug networks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A tenant has some globally routable addresses and wants to work it out with
the cloud operator to route it externally.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Neutron has been implicitly using a single scope per tenant.  Address
uniqueness is not explicitly enforced in this scope.  Most tenants likely
already do this on their own.  However, Neutron has not been enforcing
uniqueness within a tenant’s address scope.&lt;/p&gt;
&lt;p&gt;Overlapping addresses will be allowed for IPv4 pools. By default, the pool will
allow overlapping. This can be changed by setting a flag when creating the pool.
Overlapping will not be allowed under any circumstances inside IPv6 pools. However,
there will be no enforcement of uniqueness across pools.&lt;/p&gt;
&lt;p&gt;Multinetting on a network using subnets from different pools will be allowed.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;New objects will be added:&lt;/p&gt;
&lt;p&gt;SubnetPool&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the pool.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Name of the pool&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;tenant id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The tenant owning the space.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;shared&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;boolean&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Whether the pool is shared.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;version&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4 or 6&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;allow overlap&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;boolean&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Whether the pool allows overlapping&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;min prefix len&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Largest subnet that can be allocated.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;default prefix len&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The default subnet size to allocate&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;SubnetPoolRanges&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Subnet Pool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier of the SubnetPool&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;first ip&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Integer&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;last ip&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Integer&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;SubnetAllocation&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the allocation.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Subnet Pool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier of the SubnetPool&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;IP Version&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4 or 6&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;prefix&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The allocated network address prefix&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;prefix len&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The prefix length&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The pool_id field will be added to Subnet:&lt;/p&gt;
&lt;p&gt;Subnet&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;All fields as currently implemented&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;pool id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ID of the pool the subnet was allocated from&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;When the subnet is either not allocated from a pool or is migrated during upgrade,
pool_id will be ‘null’.&lt;/p&gt;
&lt;p&gt;No data migration is necessary.  The standard script to create the initial
empty tables will be provided.&lt;/p&gt;
&lt;p&gt;Needing an availability table like in existing address IPAM is not anticipated.
This will be computed dynamically.  Subnet allocation will be performed much
less often than port allocation and won’t be as contentious in the database.
This is an implementation detail to be worked out later.  The availability
table or some other clever solution may be necessary after all.&lt;/p&gt;
&lt;p&gt;Avoiding overlap in the reference implementation will be a little trickier than
with simple IP address allocation.  It can’t use a simple unique constraint on
the database because we want to support allocating subnets of different sizes,
especially for IPv4.  It could store allocations in terms of the minimum
allocation size.  So, a larger subnet allocation would be stored using multiple
rows in the database.  If SubnetPools were always of reasonable size, storing
availability and allocations in the same table by prepopulating the entire
table might be feasible.  This is an implementation detail that can be worked
out during code review.&lt;/p&gt;
&lt;p&gt;If we stored allocations in terms of the minimum allocation size then we will
have problems if that size is updated after the pool was created.  For example,
if the minimum size is increased, then what happens to existing allocations
that are already smaller and don’t align with the new size?&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Subnet details become optional in subnet-create.  Instead, an address space can
be chosen along with a prefix length indicating the size of the subnet desired.
This table summarizes changes to the subnet creation API.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;cidr&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;allocated automatically&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;address pool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;same as cidr&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;none&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Must exist and tenant must have access&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Pool to allocate from&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;allocation pools&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;-Use 0.0.0.0/NN&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;gateway ip&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Use 0.0.0.0&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Allocation pools and gateway ips can still be specified as they are with
current subnet creation.  Since the actual subnet address is not known, they
must be specified using 0 as a wildcard prefix (0.0.0.0/NN) for the subnet where NN is the prefix length
chosen.  The actual network prefix will be filled in when it has been
allocated.  For example, if I send this in a successful subnet create call:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;cidr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0.0.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;
&lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;some&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;gateway_ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0.0.1&lt;/span&gt;
&lt;span class="n"&gt;allocation_pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0.0.64&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.0.0.126&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;I might get this back:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;cidr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;10.10.10.128&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;
&lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;some&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;gateway_ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;10.10.10.129&lt;/span&gt;
&lt;span class="n"&gt;allocation_pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;10.10.10.192&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;10.10.10.254&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In some cases, the tenant is perfectly content with a default prefix length determined by the pool.
This has utility with IPv6 where the tenant just needs to be allocated a /64.  In such cases,the
pool is configured with a default prefix length and tenants have no need to supply a  prefix length
when requesting a subnet from the pool. For example, a subnet create call using the default prefix
length of the pool (/25 in this case) would look like this:&lt;/p&gt;
&lt;p&gt;Request:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;cidr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;specified&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;some&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;gateway_ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0.0.1&lt;/span&gt;
&lt;span class="n"&gt;allocation_pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0.0.192&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.0.0.254&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Allocation:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;cidr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;10.10.10.128&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;
&lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;some&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;gateway_ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;10.10.10.129&lt;/span&gt;
&lt;span class="n"&gt;allocation_pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;10.10.10.192&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;10.10.10.254&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The following explains how cidr and address pool can be used
together.  The basic rules are that cidr and prefix are mutually exclusive and
one must be specified.  If a prefix length is specified, a pool must be
specified too. The exception to this is if an option global default pool is
defined in neutron.conf.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;cidr&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;address pool&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;action&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"/&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Error when no global default pool defined&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;else subnet with default prefix length is allocated&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;specified&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Allocate using the pool’s default prefix length&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;specify specific CIDR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Same as before.  Uses Implicit tenant address pool.&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;specify specific CIDR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;specified&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Tries allocating specified subnet from pool.&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;specify wildcard CIDR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;specified&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Subnet with requested prefix length from pool.&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;specify wildcard CIDR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Error when no global default pool defined&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;else allocate subnet from global pool&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;New errors from the API are possible:  SubnetPoolNotFound,
PrefixLengthTooBig/Small, NoAddressesAvailable.&lt;/p&gt;
&lt;p&gt;New methods need to be added to create and manipulate SubnetPools.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Required&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation Constraints&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Notes&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"/&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID representing the address space&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, owner&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;name of the pool&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;shared&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all (if True); RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;False&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True/False&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;whether other tenants see it&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;version&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, owner&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4/6&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The IP version&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;allow overlap&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True if version=4&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;False if version=6&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True/False&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;allow overlapping subnets&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;min prefix len&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, owner&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;viable prefix lengths for IP version&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The IP version&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;default prefix len&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, owner&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;determined by min_prefix_len and version&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&amp;gt; min_prefix_len &amp;amp; &amp;lt; max version prefix&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;default prefix allocation len&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;ranges&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, owner&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list(2-tuples or CIDR’s)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;valid non-overlapping ranges&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Basically, if shared is True then all tenants can read all fields.  If it is
not true then only the owner can see the pool.  Only the owner is able to
write the fields in any case.  Only admin can write to the shared field.&lt;/p&gt;
&lt;p&gt;For IPv4, the prefix lengths should be between 8 and 30.  For IPv6, likely
between 32 and 64.&lt;/p&gt;
&lt;p&gt;There are certain parts of the IPv6 address space that are simply not specified
for any kind of use (i.e. outside 2000::/3, fc00:/7 for ULA, and other specified
scopes) &lt;a class="footnote-reference brackets" href="#ipv6-addr" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.  Some validation is called for.  The following address spaces should
be allowed:&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="ipv6-addr" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml"&gt;http://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Addresses&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;2000::/3&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Global unicast&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;fc00::/7&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ULA addresses which can be routable within sites.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;If ranges are updated after the initial creation, nothing will be done about
existing subnet allocations that happen to fall outside of the new ranges.&lt;/p&gt;
&lt;p&gt;This bp will start with the same shared model that we have now for networks.
However, an RBAC mechanism can be added later similar to the one proposed for
networks &lt;a class="footnote-reference brackets" href="#network-rbac" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="network-rbac" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/132661/"&gt;https://review.openstack.org/#/c/132661/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;There is an new API.  With any new API, there is the potential for new attacks
on the system.  For example, if someone could obtain control over an address
space, they could shrink it down to nothing and prevent further allocations.&lt;/p&gt;
&lt;p&gt;As long as only admins can create shared pools and quotas are in place on the
shared pools, there should be no new vulnerabilities introduced. With that said,
particular attention should be paid during code review to guard against the
introduction of new ones.&lt;/p&gt;
&lt;p&gt;Someone with unlimited control of an address space could potentially fill it up
as another way to prevent any further allocations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Allocation is performed on subnet create.  This may involve a couple of
significant database queries.  Subnet create is not nearly as common as a port
create so this is not expected to be a problem.  Use of optimistic locking
techniques should mitigate the impact.&lt;/p&gt;
&lt;p&gt;The new API methods for creating and updating pools aren’t expected to be
called often enough to have any significant impact.&lt;/p&gt;
&lt;p&gt;We should consider atypical use cases in addition to the typical.  If the
implementation performs very poorly, it could be used as a denial of service
attack and pose a Security Risk. This should be addressed during code review.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;This new feature must work for IPv6 equally as well as IPv4.  This is intended
to enhance the IPv6 experience in Neutron.  There will be no effect on existing
IPv6 features in Neutron.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;By default, the cloud system will work like it does today except that tenants
will have the ability to create their own pools without any deployer action.&lt;/p&gt;
&lt;p&gt;The deployer may use the shared pools feature to create pools of addresses that
will be available to tenants for use on their networks but is not required to.
They will likely want to use this feature if they want to route to tenant
networks either globally or within the datacenter.&lt;/p&gt;
&lt;p&gt;External IPAM may be used with this new API.  Development of external IPAM
drivers is out of the scope of this blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change was discussed at the Kilo design summit in the pluggable IPAM
session.  It has also been discussed with the IPv6 subteam.  This has been
recognized as a need for the community, especially for IPv6 routing. With
this API, the IPv6 subteam can just use prefix delegation as a mechanism
for handing out allocations, after a user has made a request to this API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~ryan-tidwell"&gt;ryan-tidwell&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~carl-baldwin"&gt;carl-baldwin&lt;/a&gt;
L3 Subteam&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;subnetpools REST API and corresponding DB support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adjustments to subnets API and DB schema&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Minimal Horizon enablement to support basic subnet allocation (v4 &amp;amp; v6)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functional Test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API test&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;This blueprint depends on the work in the neutron-ipam &lt;a class="footnote-reference brackets" href="#neutron-ipam" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; one.
That blueprint adds some of the frame-work necessary to implement this
new feature. For further information, see the Etherpad &lt;a class="footnote-reference brackets" href="#ipam-etherpad" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit test all new code of course.  This means that the code structure must be
testable.  Will use TDD.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create v4 subnetpool&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create v6 subnetpool&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allocate v4 subnet from subnetpool&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allocate v6 subnet from subnetpool&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Verify quota enforcement&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lower tenant quota, verify previously allocated resources intact, verify enforcement of new value&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assert applicable subnet allocation details not leaking cross-tenant with shared pools&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create subnetpools with allow_overlap=True and allow_overlap=False, verify allocation of subnets&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Verify defaults on subnetpool creation of v4 pools&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify defaults on subnetpool creation of v6 pools&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify allow_overlap is constrained to False for v6 pools&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create v4 subnetpool, verify shared and allow_overlap values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create v6 subnetpool, verify shared and allow_overlap values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allocate v4 subnet from subnetpool, assert success and subnet details&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allocate v6 subnet from subnetpool, assert success and subnet details&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Update networking API reference
Update admin guide&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="neutron-ipam" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-ipam"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-ipam&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ipam-etherpad" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/neutron-ipam"&gt;https://etherpad.openstack.org/p/neutron-ipam&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Wed, 20 Nov 2024 00:00:00 </pubDate></item><item><title>Pluggable IPAM Subsystem in Neutron</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/neutron-ipam.html</link><description>

&lt;p&gt;Launchpad blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-ipam"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-ipam&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint introduces the pluggable IPAM subsystem in Neutron that allows
flexible control over the lifecycle of network resources like the following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Fixed IP addresses assigned to Neutron ports&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Floating IP addresses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Network address ranges, i.e. sub-networks&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Users have a requirement to integrate OpenStack into their existing
infrastructure that uses external IPAM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Currently most (if not all) Neutron plugins leverage an IPAM implementation
that is embedded in the db_base_plugin implementation. While this works well
in a self-contained system, it makes it difficult or impossible to integrate
with an external IPAM backend without terrible hacks.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The current architecture of Neutron does not allow users to implement
their own IPAM mechanism in any other way other than introducing their own
core plugin. That is, while the DHCP provider can be changed, the actual
allocation logic cannot.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="overview"&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
&lt;p&gt;The proposed change is the addition of a well-defined, abstract IPAM interface,
and the refactoring of the existing NeutronDbPluginV2 to utilize that interface
rather than directly perform IPAM actions on its own. A related blueprint &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;
is proposed to implement a reference IPAM driver that captures the current
behavior.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/reference-ipam-driver"&gt;https://blueprints.launchpad.net/neutron/+spec/reference-ipam-driver&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;section id="ipam-interface"&gt;
&lt;h4&gt;IPAM Interface&lt;/h4&gt;
&lt;p&gt;IPAM subsystem architecture overview is shown below. There is an abstract base
class defined, IPAMDriver. There will be a reference implementation of this
class - NeutronIPAM - that will encapsulate the current behavior. The IPAMDriver
can be subclassed by third parties to implement different IPAM behaviors, such
as different subnet or IP allocation strategies, or access to an external IPAM
system.&lt;/p&gt;
&lt;p&gt;The Neutron Plugins will call into the driver for IPAM functionality.&lt;/p&gt;
&lt;p&gt;The driver interface will be synchronous.&lt;/p&gt;
&lt;img alt="../../_images/driver-interface.png" src="../../_images/driver-interface.png"/&gt;
&lt;p&gt;The IPAM implementation will define abstract Request classes for subnets and
addresses. These classes enable the caller to request subnet or IP allocations
using criteria other than the explicit subnet or address, though implementation
of request criteria other than the existing behavior is not within scope of
this blueprint.&lt;/p&gt;
&lt;p&gt;See &lt;a class="footnote-reference brackets" href="#id4" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; for the interface definition. The details of this interface are
not part of this spec, and work on this interface may continue beyond approval
of this spec.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/134339/"&gt;https://review.openstack.org/#/c/134339/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;section id="interaction-examples"&gt;
&lt;h4&gt;Interaction Examples&lt;/h4&gt;
&lt;p&gt;An example interaction scenario between Neutron Plugins and IPAM are shown in
the following diagram. In this diagram and the one that follows, “Pluggable
IPAM” represents an optional external IPAM system. These diagrams are intended
as examples; the specific details of each flow will be defined during
implementation.&lt;/p&gt;
&lt;img alt="../../_images/interaction-example-1.png" src="../../_images/interaction-example-1.png"/&gt;
&lt;p&gt;Here is another flow demonstrating the call to create a port. In this case,
the IPAM driver is called in order to retrieve a subnet, &lt;em&gt;or&lt;/em&gt; allocate the
subnet if not found. That is, the “get_subnet” call may simply retrieve an
existing subnet from the Neutron database, or it may go to an external IPAM
system to query or allocate the subnet. The behavior is left to the discretion
of the driver.&lt;/p&gt;
&lt;p&gt;The IPAMSubnet object is used for the IP allocation.&lt;/p&gt;
&lt;img alt="../../_images/interaction-example-2.png" src="../../_images/interaction-example-2.png"/&gt;
&lt;/section&gt;
&lt;section id="driver-creation"&gt;
&lt;h4&gt;Driver Creation&lt;/h4&gt;
&lt;p&gt;The IPAMDriver will contain a factory method to generate specific driver
instances. There will be a driver instance per SubnetPool (see &lt;a class="footnote-reference brackets" href="#id6" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;). However,
in this release only a single driver will be supported across the deployment.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/subnet-allocation"&gt;https://blueprints.launchpad.net/neutron/+spec/subnet-allocation&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;p&gt;Note that this BP will not provide any database or API for the SubnetPool. As
part of this BP only a minimal implementation will be created.&lt;/p&gt;
&lt;p&gt;The IPAM driver to use for a SubnetPool is specified through the configuration
file /etc/neutron/neutron.conf. The default value will point to the reference
NeutronIPAM driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="refactoring"&gt;
&lt;h4&gt;Refactoring&lt;/h4&gt;
&lt;p&gt;The existing NeutronDbPluginV2 must be refactored to utilize the new IPAM
interface. Several core plugins make calls to IPAM-related private methods in
the NeutronDbPluginV2. Stub versions of those methods must be left in place and
be refactored to utilize the IPAM interface, or the plugins must themselves be
refactored to avoid calling private methods of the base class. The current
implementation within those methods will be moved to the reference driver.&lt;/p&gt;
&lt;p&gt;While the driver will enable an external IPAM system to provide the
authoritative response on whether to allocate a new address or subnet, the
Neutron database will still be required to have an accurate representation
of the currently allocated subnets and IP addresses. Queries for existing
allocations will still access the local database rather than call out through
the driver. The synchronization of external IPAM and Neutron during initial
migration and for ongoing verification purposes is the responsibility of the
driver author, either within the driver or external to it.&lt;/p&gt;
&lt;p&gt;The DB activities currently done in NeutronDbPluginV2 would better be handled
via composition rather inheritance. The base plugin could have a database
handler object that performs these functions. This would enable the database
transaction to be performed outside (after) the addressing decision is made by
the external system. This avoids a call involving I/O during an open
transaction, which can lead to deadlock issues due to a MySQL connector flaw.&lt;/p&gt;
&lt;p&gt;This goes beyond the IPAM functions, of course. The idea here being
that all the plugins still need the core data in the Neutron DB even if they
may need to store additonal data or perform additional actions during these
calls.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="out-of-scope-items"&gt;
&lt;h3&gt;Out-of-Scope Items&lt;/h3&gt;
&lt;p&gt;Several related functions have been discussed in relation to this blueprint.&lt;/p&gt;
&lt;p&gt;DHCP options such as nameservers and host routes are intentionally de-coupled
from the IPAM implementation. Pluggable DHCP would require a separate effort,
or must be addressed within the individual drivers.&lt;/p&gt;
&lt;p&gt;Similarly, integrations with Designate or other external DNS services during
IPAM activities is out-of-scope.&lt;/p&gt;
&lt;p&gt;IPAM Regional Internet Registries (RIRs) life-cycle management and automation
is beyond the scope of this blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;There will be no data model changes for this implementation, only the addition
of interfaces and non-persistent classes. Rather, related data model updates
are captured in &lt;a class="footnote-reference brackets" href="#id8" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, though this is not strictly required for this blueprint.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/subnet-allocation"&gt;https://blueprints.launchpad.net/neutron/+spec/subnet-allocation&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;IPAM subsystem implementation of the default Neutron driver should have
similar performance to the current Neutron IPAM. The performance impact of
external IPAM drivers is beyond the scope of this document.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;Support for IPv6 is a requirement of this specification.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;A new configuration option to specify the desired IPAM driver will be available
in the neutron.conf file. If this value is not specified Neutron Server will
fallback to the default Neutron IPAM driver in the default location. This
choice was made to support backward compatibility with older neutron.conf files
that do not have this option specified.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;By default the Neutron should work as it does today. Supplied reference IPAM
driver should encapsulate current functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As core plugins override several methods from the base plugin class, we will
evaluate impact of the IPAM changes to those plugins.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change was discussed at the Juno and Kilo Design summits. There was
support for Pluggable IPAM, see link to the Etherpad in the Reference
section of document.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="id9"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;John Belamaric (jbelamaric)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Salvatore Orlando (salvatore-orlando)
Carl Baldwin (carl-baldwin)
Ryan Tidwell (ryan-tidwell)
Hosung Hwang (hhwang-2)
Yue Ko (yko)
Pavel Bondar (pasha117)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Create IPAM abstract interfaces.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create pluggable IPAM for db_base_plugin_v2.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Move all the IPAM-related functionality from db_base_plugin_v2 to the
Neutron IPAM plugin.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/reference-ipam-driver"&gt;https://blueprints.launchpad.net/neutron/+spec/reference-ipam-driver&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The existing unit test will be used when appropriate and unit test coverage
will be expanded to cover refactored Neutron IPAM code.&lt;/p&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Existing Functional Tests will be used when appropriate, refactoring of IPAM
may require additional or refactored functional tests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;The existing Neutron Tempest tests will be utilized to test the default Neutron
IPAM that will be developed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;No change to API proposed.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Admin guide will be updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;API guide will be updated.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/neutron-ipam"&gt;https://etherpad.openstack.org/p/neutron-ipam&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/subnet-allocation"&gt;https://blueprints.launchpad.net/neutron/+spec/subnet-allocation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/134339/"&gt;https://review.openstack.org/#/c/134339/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 20 Nov 2024 00:00:00 </pubDate></item><item><title>Dynamic Advertising Routes for Public Ranges</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/bgp-dynamic-routing.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/bgp-dynamic-routing"&gt;Blueprint Link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The goal of this blueprint is to add dynamic routing capability to OpenStack
deployment. This feature would allow Neutron to advertise its own routes to an
external router using the BGP protocol.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;This is a new feature and this section will describe use cases where dynamic
routing may be useful.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Expose External Networks Dynamically&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Allow Neutron to dynamically announce to external uplink routers.&lt;/p&gt;
&lt;p&gt;An OpenStack cloud would run a routing protocol (for example, BGP) against at
least one router in each uplink network provider. By announcing network
prefixes to those peers, the Neutron network would be reachable by the rest of
the internet via both paths. If the link to an uplink provider broke, the
failure information would propagate to routers further up the stream, keeping
the cloud reachable through the remaining healthy link.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sample Topology&lt;/strong&gt;&lt;/p&gt;
&lt;img alt="../../_images/bgp-sample-topology-1.png" src="../../_images/bgp-sample-topology-1.png"/&gt;
&lt;p&gt;Please note that in this diagram, the red gateway router is actually a linux
machine with a software BGP speaker and a software router. This blueprint
proposes to configure this BGP speaker through the Neutron API (see below).&lt;/p&gt;
&lt;p&gt;This also would be a valid scenario for an internal cloud, where the uplink
router is actually one’s provider router and the routes are advertised using
iBGP.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Routed Model for Floating IPs on External Network&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This use case will allow an external network with a large public IP space to
possibly span more than one L2 network. This could allow for improved scale and
isolation between AZs while maintaining the appearance of a large external
network where floating IPs and networks can float freely.&lt;/p&gt;
&lt;p&gt;This use case may also include announcing public networks behind Neutron routers
to an upstream router. For example, this will be useful for IPv6 networks when
using the &lt;cite&gt;subnet-allocation&lt;/cite&gt; mechanism to allocate routable IPv6 prefixes to
tenant networks. It does not require learning routes from the upstream router.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1453921"&gt;Address Scopes&lt;/a&gt; blueprint adds a new L3 context to make public routable tenant
networks (among other advantages). Address Scopes may leverage this development
to advertise the new routable subnets to uplink routers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sample Topology&lt;/strong&gt;&lt;/p&gt;
&lt;img alt="../../_images/bgp-sample-topology-2.png" src="../../_images/bgp-sample-topology-2.png"/&gt;
&lt;p&gt;The topology of this use case can be seen as a generalization of the previous
one, with a multi-homed OpenStack installation and leverage the fact that a
floating IP can be seen as a /32 network.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="overview"&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
&lt;p&gt;A new system that dynamically advertises routes to other peers outside the
OpenStack deployment is proposed. From the Neutron API, cloud administrator
should be able to define these peers as well as the way to interact with them.&lt;/p&gt;
&lt;section id="routing-peer"&gt;
&lt;h4&gt;Routing Peer&lt;/h4&gt;
&lt;p&gt;A system that supports dynamic routing must be able to advertise its own
routes to its peers. It order to achieve this goal the system must know the list
of its peers and be able to trust the information that it receives from them.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="route-advertisement"&gt;
&lt;h4&gt;Route Advertisement&lt;/h4&gt;
&lt;p&gt;Routes added manually by administrator will be advertised to external dynamic
routing peers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="dynamic-routing-system"&gt;
&lt;h4&gt;Dynamic Routing System&lt;/h4&gt;
&lt;p&gt;In default implementation a new system will be used to manage dynamic routing
information at the edge of OpenStack deployment. Dynamic peering will not be
performed by each individual Neutron router due to scaling concerns. Such an
approach could create an inordinately high number of peering relationships.
Instead, the model proposed sets up a speaker to represent the Neutron
deployment as a whole to external routers.&lt;/p&gt;
&lt;p&gt;This system will allow different implementations (develop your own BGP speaker
implementation, for instance) to fit into third party requirements.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;The implementation must be able to exchange IPv4 and IPv6 routes.  This
blueprint may be even more important with IPv6 to complete routing from outside
the cloud to tenant networks running IPv6.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="solution-proposed"&gt;
&lt;h3&gt;Solution Proposed&lt;/h3&gt;
&lt;p&gt;Reference implementation will employ a dynamic routing agent (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dr_agent&lt;/span&gt;&lt;/code&gt;).
This agent will have direct connectivity with configured peers and it will be
responsible to update the dynamic routes of some defined routers. Another spec
will be filled to define the details of this implementation.&lt;/p&gt;
&lt;p&gt;So, through the Neutron API, cloud administrator should be able to define the
peer connections for each agent according to his needs.&lt;/p&gt;
&lt;p&gt;The cloud administrator will be able to execute the following new actions,
through the Neutron API:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BGPSpeaker&lt;/span&gt;&lt;/code&gt; entity with configuration options of the BGP
connection. First approach will only need the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;local_as&lt;/span&gt;&lt;/code&gt; attribute. Future
implementations, such as the &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-route-policy-support-for-dynamic-routing-protocol"&gt;policy support for dynamic routing&lt;/a&gt;, will need
to add more attributes here. The implementation driver need to read this
configuration options an establish BGP sessions to its peers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RoutingPeer&lt;/span&gt;&lt;/code&gt; entity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Associate a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RoutingPeer&lt;/span&gt;&lt;/code&gt; entity to a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BGPSpeaker&lt;/span&gt;&lt;/code&gt;. The
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BGPSpeaker&lt;/span&gt;&lt;/code&gt; implementation driver will be able to connect to this
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RoutingPeer&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Associate a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Router&lt;/span&gt;&lt;/code&gt; to a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BGPSpeaker&lt;/span&gt;&lt;/code&gt;. That means the router will
have dynamic routing capabilities that will let it advertise its routes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Associate a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Network&lt;/span&gt;&lt;/code&gt; to a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BGPSpeaker&lt;/span&gt;&lt;/code&gt;. All the routers with
external gateways attached to this network will use the same
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BGPSpeaker&lt;/span&gt;&lt;/code&gt; attributes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;At this point, Neutron will compare the address scope of the subnets to which
assigned routers (step 5 implies all the routers of the external network) have
their external gateways connected to the internal subnets of the tenants to see
if they belong to the same address scope.  If so, the BGP speaker
implementation will advertise these tenant subnets to its configured
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RoutingPeers&lt;/span&gt;&lt;/code&gt;.  Floating IPs will be included implicitly since they are
allocated from the external network.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="considerations"&gt;
&lt;h3&gt;Considerations&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Multi-homed clouds can be handled using classic networking infrastructure,
configuring manually the vendor router with BGP outside the OpenStack
deployment.  This is limited.  It can’t handle the routed floating ip model
proposed above.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;This document proposes modifying data objects and schema in the following way.
For a quick glance of the Data Object Model, check out this &lt;a class="reference external" href="https://etherpad.openstack.org/p/juno-dynamic-routing"&gt;etherpad&lt;/a&gt;.&lt;/p&gt;
&lt;section id="data-object-changes"&gt;
&lt;h4&gt;Data Object Changes&lt;/h4&gt;
&lt;p&gt;Three new data model classes will be added: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BGPSpeaker&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RoutingPeer&lt;/span&gt;&lt;/code&gt;
and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;AdvertiseRoute&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We will need the binding entities:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RoutingPeerBGPSpeakerBinding&lt;/span&gt;&lt;/code&gt; to associate peers to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BGPSpeaker&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RouterBGPSpeakerBinding&lt;/span&gt;&lt;/code&gt; to associate routers &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BGPSpeaker&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NetworkBGPSpeakerBinding&lt;/span&gt;&lt;/code&gt; to associate networks to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BGPSpeaker&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;New &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BGPSpeaker&lt;/span&gt;&lt;/code&gt; class will contain the following attributes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;id&lt;/span&gt;&lt;/code&gt;: UUID of the entity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;local_as&lt;/span&gt;&lt;/code&gt;: Local AS value.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Now we only need these values. In the future, more advanced configuration
options of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BGPSpeaker&lt;/span&gt;&lt;/code&gt; will be able to be added here.&lt;/p&gt;
&lt;p&gt;New &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RoutingPeer&lt;/span&gt;&lt;/code&gt; class that represents a peer connection will contain the
following attributes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;id&lt;/span&gt;&lt;/code&gt;: UUID of the entity&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ip&lt;/span&gt;&lt;/code&gt;: IP Address of the peer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;remote_as&lt;/span&gt;&lt;/code&gt;: Remote Peer’s AS value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;auth&lt;/span&gt;&lt;/code&gt;: Authentication data of the connection that can be serialized as a&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;dictionary. { &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;type&lt;/span&gt;&lt;/code&gt;: ‘MD5’, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;password&lt;/span&gt;&lt;/code&gt;: ‘234a23d10234’ } could be
a simple example and first approach.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Another data object called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;AdvertiseRoute&lt;/span&gt;&lt;/code&gt; will be created extending the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Route&lt;/span&gt;&lt;/code&gt; entity and associated to a router. Will have the following
attributes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;nexthop&lt;/span&gt;&lt;/code&gt;:  IP address of the next hop.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;destination&lt;/span&gt;&lt;/code&gt;: CIDR prefix.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;router_id&lt;/span&gt;&lt;/code&gt;: UUID of the Routing Instance.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RoutingPeerBGPSpeakerBinding&lt;/span&gt;&lt;/code&gt; is an n-to-n relationship between bgp peer
and bgp speaker and only will have:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;peer_id&lt;/span&gt;&lt;/code&gt;: UUID of the BGPPeer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;bgpspeaker_id&lt;/span&gt;&lt;/code&gt;: UUID of the Dynamic Routing Agent&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RouterBGPSpeakerBinding&lt;/span&gt;&lt;/code&gt; is an n-to-1 relationship with the attributes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;router_id&lt;/span&gt;&lt;/code&gt;: UUID of the Router&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;bgpspeaker_id&lt;/span&gt;&lt;/code&gt;: UUID of the Dynamic Routing Agent.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NetworkBGPSpeakerBinding&lt;/span&gt;&lt;/code&gt; is an n-to-1 relationship with the attributes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network_id&lt;/span&gt;&lt;/code&gt;: UUID of the Network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;bgpspeaker_id&lt;/span&gt;&lt;/code&gt;: UUID of the Dynamic Routing Agent.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RouterBGPSpeakerBinding&lt;/span&gt;&lt;/code&gt; it will be used when you want to propagate a single
router’s AdvertiseRoutes. This option is suitable for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Expose&lt;/span&gt; &lt;span class="pre"&gt;External&lt;/span&gt;
&lt;span class="pre"&gt;Networks&lt;/span&gt; &lt;span class="pre"&gt;Dynamically&lt;/span&gt;&lt;/code&gt; use case, explained above. It can be seen as adding
dynamic routing capabilities to a Router&lt;/p&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NetworkBGPSpeakerBinding&lt;/span&gt;&lt;/code&gt; is the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Routed&lt;/span&gt; &lt;span class="pre"&gt;Model&lt;/span&gt; &lt;span class="pre"&gt;for&lt;/span&gt; &lt;span class="pre"&gt;Floating&lt;/span&gt; &lt;span class="pre"&gt;IPs&lt;/span&gt; &lt;span class="pre"&gt;on&lt;/span&gt; &lt;span class="pre"&gt;External&lt;/span&gt;
&lt;span class="pre"&gt;Network&lt;/span&gt;&lt;/code&gt; use case: in this case you propagate tenant routes (IPv6) or Floating
IPs into an upstream router. These routes are more dynamic to assign, because it
is up to the tenant use to set them. You will want any router attached to a
network, to automatically be added to propagate its routes.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;API endpoints should be implemented according to the Solution Proposed section.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;This feature will allow an external system to manipulate routing information
within Neutron network. The external system should be trusted and may be
authenticated using a shared secret.&lt;/p&gt;
&lt;p&gt;Dynamic routing may only be configured by the system administrator.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;A notification should be provided when connectivity of control channel over
which routes are exchanged is interrupted&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;The following CLI commands will be added to manage dynamic routing specification for
connecting OpenStack to outside networks:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-speaker-list&lt;/strong&gt;: List configured bgpspeakers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-speaker-show&lt;/strong&gt;: Show detailed bgpspeaker configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-speaker-create&lt;/strong&gt; Create new bgpspeaker connection.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-speaker-update&lt;/strong&gt;: Update bgpspeaker specification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-speaker-delete&lt;/strong&gt;: Delete bgpspeaker specification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-speaker-peer-add&lt;/strong&gt;: Associate a peer to a bgpspeaker.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-speaker-peer-list&lt;/strong&gt;: List Peers on bgpspeaker&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-speaker-peer-remove&lt;/strong&gt;: Remove peers on bgpspeaker.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-speaker-network-add&lt;/strong&gt;: Associate a network to a bgpspeaker.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-speaker-network-list&lt;/strong&gt;: List networks on bgpspeaker&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-speaker-network-remove&lt;/strong&gt;: Remove networks on bgpspeaker.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-speaker-router-add&lt;/strong&gt;: Associate a peer to a bgpspeaker.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-speaker-router-list&lt;/strong&gt;: List routers on bgpspeaker&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-speaker-router-remove&lt;/strong&gt;: Remove router on bgpspeaker.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-peer-list&lt;/strong&gt;: List configured peers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-peer-show&lt;/strong&gt;: Show detailed peer configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-peer-create&lt;/strong&gt; Create new peer connection.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-peer-update&lt;/strong&gt;: Update peer specification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bgp-peer-delete&lt;/strong&gt;: Delete peer specification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;router-advertiseroutes-list&lt;/strong&gt;: List advertise routes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="horizon-requirements"&gt;
&lt;h4&gt;Horizon Requirements&lt;/h4&gt;
&lt;p&gt;A new screen will be added to configure gateway configuration for connecting
OpenStack to outside networks. This screen will allow routes and peer
configuration to be added to gateway configuration.&lt;/p&gt;
&lt;p&gt;An external network will have an option to be linked to a routing instance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="usage-example"&gt;
&lt;h4&gt;Usage Example&lt;/h4&gt;
&lt;p&gt;Configure 2 uplinks for the routing instance serving an external network to
advertise its routes and update the discovered ones.&lt;/p&gt;
&lt;p&gt;Sample configuration using Neutron CLI commands:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speaker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="mi"&gt;12345&lt;/span&gt;

&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="mf"&gt;123.23.43.4&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;remote&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1234&lt;/span&gt;

&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speaker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;peer1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;previous&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="n"&gt;created&lt;/span&gt; &lt;span class="n"&gt;peer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt;
&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;but&lt;/span&gt; &lt;span class="n"&gt;modified&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;sake&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;understanding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speaker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;bgpspeaker1&lt;/span&gt; &lt;span class="n"&gt;network1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;same&lt;/span&gt; &lt;span class="n"&gt;here&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;uuids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;This feature describes an out of band mechanism to negotiate routing
configuration. This feature should not have a performance impact on Neutron
network.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;This feature would have to explicitly enabled and configured before it will take
effect. There are no changes to configuration files.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;This change does not affect current developments or any plugin development.&lt;/p&gt;
&lt;p&gt;Neutron API exposed is agnostic of the exchange routing protocol used.  If
another developer want to provide other driver than BGP with exabgp, only the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dr_agent&lt;/span&gt;&lt;/code&gt; part will be affected with new code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change does not impact community.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="id1"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Taking into account the use case (BGP connectivity), we think that the agent
approach is the only one that fits into Neutron. Although maybe the
functionality would be solved using another entities and workflow.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;This is a pre-liminary contributor list&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tidwellr
vikram&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;devvesa
YAMAMOTO&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dr_agent&lt;/span&gt;&lt;/code&gt;, exposing the API and implemented with the chosen
BGP speaker. (&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/BGPSpeakersComparison"&gt;BGP Comparison&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Model tables and API resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Periodically scheduled process to communicate with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dr_agent&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Devstack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Depending on the implementation, new system library or python library will need
to be installed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Dynamic routing testing may be performed in an isolated environment. An external
autonomous system may be simulated with an instance of BGP capable software
router (for example, quagga).&lt;/p&gt;
&lt;p&gt;The following dynamic routing scenarios could be tested:&lt;/p&gt;
&lt;p&gt;Verify that when BGP is enabled on the gateway and one peer is configured the
agent establishes BGP session with the peer, receives a list of routes, and
submits advertised routes to the peer.&lt;/p&gt;
&lt;p&gt;Verify that when BGP is disabled on the gateway and one peer is configured the
dr_agent establishes no BGP sessions.&lt;/p&gt;
&lt;p&gt;Verify that when BGP is enabled on the agent and 3 BGP peer connections are
configured, the agent establishes 3 BGP sessions, one to each of the
configured peers.&lt;/p&gt;
&lt;p&gt;When 2 or more peers are configured, verify that BGP implementation is able to
detect when the BGP session is interrupted the routes received from that BGP
session are automatically removed from the routing table.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Full top-down Neutron API internal logic must be developed by mocking the agent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;All API exposed endpoints by Neutron extensions must be tested.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;New documentation for the whole functionality.&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;User documentation explaining the functionality must be provided.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Developer documentation about how to develop a new driver for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dr_agent&lt;/span&gt;&lt;/code&gt;
must be provided.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Previous work:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/115554/"&gt;Introducing entities&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/111311/"&gt;Add the dr_agent&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Links and helpers:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/DynamicRoutingUseCases"&gt;Neutron Dynamic Routing Use Cases&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/pluggable-ext-net"&gt;Pluggable External Net Blueprint&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Border_Gateway_Protocol"&gt;Border Gateway Protocol&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://www.nongnu.org/quagga/"&gt;Quagga&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://tools.ietf.org/html/rfc4364"&gt;BGP/MPLS IP Virtual Private Networks (VPNs)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/juno-dynamic-routing"&gt;etherpad&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Virtual_Routing_and_Forwarding"&gt;VRF&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/BGPSpeakersComparison"&gt;BGP Comparison&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://ryu.readthedocs.org/en/latest/library_bgp_speaker.html"&gt;Ryu’s BGP speaker&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-route-policy-support-for-dynamic-routing-protocol"&gt;policy support for dynamic routing&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1453921"&gt;Address Scopes&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 20 Nov 2024 00:00:00 </pubDate></item><item><title>Port Forwarding API</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/rocky/port-forwarding.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/port-forwarding"&gt;https://blueprints.launchpad.net/neutron/+spec/port-forwarding&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Port forwarding is a common feature in networking and more specifically in PaaS
and SaaS cloud systems which aim at reusing the same public IP for different
clients that use different VMs for their services.&lt;/p&gt;
&lt;p&gt;This is especially relevant for deployments which lack a large number of public
IPs they can assign.&lt;/p&gt;
&lt;p&gt;Common use case for this feature is a client requesting a specific service,
where the serving platform (PaaS, SaaS) allocates a VM to run the service and
then allocates a client port to access this service.
This means that various clients use the same public IP, but the TCP/UDP
destination port is used to distinguish between the end point VMs.&lt;/p&gt;
&lt;p&gt;Example, a mapping for web servers:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;client1  172.24.4.2:4001 TCP  =&amp;gt; maps to 10.0.0.2 port 80 TCP (VM1)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;client2  172.24.4.2:4002 TCP  =&amp;gt; maps to 10.0.0.3 port 80 TCP (VM2)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This spec will focus on port forwarding based on Floating IPs. A future spec
will be submitted for port forwarding based on routers external gateway
interface.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In environments constrained with limited IPs, operators would like
to reuse public IPs instead of assigning to each VM its own public
IP (Floating IP).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Docker supports a port-mapping feature and hence a big eco-system of
automation orchestration and management plugins leverage it.
We would like to make Neutron compatible for these tools and systems
and provide a similar API &lt;a class="footnote-reference brackets" href="#foot1" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Introduce port forwarding API and implementation to Floating IPs.&lt;/p&gt;
&lt;p&gt;The user can define various port forwarding rules on the Floating IPs
containing the internal/client port and the external/destination port,
connected with the VM they want to expose. And users would be allowed to create
port forwarding rules only on a “free” Floating IP, i.e. a Floating IP which is
not directly associated with a Fixed IP of a tenant’s VM.&lt;/p&gt;
&lt;p&gt;We will have four deployment variants:&lt;/p&gt;
&lt;p&gt;a) Legacy Router: For the generic Router deployment, the port forwarding rules
would be installed in the Router namespace on the network node and forwarding
functions would be performed.&lt;/p&gt;
&lt;p&gt;b) HA Router: For the HA Router deployment, the port forwarding rule will be
installed in both the ACTIVE and the BACKUP Router namespaces on the network
nodes they are located on.&lt;/p&gt;
&lt;p&gt;c) DVR: As &lt;a class="footnote-reference brackets" href="#foot2" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; has been merged, we now have the ability to create
centralized Floating IPs in a DVR supported deployment.
This helps in mapping the Compute nodes where the destination VM is present
with the centralized FIP for Port forwarding. This mechanism will centralize
a floating IP not only when it is associated with a port bound to a host with
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dvr_no_external&lt;/span&gt;&lt;/code&gt; option enabled, but also when port forwarding
attributes are added to it.&lt;/p&gt;
&lt;p&gt;d) DVR + HA: If the created router is not an HA router, then we can proceed
with option (c). While if the router is an HA router, then we will use the
centralized HA router to install the port forwarding rules.&lt;/p&gt;
&lt;p&gt;In all deployment variants, the port forwarding entry NATs a specific
Floating IP:Port and protocol to a specific Neutron port (and a private IP that
is attached to this port). That means it will maintain a mapping like
“FIP:extport protocol” to “Neutron Port Fixed IP:intport protocol”. So if a
Neutron Port contains multiple Fixed IPs, then it will be allowed to create
multiple port forwarding entries for a particular Neutron port, with different
external ports, such as:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;FIPX:EXTPORTX PROTOCOLA =&amp;gt; Neutron PortQ Fixed IPA:INTPORTA PROTOCOLA (VM1)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FIPX:EXTPORTY PROTOCOLA =&amp;gt; Neutron PortQ Fixed IPB:INTPORTA PROTOCOLA (VM1)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, the same Fixed IP:intport socket cannot be mapped with different
protocols.&lt;/p&gt;
&lt;p&gt;If the Neutron port is deleted, the port forwarding entries that match this
port are also deleted. Same is applicable in case the Floating IP is deleted.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;The following new table is added as part of the port forwarding feature:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;port_forwarding&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="n"&gt;CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt; &lt;span class="n"&gt;PRI&lt;/span&gt; &lt;span class="n"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;floating_ip_id&lt;/span&gt; &lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;external_port&lt;/span&gt; &lt;span class="n"&gt;INT&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;internal_neutron_port_id&lt;/span&gt; &lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt; &lt;span class="n"&gt;FOREIGN&lt;/span&gt; &lt;span class="n"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;protocol&lt;/span&gt; &lt;span class="n"&gt;CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;socket&lt;/span&gt; &lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="n"&gt;floating_ip_id_external_port_constraint&lt;/span&gt; &lt;span class="n"&gt;UNIQUE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;floating_ip_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;external_port&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="n"&gt;internal_neutron_port_id_socket_constraint&lt;/span&gt; &lt;span class="n"&gt;UNIQUE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;internal_neutron_port_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;socket&lt;/span&gt;&lt;/code&gt; column will store the string like ‘Fixed IP:Port’.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This table lacks &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt;, as the owner of this
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port_forwarding&lt;/span&gt;&lt;/code&gt; must be the owner of associated Floating IP. So
there is a project_id check for preventing association of
Floating IP to internal Neutron Port if their &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; are
different. Also, allow the association that Floating IP/internal
Neutron Port exists on a shared network for admin users in different
project_id cases, such as FloatingIP from a shared public network
created by a admin user and a Neutron Port from a particular
internal tenant network created by the tenant user, then admin user
want a association of them which have different project_ids. For
general users, there is only the same project_id case.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="sub-resource-extension"&gt;
&lt;h3&gt;Sub Resource Extension&lt;/h3&gt;
&lt;p&gt;Neutron &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;floatingips&lt;/span&gt;&lt;/code&gt; will be extended with a sub resource
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port_forwarding&lt;/span&gt;&lt;/code&gt;, it will contain some fields to expose the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port_forwarding&lt;/span&gt;&lt;/code&gt; assigned to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;floatingip&lt;/span&gt;&lt;/code&gt; resource.&lt;/p&gt;
&lt;p&gt;For this new feature, a new service plugin will be introduced, and the
following methods will be added:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;‘create_floatingip_port_forwarding()’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘delete_floatingip_port_forwarding()’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘get_floatingip_port_forwarding()’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘get_floatingip_port_forwardings()’&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For update operation, we will extend the function in the future if possible.
But for now, we will just support create/delete/get functions.&lt;/p&gt;
&lt;p&gt;So the attributes map of new sub resource would be like:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;SUB_RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'port_forwarding'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'parent'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'collection_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'floatingips'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'member_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'floatingip'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'parameters'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'external_port'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                     &lt;span class="n"&gt;convert_validate_port_value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'internal_port'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                     &lt;span class="n"&gt;convert_validate_port_value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'internal_ip_address'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                        &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                                        &lt;span class="s1"&gt;'type:ip_address_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'protocol'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                              &lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IPTABLES_PROTOCOL_MAP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()},&lt;/span&gt;
                           &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;converters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_protocol&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'internal_port_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                    &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                    &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:int'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                                    &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;The idea is to extend the Floating IP Rest API with a new extension
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;floating_ip_port_forwarding&lt;/span&gt;&lt;/code&gt; with the below defined attributes.&lt;/p&gt;
&lt;table class="docutils align-default" id="id4"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;Floating IP extension&lt;/span&gt;&lt;/caption&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Attribute Name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Default Value&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;port_forwardings&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;List&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The associated ‘port-forwarding’ sub resource with the particular
Floating IP resource.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The Floating IP extension definition would be expanded as :&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="s1"&gt;'floatingips'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s1"&gt;'port_forwardings'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This new field will be exposed in the response during GET/POST/PUT requests of
Floating IP resource. That means users can not change the forwarding resources
through CRU FloatingIP, only can create the forwardings one by one with the new
port forwarding API which will be introduced below.&lt;/p&gt;
&lt;p&gt;For example, GET a Floating IP:&lt;/p&gt;
&lt;p&gt;GET /v2.0/floatingips/&amp;lt;floatingip-uuid&amp;gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"floatingip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s2"&gt;"floating_network_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"376da547-b977-4cfe-9cba-275c80debf57"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"router_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"d23abc8d-2991-4a55-ba98-2aaea84cc72f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"fixed_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"floating_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"172.24.4.228"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"4969c491a3c74ee4af974e6d800c62de"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"4969c491a3c74ee4af974e6d800c62de"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"port_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2f245a7b-796b-4f26-9cf9-9e82d248fda7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"port_forwardings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
             &lt;span class="p"&gt;{&lt;/span&gt;
                 &lt;span class="s2"&gt;"internal_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s2"&gt;"internal_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s2"&gt;"external_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"7001"&lt;/span&gt;
             &lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="p"&gt;{&lt;/span&gt;
                 &lt;span class="s2"&gt;"internal_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"192.168.4.32"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s2"&gt;"internal_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s2"&gt;"external_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"7002"&lt;/span&gt;
             &lt;span class="p"&gt;}&lt;/span&gt;
         &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For the new sub resource ‘port_forwarding’, a new url will be introduced:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;/v2.0/floatingips/&amp;lt;floatingip-uuid&amp;gt;/port_forwardings&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="list-port-forwardings"&gt;
&lt;h4&gt;List Port Forwardings&lt;/h4&gt;
&lt;p&gt;GET /v2.0/floatingips/&amp;lt;floatingip-uuid&amp;gt;/port_forwardings&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"port_forwardings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ae34051f-aa6c-4c75-abf5-50dc9ac99ef3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"external_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"7003"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"internal_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"internal_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.10"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"internal_port_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"b930d7f6-ceb7-40a0-8b81-a425dd994ccf"&lt;/span&gt;
         &lt;span class="p"&gt;},&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"915a14a6-867b-4af7-83d1-70efceb146f9"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"external_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"7004"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"internal_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"internal_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"internal_port_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"0c56df5d-ace5-46c8-8f4c-45fa4e334d18"&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default" id="id5"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;Response Parameters&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Parameter&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Style&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;port_forwardings&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:list&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A list of &lt;em&gt;port_forwarding&lt;/em&gt; objects&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;More parameters see &lt;a class="reference internal" href="#show-port-forwarding"&gt;&lt;span class="std std-ref"&gt;Show Port Forwarding&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="show-port-forwarding"&gt;
&lt;span id="id3"/&gt;&lt;h4&gt;Show Port Forwarding&lt;/h4&gt;
&lt;p&gt;GET /v2.0/floatingips/&amp;lt;floatingip-uuid&amp;gt;/port_forwardings/&amp;lt;port-forwarding-id&amp;gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"port_forwarding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ae34051f-aa6c-4c75-abf5-50dc9ac99ef3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"external_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"7003"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"internal_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"internal_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.10"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"internal_port_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"b930d7f6-ceb7-40a0-8b81-a425dd994ccf"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default" id="id6"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;Response Parameters&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Parameter&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Style&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;port_forwarding&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:dict&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A &lt;em&gt;port_forwarding&lt;/em&gt; object&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The ID of  &lt;em&gt;port_forwarding&lt;/em&gt; object&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;external_port&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The exposed external protocol port number&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;internal_port&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The port forwarding mapped internal protocol port number&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;internal_ip_address&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The IP Address from the fixed ips of a particular port&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;protocol&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The traffic protocol type, such as TCP or UDP. Default value is ‘TCP’.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;internal_port_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;xsd:string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The Neutron internal Port ID.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="create-port-forwarding"&gt;
&lt;h4&gt;Create Port Forwarding&lt;/h4&gt;
&lt;p&gt;POST /v2.0/floatingips/&amp;lt;floatingip-uuid&amp;gt;/port_forwardings&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"port_forwarding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s2"&gt;"external_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"7233"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"internal_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"internal_port_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"b930d7f6-ceb7-40a0-8b81-a425dd994ccf"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response parameters&lt;/p&gt;
&lt;p&gt;see &lt;a class="reference internal" href="#show-port-forwarding"&gt;&lt;span class="std std-ref"&gt;Show Port Forwarding&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"port_forwarding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"f8a44de0-fc8e-45df-93c7-f79bf3b01c95"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"external_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"7233"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"internal_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"internal_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"192.168.43.33"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"internal_port_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"b930d7f6-ceb7-40a0-8b81-a425dd994ccf"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="delete-port-forwarding"&gt;
&lt;h4&gt;Delete Port Forwarding&lt;/h4&gt;
&lt;p&gt;DELETE /v2.0/floatingips/&amp;lt;floatingip-uuid&amp;gt;/port_forwardings/&amp;lt;port-forwarding-id&amp;gt;&lt;/p&gt;
&lt;p&gt;This operation does not accept a request body and does not return a response
body.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="effects-on-existing-floating-ip-apis"&gt;
&lt;h3&gt;Effects on Existing Floating IP APIs&lt;/h3&gt;
&lt;p&gt;Slight adjustment to existing Floating IP APIs:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create a Floating IP just the same with current behavior.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Associate a Neutron internal port with a Floating IP, if the requested url
is the same as previous, the Floating IP will work as 1:1 DNAT like current
behavior. If the request with the new url, that means the request needs a
port-forwarding function towards the Floating IP.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get a Floating IP resource will be the same as before if the Floating IP
resource had already associated with a neutron port for 1:1 DNAT. If a
Floating IP resource contains more than 1 port-forwarding sub resource, it is
better to show the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port-forwardings&lt;/span&gt;&lt;/code&gt; summary in the Floating IP response
body to distinguish which Floating IP resource is available for different
requirements, such as 1:1 DNAT, port-forwarding.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="command-line-client-impact"&gt;
&lt;h3&gt;Command Line Client Impact&lt;/h3&gt;
&lt;p&gt;Openstack Client would have additional options &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;portforwarding&lt;/span&gt;&lt;/code&gt; for
Floating IP CLI, which would define the port-forwarding characteristics.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;Port forwarding is similar in nature to centralized DNAT, so should not pose
additional security implications. But if users actually want to use Port
forwarding, they must make sure to allow the associated ingress Security Group
towards the internal ip which is used by the neutron port of their VMs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;Depends on the implementation spec&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Performance testing must be conducted to see what is the overhead
of enabling this feature, of course that if the feature is
disabled no performance impact should be noticed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;IPv6 is not supported&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Deployer will be able to leverage port forwarding for a unique way to reach a
private VM/Container without wasting new public IPs&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Future SNAT distribution plans should take port forwarding into consideration.
Kuryr can leverage port forwarding for feature compatibility with Docker port
mapping.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Users can use an external VM that provide this NAT capability or assign a new
Floating IP for each VM.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl&gt;
&lt;dt&gt;Primary assignees:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;reedip &amp;lt;&lt;a class="reference external" href="mailto:reedip.banerjee%40nectechnologies.in"&gt;reedip&lt;span&gt;.&lt;/span&gt;banerjee&lt;span&gt;@&lt;/span&gt;nectechnologies&lt;span&gt;.&lt;/span&gt;in&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;gal-sagie &amp;lt;&lt;a class="reference external" href="mailto:gal.sagie%40gmail.com"&gt;gal&lt;span&gt;.&lt;/span&gt;sagie&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;p&gt;tian-mingming &amp;lt;&lt;a class="reference external" href="mailto:tian.mingming%40h3c.com"&gt;tian&lt;span&gt;.&lt;/span&gt;mingming&lt;span&gt;@&lt;/span&gt;h3c&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;p&gt;zhaobo &amp;lt;&lt;a class="reference external" href="mailto:zhaobo6%40huawei.com"&gt;zhaobo6&lt;span&gt;@&lt;/span&gt;huawei&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;API Implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB Implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reference implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Need to add tempest tests&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Need to add functional tests&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Need to add API tests&lt;/p&gt;
&lt;/section&gt;
&lt;section id="fullstack-tests"&gt;
&lt;h3&gt;Fullstack Tests&lt;/h3&gt;
&lt;p&gt;Need to add Fullstack tests.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Needs user documentation&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Needs devref documentation&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="foot1" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.docker.com/engine/userguide/networking/default_network/binding/"&gt;https://docs.docker.com/engine/userguide/networking/default_network/binding/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="foot2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/485333/20"&gt;https://review.openstack.org/#/c/485333/20&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Wed, 20 Nov 2024 00:00:00 </pubDate></item><item><title>Neutron-Neutron Interconnections</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stein/neutron-interconnection.html</link><description>

&lt;p&gt;Launchpad RFE: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1750368"&gt;https://bugs.launchpad.net/neutron/+bug/1750368&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Today, to realize connectivity between two OpenStack clouds or more (e.g.
between distinct OpenStack deployments, or between OpenStack regions,
for instance) some options are available, such as floating IPs, VPNaaS
(IPSec-based), and BGPVPNs.&lt;/p&gt;
&lt;p&gt;However, none of these options are appropriate to address use cases where all
the following properties are desired:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;interconnection consumable on-demand, without admin intervention &lt;a class="footnote-reference brackets" href="#f1" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;have network isolation and allow the use of private IP addressing
end-to-end &lt;a class="footnote-reference brackets" href="#f2" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;avoid the overhead of packet encryption &lt;a class="footnote-reference brackets" href="#f3" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;An additional design requirement to the solution is to avoid introducing a
component that would require having admin rights on all the OpenStack
clouds involved.&lt;/p&gt;
&lt;p&gt;The goal of this spec is a solution to provide network connectivity
between two or more OpenStack deployments or regions, respecting these
requirements.&lt;/p&gt;
&lt;section id="use-cases"&gt;
&lt;h3&gt;Use cases&lt;/h3&gt;
&lt;section id="example-1"&gt;
&lt;h4&gt;Example 1&lt;/h4&gt;
&lt;p&gt;User Foo has credentials for OpenStack cloud A and OpenStack cloud B, one
Router X in OpenStack A, one Router Y in OpenStack B, both using a distinct
subnet in the private IPv4 address space.&lt;/p&gt;
&lt;p&gt;User Foo would like to consume via an API a service that will result in
establishing IP connectivity between Router A and Router B.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="example-2"&gt;
&lt;h4&gt;Example 2&lt;/h4&gt;
&lt;p&gt;Same as example 1, but this time L2 connectivity is desired between Network X
in OpenStack A, and Network Y in OpenStack B.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="example-3"&gt;
&lt;h4&gt;Example 3&lt;/h4&gt;
&lt;p&gt;Same as example 1 or 2, but with 3 OpenStack deployments involved.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="overview"&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
&lt;p&gt;The proposition consists in introducing a service plugin and a corresponding
API extension involving a new ‘interconnection’ resource. The ‘interconnection’
resource on a Neutron instance will refer to both a local resource (e.g.
Router A) and a remote resource (OpenStack B:Router B), and will have the
semantic that connectivity is desired between the two.&lt;/p&gt;
&lt;p&gt;This resource will be part of two sorts of API calls:&lt;/p&gt;
&lt;ol class="upperalpha simple"&gt;
&lt;li&gt;&lt;p&gt;calls between the user having the connectivity need and each Neutron
instance involved; the role of these calls is to let the need for
connectivity be known by all Neutron instances&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API calls between a Neutron instance and another Neutron instance; the role
of these calls is to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;let each Neutron instance validate the consistency between the
“interconnection” resources defined locally and the “interconnection”
resources made in other Neutron instances&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;after this validation, let two Neutron instances identify the mechanism
to use and the per-interconnection parameters (depending on the
mechanism; could be a pair of VLANs on a interconnection box, a BGPVPN
RT identifiers, VXLAN ids, etc.)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                               .-------------.
                               | tenant user |
                               '----+---+----'
                                    |   |
   .--------------------------------'   '--------------------.
   | A1. create "interconnection"                            |
   |     between local net X,                                |
   |     and "Neutron B: net Y"                              |
   |                                          A2. create "interconnection"
   |                                              between local net Y,
   |                                              and "Neutron A: net X"
   |                                                         |
   |                                                         |
   |                                                         |
   |                                                         |
   V                         B1. check symmetric inter.      V
.-------------------------.                      (fail) .--------------------.
|                         +---------------------------&amp;gt; |                    |
|   Neutron A             |                             |   Neutron B        |
|                         | &amp;lt;---------------------------+                    |
|                         |  B2. check symmetric inter. |                    |
|                         |                       (ok!) |                    |
|                         |                             |                    |
|                         +---------------------------&amp;gt; |                    |
|                         | &amp;lt;---------------------------+                    |
'-------------------------'  B3. exchange info to build '--------------------'
                   net X        interconnection           net Y
                     |                                      |
                     |                                      |
                   --+                                      +--
                     |      C. interconnection is built     |
                     +--    - - - - - - - - - - - - - -   --+
                     |                                      |
                     |                                      |
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that the order between A1/A2/B1/B2 can vary, but the result is
unchanged: at least one of the two Neutron instances will eventually confirm
that the interconnection has been defined on both side symmetrically, and the
interconnection setup phase will ultimately proceed on both sides (see
&lt;a class="reference internal" href="#details"&gt;&lt;span class="std std-ref"&gt;Details on operations&lt;/span&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;When more than two OpenStack deployments, or more than two OpenStack regions,
are involved, these API calls will happen for each pair of region/deployments.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="base-assumptions-trust-model"&gt;
&lt;h3&gt;Base assumptions, trust model&lt;/h3&gt;
&lt;p&gt;The base assumption underlying the trust model in this proposal is that the end
user requesting connectivity delegates trust to each OpenStack deployment to
provide only the interconnection requested, i.e. to not create connectivity
between resources unless requested.&lt;/p&gt;
&lt;p&gt;To respect this contract each OpenStack deployment needs, by definition, a
trust relationship with the other(s) OpenStack deployment(s) involved in these
interconnections; practically speaking it cannot do better, when receiving
a packet from another deployment, identified as intended for own of its local
network A (VLAN, VXLAN ID, MPLS label, etc.) to trust that this identifier was
pushed by the OpenStack deployment by mechanisms ultimately respecting the
contract of these specifications.&lt;/p&gt;
&lt;p&gt;Another aspect, obvious but better made explicit, is that the choice and
definition of the network identifiers that will be used for an interconnection
and to keep interconnections isolated from one another, are not controlled
by consumers of this API. In this proposal these consumers do not and cannot
write, or even read, these identifiers.&lt;/p&gt;
&lt;p&gt;Note that only the API calls to the ‘interconnection’ resources at steps A1/A2
require write access to the “interconnection” resources by tenant users (but
not to the attributes related to the network mechanism to use).&lt;/p&gt;
&lt;p&gt;The calls at steps B1/B2/B3, only require read-only access to these resources;
this can be achieved by introducing an “interconnection” role with read-only
access to all “interconnection” resources, and having each OpenStack deployment
having credentials for a user with this role in other OpenStack deployments.&lt;/p&gt;
&lt;p&gt;With the above in mind, Keystone federation is not required for the calls at
steps A1/A2, nor for the calls at step B1/B2. However, using Keystone
Federation for the user(s) used at step B1/B2 will certainly be useful and
will avoid requiring the management in each Neutron instance of the
credentials to use to each other OpenStack.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="interconnection-mechanisms"&gt;
&lt;h3&gt;Interconnection mechanisms&lt;/h3&gt;
&lt;p&gt;Although these specifications try to be agnostic to the network technique
ultimately used to realize an interconnection, the assumption is made that
for each ‘interconnection’, there is a technique common to the two OpenStack
deployments involved.&lt;/p&gt;
&lt;p&gt;The approach proposed is a simple approach where each OpenStack deployment
determines based on a configuration file, which technique to use when
establishing an interconnection with a given OpenStack deployment.&lt;/p&gt;
&lt;p&gt;Note that only the parameters that do not differ between two interconnection
would sit in a configuration file. The API exchange between two Neutron
instances is used to exchange parameters that are specific to each
interconnection.&lt;/p&gt;
&lt;section id="example-interconnection-techniques"&gt;
&lt;h4&gt;Example interconnection techniques&lt;/h4&gt;
&lt;p&gt;The following techniques can be considered for realizing interconnections:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;BGP-based VPNs: already supported via the Neutron BGPVPN Interconnection
service (see &lt;a class="reference external" href="https://docs.openstack.org/networking-bgpvpn"&gt;networking-bgpvpn&lt;/a&gt;), it allows to create L2 (with EVPN) or L3
connectivity (with BGP/MPLS IP VPNs)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VXLAN stitching with &lt;a class="reference external" href="https://docs.openstack.org/networking-l2gw"&gt;networking-l2gw&lt;/a&gt; (details remain to be investigated)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VLAN stitching (details remain to be investigated)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is expected that the first implementation will provide at least support
for the BGPVPN interconnection technique, which is already supported across
an interesting range of Neutron backends (Neutron reference drivers,
OpenDaylight, OpenContrail, Nuage Networks), and hence would allow this API
extension to be implemented on day one with a support for all these controllers
without any further per-controller driver development.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="details-on-operations"&gt;
&lt;span id="details"/&gt;&lt;h3&gt;Details on operations&lt;/h3&gt;
&lt;p&gt;When an “interconnection” resource is created, the Neutron instance will check
that the symmetric interconnection exists on the remote Neutron instance
designated in the interconnection, and will not proceed further until this
becomes true.&lt;/p&gt;
&lt;p&gt;This check is what establishes the end-to-end trust, that on both sides the
connectivity has been requested.&lt;/p&gt;
&lt;p&gt;Once a Neutron instance determines that an interconnection is symmetrically
defined, further exchanges happen to determine the network parameters to use
to realize the interconnection:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;the Neutron (e.g. Neutron B) that just confirmed the symmetricity allocates
the required network identifiers, and asks the remote Neutron instance (A)
to refresh its state&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron A refreshes its state: checks symmetricity again (which now succeeds)
retrieves at the same time the network identifiers allocated by B,
and asks Neutron B to refresh&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron B refreshes again, this time retrieves at the same time the
network identifiers allocated by A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the above, “ask the remote Neutron instance to refresh its state” is
done with a PUT on a specific &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;refresh&lt;/span&gt;&lt;/code&gt; action on the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;interconnection&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="interconnection-lifecycle"&gt;
&lt;span id="lifecycle"/&gt;&lt;h3&gt;Interconnection lifecycle&lt;/h3&gt;
&lt;p&gt;In the previous section, it is implicit that an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;interconnection&lt;/span&gt;&lt;/code&gt; is along
its life in different states before it is ultimately realized.  When an
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;interconnection&lt;/span&gt;&lt;/code&gt; resource is deleted on one side, the other side need also
to ultimately be able to update its own state (if only for cleanup purpose
or giving proper feedback to end users).&lt;/p&gt;
&lt;p&gt;Additionally, the interaction between a Neutron instance with another Neutron
instance needs to happen out of the API call processing path, because it is not
desirable that the success of a local API call would depend on the success of
an operation with an external component which possibly would not be available
at the moment.&lt;/p&gt;
&lt;p&gt;For all these reasons, a state machine will be introduced to handle the
lifecycle of an interconnection resource, with triggered and periodic operation
being done out-of-band of the API calls, to handle the operations for each
state.&lt;/p&gt;
&lt;p&gt;Exposing this state in the API will allow:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;end users to have feedback on how close they are to having something working&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;each Neutron instance to possibly identify that the remote state
is inconsistent with the local state&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;State machine summary:&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;TO_VALIDATE&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;interconnection resource has been created, but the existence of the
symmetric interconnection hasn’t been validated yet&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;VALIDATED&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;the existence of the symmetric interconnection has been validated and local
interconnection parameters have been allocated (remote parameters are
still unknown)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;ACTIVE&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;both local parameters and remote parameters are known, interconnection has
been setup, it should work&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;TEARDOWN&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;local action taken to delete this interconnection, action
is being taken to have the remote state get in sync&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;(DELETED)&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;implicit state corresponding to the resource not existing anymore&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;img alt="../../_images/state-machine-summary.png" src="../../_images/state-machine-summary.png"/&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;The proposal is to introduce an API extension &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;interconnection&lt;/span&gt;&lt;/code&gt;, exposing a
new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;interconnection&lt;/span&gt;&lt;/code&gt; resource.&lt;/p&gt;
&lt;section id="interconnection-resource"&gt;
&lt;h4&gt;Interconnection resource&lt;/h4&gt;
&lt;p&gt;The new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;interconnection&lt;/span&gt;&lt;/code&gt; API resource will be introduced under the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;interconnection&lt;/span&gt;&lt;/code&gt; API prefix, and having the following attributes:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Comment&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;enum&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;router&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network_l2&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network_l3&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;state&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;enum&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO
will be updated
by Neutron
along the life
of the resource&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;see states in &lt;a class="reference internal" href="#lifecycle"&gt;&lt;span class="std std-ref"&gt;Interconnection lifecycle&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;local_resource_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;router or network UUID&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;remote_resource_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;router or network UUID&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;remote_keystone&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;AUTH_URL of remote
keystone&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;remote_region&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;region in remote keystone&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;remote_interconnection_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td rowspan="3"&gt;&lt;p&gt;RO&lt;/p&gt;
&lt;p&gt;will be updated
by Neutron
along the life
of the resource&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid of remote interconnection&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;local_parameters&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dict&lt;/p&gt;&lt;/td&gt;
&lt;td rowspan="2"/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;remote_parameters&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dict&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This resource will be used with typical CRUD operations:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/interconnection/interconnections&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/interconnection/interconnections&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/interconnection/interconnections/&amp;lt;uuid&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/interconnection/interconnections/&amp;lt;uuid&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DELETE&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/interconnection/interconnections/&amp;lt;uuid&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additionally, an additional REST operation is introduced to trigger a
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;refresh&lt;/span&gt;&lt;/code&gt; action on an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;interconnection&lt;/span&gt;&lt;/code&gt; resource:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/interconnection/interconnections/&amp;lt;uuid&amp;gt;/refresh&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When this action is triggered the neutron instance on which the call is made
will try to retrieve (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt;&lt;/code&gt;) an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;interconnection&lt;/span&gt;&lt;/code&gt; resource on the remote
neutron instance having same &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;type&lt;/span&gt;&lt;/code&gt; as the local resource,
as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;local_resource_id&lt;/span&gt;&lt;/code&gt; the local resource &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;remote_resource_id&lt;/span&gt;&lt;/code&gt;, and
as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;remote_resource_id&lt;/span&gt;&lt;/code&gt; the local resource &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;local_resource_id&lt;/span&gt;&lt;/code&gt;.  Depending
on the current local state, and depending on success or failure to find such
a resource, the local state machine will transition.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="example"&gt;
&lt;h4&gt;Example&lt;/h4&gt;
&lt;p&gt;This shows an example of API exchanges for a Neutron-Neutron interconnection
between two Networks.&lt;/p&gt;
&lt;p&gt;API Call A1, from tenant user to Neutron A:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;interconnection&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;interconnections&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'interconnection'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'network_l3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s1"&gt;'local_resource_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s1"&gt;'remote_keystone'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'http//&amp;lt;keystone-B&amp;gt;/identity'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s1"&gt;'remote_region'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'RegionOne'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s1"&gt;'remote_resource_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;}}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'interconnection'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="o"&gt;...&lt;/span&gt;
 &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;API Call B1, from Neutron A to Neutron B:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET /v2.0/interconnection/interconnections?local_resource_id=&amp;lt;uuid of network Y&amp;gt;&amp;amp;remote_resource_id=&amp;lt;uuid of network X&amp;gt;

Response: 404 Not Found
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;API Call A2, from tenant user to Neutron B:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;interconnection&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;interconnections&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'interconnection'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'network_l3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s1"&gt;'local_resource_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s1"&gt;'remote_keystone'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'http//&amp;lt;keystone-A&amp;gt;/identity'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s1"&gt;'remote_region'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'RegionOne'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s1"&gt;'remote_resource_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;}}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'interconnection'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="o"&gt;...&lt;/span&gt;
 &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;API Call B2, from Neutron B to Neutron A:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;interconnection&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;interconnections&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local_resource_id&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;remote_resource_id&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'interconnection'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="s1"&gt;'local_parameters'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
 &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;API Call B3’ from Neutron B to Neutron A:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;interconnection&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;interconnections&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;refresh&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;API Call B3’’, from Neutron A to Neutron B&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;interconnection&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;interconnections&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local_resource_id&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;remote_resource_id&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'interconnection'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="s1"&gt;'local_parameters'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s1"&gt;'foo'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'42'&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;API Call B3’’’, from Neutron A to Neutron B&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;interconnection&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;interconnections&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;refresh&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;API Call B3’’’’, from Neutron B to Neutron A&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;interconnection&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;interconnections&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'interconnection'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="s1"&gt;'remote_interconnection_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="s1"&gt;'remote_parameters'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s1"&gt;'foo'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'42'&lt;/span&gt;
     &lt;span class="p"&gt;},&lt;/span&gt;
     &lt;span class="s1"&gt;'local_parameters'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s1"&gt;'bar'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'43'&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="command-line-client-impact"&gt;
&lt;h3&gt;Command Line Client Impact&lt;/h3&gt;
&lt;p&gt;python-neutronclient will be updated to introduce an OSC extension to
create/remove/update/delete &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;interconnection&lt;/span&gt;&lt;/code&gt; resources.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="client-libraries-impact"&gt;
&lt;h3&gt;Client Libraries Impact&lt;/h3&gt;
&lt;p&gt;python-neutronclient and openstacksdk will need to be updated to support
create/remove/update/delete operations on &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;interconnection&lt;/span&gt;&lt;/code&gt; resources.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="credits"&gt;
&lt;h3&gt;Credits&lt;/h3&gt;
&lt;p&gt;Przemyslaw Jasek contributed to exploring ideas that lead to this proposal
during a six-months internship at Orange.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;OpenStack Summit Sydney, lightning talk
&lt;a class="reference external" href="https://www.openstack.org/videos/sydney-2017/neutron-neutron-interconnections"&gt;https://www.openstack.org/videos/sydney-2017/neutron-neutron-interconnections&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="f1" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;possible with floating IPs, VPNaaS, but not with the BGP VPN
interconnections API extension (using a BGPVPN does not require admin
right, but creating a new BGPVPN does require admin rights)&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="f2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;possible with VPNaaS, and BGP VPN interconnections, but not with
floating IPs&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="f3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;possible with floating IPs and BGP VPN interconnections, but by
definition not with VPNaaS&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Wed, 20 Nov 2024 00:00:00 </pubDate></item><item><title>Introduce distributed locks to ipam module</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/train/introduce-distributed-locks-to-ipam.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/introduce-distributed-locks-to-ipam"&gt;https://blueprints.launchpad.net/neutron/+spec/introduce-distributed-locks-to-ipam&lt;/a&gt;
RFE:https://bugs.launchpad.net/neutron/+bug/1836834&lt;/p&gt;
&lt;p&gt;Introduce the OpenStack tooz distributed lock to the ipam module. In the scenario
of large-scale port creation, avoid ip allocation exceeding the maximum retry
limit failure and improve ip allocation efficiency.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Current port creation has a probability of failure.&lt;/p&gt;
&lt;p&gt;When the virtual machines are created in batches, nova will call the neutron
API to create the ports concurrently. Port creation will fail if there is an
ip allocation conflict, see &lt;a class="footnote-reference brackets" href="#id3" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And bulk create port has the similiar problem, when multiple “create_port_bulk”
APIs are called simultaneously on the same subnet, although this scenario is
used less frequently.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When creating ports concurrently, the utilization ratio of neutron
server CPU increases and the allocation efficiency decreases.&lt;/p&gt;
&lt;p&gt;When an ip allocation conflict fails to submit a database, a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DB&lt;/span&gt; &lt;span class="pre"&gt;ERROR&lt;/span&gt;&lt;/code&gt;
exception is thrown. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Create_port&lt;/span&gt;&lt;/code&gt; will catch the above exception and rest
after &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;retry_interval=0.1&lt;/span&gt;&lt;/code&gt; and re-call &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create_port&lt;/span&gt;&lt;/code&gt; until it exceeds
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;max_retries=10&lt;/span&gt;&lt;/code&gt;. When it exceeds &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;max_retries=10&lt;/span&gt;&lt;/code&gt; times, “Create_port”
will fail. When concurrency is large and conflict intensifies, repeated call
to create_port increases CPU’s burden and reduces allocation efficiency.
Adjusting &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;retry_interval&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;max_retries&lt;/span&gt;&lt;/code&gt; can only reduce the
probability of problems, but can not solve them thoroughly.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This solution implements a new ipam driver by introducing a distributed lock
to completely solve the problem of ip address allocation conflict leading
to failure.&lt;/p&gt;
&lt;p&gt;For distributed locks we will use OpenStack tooz &lt;a class="footnote-reference brackets" href="#id4" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; , which supports many
backend drivers, such as Zookeeper, Memcached, Redis, Mysql, etc., and it is
an OpenStack native project. We will support the configuration of tooz backend
drivers in neutron.conf, such as adding [tooz] configuration items.&lt;/p&gt;
&lt;p&gt;The new IPAM allocate ip seqdiag.&lt;/p&gt;
&lt;img alt="../../_images/ipam-allocate.png" src="../../_images/ipam-allocate.png"/&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;We can modify the current ipam driver to introduce distributed locks to solve
the above mentioned problems when creating a new ipam driver is not feasible.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Operator can configure the backend driver for tooz using the [tooz] configuration
block in neutron.conf.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;[tooz]
# Tooz backend connection string.
backend_url = file://$state_path

# Number of seconds between heartbeats for distributed coordination.
heartbeat = 1.0

# Number of seconds to wait after failed reconnection to Tooz backend.
initial_reconnect_backoff = 0.1

# Maximum number of seconds between sequential reconnection retries to Tooz backend.
max_reconnect_backoff = 60.0
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operator can switch to our new ipam driver by setting “ipam_driver” in neutron.conf.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# Neutron IPAM (IP address management) driver to use. By default, the reference&lt;/span&gt;
&lt;span class="c1"&gt;# implementation of the Neutron IPAM driver is used. (string value)&lt;/span&gt;
&lt;span class="n"&gt;ipam_driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ipam_with_dlm&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;When using rally to test concurrently to create vms or ports or the similar scenes.&lt;/p&gt;
&lt;p&gt;The good aspects:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Solve the failure of creating vms or ports due to ip allocation conflicts, and
improve the success rate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reduced average time to create vms or ports.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create vms or ports with a smoother distribution of time.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Minor impact:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The minimum time to create vms or ports has increased slightly, and creating a
port time in a non-concurrent scenario will also increase slightly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;qinhaizhong&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;zhouhenglc&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create a new ipam driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support for parsing [tooz] backend drivers, encapsulating distributed lock modules,
and implementing distributed lock initialization, locking, unlocking, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make “create_port” to support the new ipam driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make “bulk_create_port” to support the new ipam driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation work.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests, functional tests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1777968"&gt;https://bugs.launchpad.net/neutron/+bug/1777968&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/python-tooz"&gt;https://launchpad.net/python-tooz&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Wed, 20 Nov 2024 00:00:00 </pubDate></item><item><title>ML2/OVN - Coexistence Support for OVN externally managed resources</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2024.1/ml2ovn-coexistence-support-ovn-ext-resources.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/2027742"&gt;https://bugs.launchpad.net/neutron/+bug/2027742&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently two individual Neutron deployments using ML2/OVN are separate and may
only communicate using normal provider networks. However OVN supports the
feature &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;OVN&lt;/span&gt; &lt;span class="pre"&gt;interconnect&lt;/span&gt;&lt;/code&gt; (OVN-IC), that allows multiple separate OVN
deployments to be connected together. The interconnection is implemented using
a normal overlay (just like the one between compute nodes) and can therefore be
created easily in a large scale (something that is not necessarily the case for
provider networks).&lt;/p&gt;
&lt;p&gt;Nowadays the Neutron OVN db sync command is actively interfering with
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;OVN&lt;/span&gt; &lt;span class="pre"&gt;interconnect&lt;/span&gt;&lt;/code&gt; by removing non-Neutron resources from the Northbound
database. The goal of this spec is to remove this interference and allow
operators to use OVN interconnect and other features externally managed by OVN.
It is out of the scope of this spec to integrate OVN interconnect directly to
Neutron (however this might be part of a future spec).&lt;/p&gt;
&lt;section id="background-ovn-interconnect-use-case"&gt;
&lt;h2&gt;Background: OVN Interconnect use case&lt;/h2&gt;
&lt;p&gt;The OVN Interconnect allows multiple clusters to be interconnected at Layer 3
level. This can be useful for deployments with multiple Availability
Zones (AZs) that needs to allow connectivity between workloads in separate
zones.&lt;/p&gt;
&lt;p&gt;In the case of layer 3 interconnection, the logical routers on each cluster /
availability zone can be connected via transit overlay networks. The transit
network is an abstract representation of the interconnect layer, and the
element responsible for this intercluster visibility is the Transit Switch (TS)
. These interconnection switches are created in a global database and
replicated to each AZ via OVN-IC daemon. So, basically, a logical router in one
AZ is connected to a Logical router in another AZ via Transit switch. More
details can be found in the ovn-architecture manpage &lt;a class="footnote-reference brackets" href="#id3" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The reference design using two separated OVN clusters (north and south) is
described below:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+---------------------------------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;OVN&lt;/span&gt; &lt;span class="n"&gt;north&lt;/span&gt; &lt;span class="n"&gt;cluster&lt;/span&gt;                                                    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;+------------------------------------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;OVN&lt;/span&gt; &lt;span class="n"&gt;central&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+---------------+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+-------------+&lt;/span&gt;        &lt;span class="o"&gt;+-------------+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ovsdb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ovsdb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ovn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;+---------+&lt;/span&gt;&lt;span class="n"&gt;southbound&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;northbound&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+---------------+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+---------------+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;compute&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ovn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;+---------+&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+---------------+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+------+------+&lt;/span&gt;        &lt;span class="o"&gt;+-------+-----+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;+---+---------------+---+&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+----------+-----+&lt;/span&gt;   &lt;span class="o"&gt;+-----+---------+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ovn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ic&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ovn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;northd&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+-------+--------+&lt;/span&gt;   &lt;span class="o"&gt;+---------------+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;                               &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;+----------|-------------------------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                   &lt;span class="o"&gt;|&lt;/span&gt;                                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------------------|---------------------------------+&lt;/span&gt;
                                    &lt;span class="o"&gt;|&lt;/span&gt;
            &lt;span class="o"&gt;+-----------------------+---------------------+&lt;/span&gt;
            &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Global&lt;/span&gt; &lt;span class="n"&gt;DB&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Transit&lt;/span&gt; &lt;span class="n"&gt;switches&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
            &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ovsdb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;northbound&lt;/span&gt; &lt;span class="n"&gt;IC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;southbound&lt;/span&gt; &lt;span class="n"&gt;IC&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
            &lt;span class="o"&gt;|&lt;/span&gt;                                             &lt;span class="o"&gt;|&lt;/span&gt;
            &lt;span class="o"&gt;+-----------------------+---------------------+&lt;/span&gt;
                                    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------------------|---------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;OVN&lt;/span&gt; &lt;span class="n"&gt;south&lt;/span&gt; &lt;span class="n"&gt;cluster&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;                                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;+----------|-------------------------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;                               &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+-------+--------+&lt;/span&gt;   &lt;span class="o"&gt;+---------------+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ovn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ic&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ovn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;northd&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+----------+-----|&lt;/span&gt;   &lt;span class="o"&gt;+-----+---------+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;+---+---------------+---+&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+---------------+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+------+------+&lt;/span&gt;        &lt;span class="o"&gt;+-------+-----+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;nodeer&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ovsdb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ovsdb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ovn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;+---------+&lt;/span&gt;&lt;span class="n"&gt;southbound&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;northbound&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+---------------+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+---------------+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;compute&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ovn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;+---------+&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+---------------+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+-------------+&lt;/span&gt;        &lt;span class="o"&gt;+-------------+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;OVN&lt;/span&gt; &lt;span class="n"&gt;central&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="o"&gt;+------------------------------------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+---------------------------------------------------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The following example will outline how OVN Interconnect works within the scope
of OVN. It therefore follows the naming of OVN and not that of Neutron (should
the two disagree).&lt;/p&gt;
&lt;p&gt;Example setup:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+-------------------------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="n"&gt;Logical_Switch&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="n"&gt;ts1&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------+----------------------------------+---------------+&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;+-------+-----------+&lt;/span&gt;              &lt;span class="o"&gt;+-------+-----------+&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Logical_Switch_Port&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Logical_Switch_Port&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;lsp_ts1_lr1&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;lsp_ts1_lr2&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;+-------+-----------+&lt;/span&gt;              &lt;span class="o"&gt;+-------+-----------+&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;             &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Logical_Router_Port&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Logical_Router_Port&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;lrp_lr1_ts1&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;lrp_lr2_ts1&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mf"&gt;172.24.0.10&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mf"&gt;172.24.0.20&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;             &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;             &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Logical_Router&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Logical_Router&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;lr1&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;lr2&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;             &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;             &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Logical_Router_Port&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Logical_Router_Port&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;lrp_lr1_ls1&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;lrp_lr2_ls2&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mf"&gt;192.168.0.1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mf"&gt;192.168.1.1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;             &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;             &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Logical_Switch_Port&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Logical_Switch_Port&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;lsp_ls1_lr1&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;lsp_ls2_lr2&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;             &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;             &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Logical_Switch&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Logical_Switch&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ls1&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ls2&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;             &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;             &lt;span class="o"&gt;+-------+------------+&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Logical_Switch_Port&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Logical_Switch_Port&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;lsp_ls1_vm1&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;lsp_ls2_vm2&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;+--------------------+&lt;/span&gt;             &lt;span class="o"&gt;+--------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The example above is a logical representation of the elements involved in the
interconnection process. On each side we have an OVN cluster/AZ with its local
managed resources: LSP for VMs, LS, LSP connecting the VM to the router and
the LR. What does OVN interconnect add to a standard topology to make this
work? A connection between the Tenant logical router and a Transit Switch.&lt;/p&gt;
&lt;p&gt;The global database of the OVN IC dynamically replicates the TS between all
members of the interconnect domain (clusters/AZs), and what needs to be done
is basically to add this dynamically created TS in the OVN Northbound database
with the Tenant logical router.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ownership-of-resources"&gt;
&lt;h2&gt;Ownership of resources&lt;/h2&gt;
&lt;p&gt;With the usage of OVN Interconnect Neutron is no longer the only owner of
resources in each OVN deployment.&lt;/p&gt;
&lt;p&gt;We therefore need to first define which component owns which kind of resources.
The resources will be listed below for the left OVN deployment from the
example above.&lt;/p&gt;
&lt;section id="resources-owned-by-neutron"&gt;
&lt;h3&gt;Resources owned by Neutron&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;lr1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;lrp_lr1_ls1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;lsp_ls1_lr1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ls1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;lsp_ls1_vm1&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of these represent the:
* Tenant Network (ls1)
* Port of VMs or other things (lsp_ls1_vm1)
* Router of the Tenant (lr1, lrp_lr1_ls1, lsp_ls1_lr1)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="resources-owned-by-ovn-ic"&gt;
&lt;h3&gt;Resources owned by OVN-IC&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;ts1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;lsp_ts1_lr2 (created in the left OVN deployment)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;potentially Logical_Router_Static_Routes attached to lr1
(if route learning is enabled)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The resources owned by OVN-IC are dynamically created and removed by the
OVN-IC daemon when the process synchronizes the Northbound database between
interconnect domain elements.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="resources-owned-by-the-operator"&gt;
&lt;h3&gt;resources owned by the operator&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;lsp_ts1_lr1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;lrp_lr1_ts1&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The resources to connect the Transit Switch to the router of the user need to
be created by the operator (manually or with some kind of automation).
Managing these resources in Neutron is out of scope of this spec.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The above setup can already be created by an operator.
However the &lt;cite&gt;neutron-ovn-db-sync-util&lt;/cite&gt; tool will remove the resources owned by
OVN-IC and the operator, as Neutron does not know about them.&lt;/p&gt;
&lt;p&gt;Example of resources created by OVN-IC:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Logical_Switch
&lt;cite&gt;other_config:interconn-ts&lt;/cite&gt; with any value&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logical_Router_Static_Route
&lt;cite&gt;external_ids:ic-learned-route&lt;/cite&gt; with any value&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logical_Switch_Port
&lt;cite&gt;type&lt;/cite&gt; is set to &lt;cite&gt;remote&lt;/cite&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These fields are automatically set by OVN-IC, so they do not have a Neutron key
in the &lt;cite&gt;external_ids&lt;/cite&gt; or &lt;cite&gt;other_config&lt;/cite&gt; registers.&lt;/p&gt;
&lt;p&gt;Example of resources owned by the operator:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Logical_Switch_Port
&lt;cite&gt;external_ids&lt;/cite&gt; or &lt;cite&gt;other_config&lt;/cite&gt; with any value&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logical_Router_Port
&lt;cite&gt;external_ids&lt;/cite&gt; or &lt;cite&gt;other_config&lt;/cite&gt; with any value&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For resources created by operators such predefined options for &lt;cite&gt;external_ids&lt;/cite&gt;
or &lt;cite&gt;other_config&lt;/cite&gt; do not exist.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;To solve the problem described above, the proposal is to introduce a new filter
rule to check for the Neutron key during the &lt;cite&gt;neutron-ovn-db-sync-util&lt;/cite&gt; method
and not remove resources externally managed by OVN.&lt;/p&gt;
&lt;p&gt;This implementation is being named as to &lt;cite&gt;coexistence support for OVN
externally managed resources&lt;/cite&gt; because it is out of scope any type of OVN
externally managed resources integration as part of Neutron. The proposal of
this implementation is the creation of filters in the checking of the resources
created by Neutron, and it is the basis for any future implementation that
intends to integrate the OVN interconnect or other OVN features to Neutron.&lt;/p&gt;
&lt;p&gt;To implement the coexistence support the &lt;cite&gt;neutron-ovn-db-sync-util&lt;/cite&gt; tool only
needs to check the resources managed by Neutron. The main idea of this proposal
is described below.&lt;/p&gt;
&lt;p&gt;For resources created by Neutron the proposed solution implements the support
by checking the specific Neutron signature on these resources. Neutron creates
resources in the OVN NB database with the &lt;cite&gt;neutron:&lt;/cite&gt; key in the &lt;cite&gt;external_ids&lt;/cite&gt;
register:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Logical_Switch
&lt;cite&gt;external_ids:”neutron:”&lt;/cite&gt; with any value&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;_uuid&lt;/span&gt;               &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;bf82c8e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;fa49&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;b46&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bc4f&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;737311359&lt;/span&gt;&lt;span class="n"&gt;f44&lt;/span&gt;
&lt;span class="n"&gt;acls&lt;/span&gt;                &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;copp&lt;/span&gt;                &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;dns_records&lt;/span&gt;         &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;external_ids&lt;/span&gt;        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"neutron:availability_zone_hints"&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s2"&gt;"neutron:mtu"&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1442"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s2"&gt;"neutron:network_name"&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;self_network_az1_tenant1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s2"&gt;"neutron:revision_number"&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;forwarding_groups&lt;/span&gt;   &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;load_balancer&lt;/span&gt;       &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;load_balancer_group&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;name&lt;/span&gt;                &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2979&lt;/span&gt;&lt;span class="n"&gt;fcc1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9540&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4012&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="n"&gt;a2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;f83738b5b6f&lt;/span&gt;
&lt;span class="n"&gt;other_config&lt;/span&gt;        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;mcast_flood_unregistered&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mcast_snoop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="n"&gt;vlan&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;passthru&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;ports&lt;/span&gt;               &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;8e128001&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;d9a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="n"&gt;eb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a84b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;052&lt;/span&gt;&lt;span class="n"&gt;dc28a74bc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="mi"&gt;98555&lt;/span&gt;&lt;span class="n"&gt;f1c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;a12&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4703&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;dcb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="n"&gt;f44900f6b8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="n"&gt;abeca18e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5706&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;a2d&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;871&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5514&lt;/span&gt;&lt;span class="n"&gt;ba20f554&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="n"&gt;ba0e5d5e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5571&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f8c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b15c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dfa5115ba61c&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;qos_rules&lt;/span&gt;           &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Logical_Switch_Port, Logical_Router, Logical_Router_Port, etc.
&lt;cite&gt;external_ids:”neutron:”&lt;/cite&gt; with any value&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These &lt;cite&gt;neutron:…&lt;/cite&gt; keys in the external_ids are automatically set by Neutron,
so we can rely on them being there. We need to ensure that all methods called
by &lt;cite&gt;neutron-ovn-db-sync-util&lt;/cite&gt; check the Neutron signature in the external_ids,
and filter/ignore all the other externally managed resources when synchronizing
between Neutron and the OVN NB database.&lt;/p&gt;
&lt;section id="db-impact"&gt;
&lt;h3&gt;DB Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-changes"&gt;
&lt;h3&gt;Rest API Changes&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ovn-driver-changes"&gt;
&lt;h3&gt;OVN driver changes&lt;/h3&gt;
&lt;p&gt;Update &lt;cite&gt;neutron-ovn-db-sync-util&lt;/cite&gt; as described above.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="out-of-scope"&gt;
&lt;h2&gt;Out of Scope&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Integrating ovn-interconnect or other OVN externally managed feature into
Neutron in any way;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Primary assignees:
Felix Huettner &amp;lt;&lt;a class="reference external" href="mailto:felix.huettner%40mail.schwarz"&gt;felix&lt;span&gt;.&lt;/span&gt;huettner&lt;span&gt;@&lt;/span&gt;mail&lt;span&gt;.&lt;/span&gt;schwarz&lt;/a&gt;&amp;gt;
Roberto Bartzen Acosta &amp;lt;&lt;a class="reference external" href="mailto:rbartzen%40gmail.com"&gt;rbartzen&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add exclusion to &lt;cite&gt;neutron-ovn-db-sync-util&lt;/cite&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement relevant unit and functional tests using the existing facilities
in Neutron.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="administrator-documentation"&gt;
&lt;h3&gt;Administrator Documentation&lt;/h3&gt;
&lt;p&gt;Administrator documentation will need be included to describe to operators how
to use the OVN interconnect when building their interconnected OpenStack
clusters.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit/functional tests &lt;a class="footnote-reference brackets" href="#id4" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.ovn.org/support/dist-docs/ovn-architecture.7.html"&gt;https://www.ovn.org/support/dist-docs/ovn-architecture.7.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/contributor/testing/testing.html"&gt;https://docs.openstack.org/neutron/latest/contributor/testing/testing.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Mon, 06 May 2024 00:00:00 </pubDate></item><item><title>Apic ML2 driver enhancements</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/apic_ml2_driver_enhancements.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/apic-driver-enhancements"&gt;https://blueprints.launchpad.net/neutron/+spec/apic-driver-enhancements&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint keeps track of some improvements needed by the APIC ML2 Driver.
Specifically, the target enhancements will be:&lt;/p&gt;
&lt;p&gt;Refactoring of the apic-manager:
Making it more robust and it’s operations idempotent,
being also able to “fix” any incoherence that may happen between the APIC
and the Neutron world;&lt;/p&gt;
&lt;p&gt;Name mapping:
Defining configurable naming strategy for APIC. This allows the end-user
to see names instead of uuids for APIC resources in APIC GUI;&lt;/p&gt;
&lt;p&gt;External Gateway:
Enable router external gateway feature for the APIC plugin;&lt;/p&gt;
&lt;p&gt;Dynamic Topology Discovery:
Enable the ability for the APIC plugin to automatically discover
the physical topology (eg. compute host attached interfaces).
This allows for less manual configuration from the user.&lt;/p&gt;
&lt;p&gt;Support for VPC/LACP (bonding):
Enable the use of openstack servers connected in a
redundant topology with VPC/LACP (port bonding).&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;This blueprint is targeting a number of small enhancements
to solve different problems.&lt;/p&gt;
&lt;p&gt;High Availability:
Current APIC ML2 driver does not support a High Availability
and Synchronization strategy for APIC, making it hard to recover
from failures of the Neutron server. Also, the driver doesn’t
leverage APIC management address redundancy/fallback mechanism,
which translates into plugin failures every time the single APIC
controller address in it’s configuration is not reachable.&lt;/p&gt;
&lt;p&gt;Name Mapping:
At the current state, creating objects in the neutron model is
translated into an APIC model always named by the object UUID.
A alternative name mapping strategy should be provided to the user.&lt;/p&gt;
&lt;p&gt;L3 External Gateway Support:
Today, the APIC L3 driver doesn’t support the external gateway
extension for routers.&lt;/p&gt;
&lt;p&gt;Dynamic Topology Discovery:
The APIC drivers discovers the topology by leveraging some static
Neutron configuration. Ideally we want to be able to automatically
discover the topology by the use of a new agent.&lt;/p&gt;
&lt;p&gt;Support for VPC/LACP (bonding):
The current APIC driver does not support VPC/LACP or bonding of
ports. This is a desirable configuration for HA deployments
that we want to support.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;High Availability:
The changes for this point can be summarized into two major items:&lt;/p&gt;
&lt;p&gt;First, modifying the current APIC driver configuration so that the
user can specify as many APIC controllers as he likes. The APIC
client will then rotate among these addresses every time there’s a
connection failure.&lt;/p&gt;
&lt;p&gt;To improve the manager’s operations idempotence and reliability, a
transactional model is introduced which leverages the ability of
the APIC to run operations on a Model’s full subtree transactionally.&lt;/p&gt;
&lt;p&gt;Name Mapping:
A new DB table will be added to keep track of the “APIC Name” used
by a specific neutron object’s ID. Every time the driver is called,
the mapper will be used to retrieve the actual names in the backend.&lt;/p&gt;
&lt;p&gt;L3 External Gateway Support:
Every time a port with device_owner “router:gateway” is created, the
mechanism driver will run all the needed operations in order to
guarantee external connectivity to the proper networks. Some
configuration may be needed to describe the external router.&lt;/p&gt;
&lt;p&gt;Dynamic Topology Discovery:
An APIC specific agent is proposed. It will be installed as a 3rd
party agent on all openstack nodes that need to be connected to the
APIC fabric. The agent will listen to LLDP advertisements, and on
discovering a topology change, it will update the APIC with the
appropriate interface mapping.&lt;/p&gt;
&lt;p&gt;Support for VPC/LACP (bonding):
VPC pairs are defined in the plugin configuration. When an interface
from a switch that is in a VPC pair is detected, the appropriate
fabric configuration to enable that interface to work as a part of
VPC/LACP bond is created on the APIC.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Following new models are created by this driver. Note that these are
specific to this driver:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;ApicName: Tracks the name mapping.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ApicKey: Tracks persistent config on APIC that needs to be in sync with driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HostLink: Tracks connectivity of host links.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are also changes on the existing model. Again, everything
is APIC specific:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;NetworkEPG: Deleted;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PortProfile: Deleted;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TenantContract: Becomes RouterContract, since the contract will now be considered by Router and no by Tenant.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A database migration is included to create the tables for these
models.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;There is potentially a new configuration (for VPC pairs), if
that feature is used.
Also, if dynamic topology discovery is used, the agent should
be added to all the compute node, while the service will be
likely installed on the cloud controller.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The transactional model for the APIC manager does a lot of work
“locally”, and only 1 rest call at the end of each transaction.
This will improve the responsiveness of the plugin.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The configuration of host connectivity is no longer required in
the configuration file.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Ivar Lazzaro (mmaleckk)&lt;/p&gt;
&lt;p&gt;Mandeep Dhami (mandeep-dhami)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;APIC Mechanism driver package;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;APIC L3 driver package;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit Tests Code (APIC Specific).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit Test&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Configuration Reference guide will be updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Mon, 06 May 2024 00:00:00 </pubDate></item><item><title>Adding support for host-routes and dns_nameservers options for Nuage Plugin</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/dhcp-host-routes-and-dns-support-for-nuage-plugin.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/dhcp-host-routes-and-dns-support-for-nuage-plugin"&gt;https://blueprints.launchpad.net/neutron/+spec/dhcp-host-routes-and-dns-support-for-nuage-plugin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Adding support for host-routes and dns_nameservers options via DHCP options
for the Nuage Plugin&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The current the Nuage Plugin does not support adding host routes or
DNS nameservers via DHCP options for a Neutron subnet.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Currently the Nuage Plugin does not support Neutron’s adding host routes or DNS
nameservers via DHCP options on a subnet.&lt;/p&gt;
&lt;p&gt;The Nuage’s VSP supports this feature and the support needs to be added in the
plugin code.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;The following DHCP options will be supported :&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DNS nameserver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Host routes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The proposed change is to support the creation of DNS nameserver and/or Host
routes using the Neutron DNS and Host routes&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;For example:&lt;/dt&gt;&lt;dd&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;neutron subnet-create test 192.168.10.0/24&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;–dns_nameservers list=true 8.8.4.4 8.8.8.8&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;This action will create a subnet name test with a CIDR 192.168.10.0/24.
The nameservers 8.8.4.4 8.8.8.8 will added to this subnet, this translate to a
subnet in the Nuage’s VSP subnet with the same nameservers&lt;/p&gt;
&lt;p&gt;The CRUD operations will be supported by the Nuage’s VSP plugin for both
DNS nameserver and Host routes.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;The modification are required on the plugin.py&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;The new method __create_port_gateway will be created.&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;This method will create a port of type network:dhcp for the current subnet and tenant&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The __validate_create_subnet method will be modified to allow the host_routes key to be a valid options of the subnet dictionary&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The update_subnet method will be added to the plugin&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The  _create_nuage_subnet method will be merged into the create_subnet method. This will newly updated method will also create a DHCP port using the method _create_port_gateway described above.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Franck Yelles&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;fyelles&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Extension code in Nuage plugin&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nuage CI coverage addition&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nuage Unit tests additions, the following test units will be updated/added :
* test_create_subnet_bad_hostroutes
* test_update_subnet_adding_additional_host_routes_and_dns
* test_create_subnet_with_one_host_route
* test_create_subnet_with_two_host_routes
* test_create_subnet_with_too_many_routes
* test_update_subnet_route
* test_update_subnet_route_to_None
* test_update_subnet_route_with_too_many_entries
* test_delete_subnet_with_route
* test_delete_subnet_with_dns_and_route
* test_validate_subnet_host_routes_exhausted
* test_validate_subnet_dns_nameservers_exhausted&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit Test coverage for the DHCP options within Nuage unit test
Nuage CI will be modified to start supporting this extension tests&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 06 May 2024 00:00:00 </pubDate></item><item><title>Enhancement to Neutron BGPaaS</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/xena/bgpaas-enhancements.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1921461"&gt;https://bugs.launchpad.net/neutron/+bug/1921461&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Enhancement to Neutron BGPaaS to directly support Neutron Routers and
bgp-peering from such routers over internal &amp;amp; external Neutron Networks&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;There are very good foundation APIs in Neutron BGPaaS that brought in BGP
service functionality (see &lt;a class="footnote-reference brackets" href="#id11" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;) into Neutron through Neutron Dynamic Routing.
(see &lt;a class="footnote-reference brackets" href="#id13" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; )&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;In this spec, Neutron-BGPaaS, BGPaaS and  neutron-dynamic-routing/bgp are
used as synonymns. These refers to “Neutron Dynamic Routing using BGPaaS”
function already available in Neutron. Similarly, ‘ISP network’ and
‘Neutron External Network’ are used as synonymns.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In a Telco Service Provider environment, VNFs (Virtual Network Functions &lt;a class="footnote-reference brackets" href="#id14" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;)
&amp;amp; CNFs (Containerized-Network-Functions) are run that provides simple-to-fairly
complex services to subscribers. These VNFs use many Non-Neutron IP-Addresses
which need to be exposed to subscribers. The subscribers access these services
through these Non-Neutron IP-Addresses, referred as ‘Service-Address’. It can
belong to either IPv4 (or) IPv6 address-families.&lt;/p&gt;
&lt;p&gt;Service-Address are wholly managed inside a VNF transparent to Neutron. But
these Service-Address are reachable on the dataplane by subscribers, through
VNICs (or Ports) holding Neutron-managed Addresses. In short, the Neutron
managed primary-addresses on VNFs VNICs act as NextHops to the Service-Address
of VNF.&lt;/p&gt;
&lt;p&gt;In order to enable L3 reachability to these Service-Addresses from an
ISP-network (or) make the Service-addresses reachable from another
neutron-tenant-network entity, these Service-Addresses need to be brought into
a Neutron Router’s Routing Table.&lt;/p&gt;
&lt;p&gt;The number of VNFs are high and hence the number of service addresses to be
exposed are higher. “BGP between the VNFs and their hosting Neutron Routers”
provides a very elegant and scalable automated approach for a control-plane
driven route-learning of Service-Address by the Neutron Router from the VNFs.
This enables L3 reachability of such Service-Addresses from other
neutron-tenant-network-VNFs that is attached to the same Neutron Router.&lt;/p&gt;
&lt;p&gt;These service addresses also need to be advertised to the ISP-PE-Router. This
will enable subscribers present on ISP-network be able to use the services
exported by applications in the VNFs.&lt;/p&gt;
&lt;p&gt;The existing Neutron Dynamic BGPaaS falls a little short of supporting the
above requirements due to below reasons:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Existing BGPaaS lacks the functionality (both API and implementations) to do
BGP Peering over Neutron Internal Networks. The addition of service-addresses
to Neutron Router’s Routing Table requires BGP control plane to bring them in
via BGP peering (see &lt;a class="footnote-reference brackets" href="#id12" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;) towards the VNFs over Neutron Tenant Networks from
Neutron Router. It also requires BGP speaker to learn routes from the BGP
peers. Current implementation advertises routes to peers but doesn’t learn
from peers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Existing Neutron BGPaaS supports BGP Peering only over Non-Neutron Networks.
Please refer the current implementation and documentation as in &lt;a class="footnote-reference brackets" href="#id18" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; .
Advertisment of service-addresses to the ISP-PE-Router requires BGP Peering
over Neutron External Networks. This will enable the ISP-PE-Router to learn
the Service-Addresses over the BGP control plane. Thereby, enabling
L3-reachability for subscribers on the ISP-side to be able to take advantage
of services offered by VNFs (and CNFs).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Exising BGPaaS doesn’t provide API/implementation to associate a BGP speaker
to a router. It currently supports a’loose-association’of network to BGP
speaker. This ‘loose-association’ is concept where the BGP speaker derives
the routes of the Neutron Router through APIs and not due to direct
connectivity of BGP Speaker to the Neutron Router. Association of BGP speaker
to router enables access to all the neutron-router-interfaces ie. both
internal/external interfaces. This will enable a single bgpspeaker associated
with the Neutron Router, be able to peer simultaneously towards VNFs on
neutron-tenant-network as well as the ISP-PE-Router on
neutron-external-network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It also doesn’t support BGP peer group feature. BGP Peer Group feature
enables automatic-bgp-peering towards VNFs by Neutron Router whenever the
VNFs are scaled-out in a VNF cluster or whenever the VNFs are scaled in from
a VNF cluster. The automatic-bgp-peering refers to the fact that the current
BGP Speaker will be enhanced to automatically accept peering-requests from
VNF if the VNFs are within a pre-configured ip-address-range (aka
listen-range) that openstack tenant can configure for the BGP speaker.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;BGPaaS capability will have varying implementations from different Neutron
backends.  This makes it important to have some feedback ingrained in the
Neutron BGPaaS API. It will allow various Neutron backends (including
reference BGPaaS backend) to drive realization status inside Openstack Infra
for the BGP resources exposed by Neutron BGPaaS. To provide that, the
proposal in the spec is to add a new resource type ‘Association’ that can
work with current BGPSpeaker object. More specifically, the plan is to
support router_association, peer_association as resources under a BGPSpeaker
object. A &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;router_association&lt;/span&gt;&lt;/code&gt; resource will be used to create a binding
between a BGPSpeaker and a Neutron Router, that will internally realizes BGP
Control Plane over that Neutron Router. Similarly, a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;peer_association&lt;/span&gt;&lt;/code&gt;
resource will be used to create a binding between a BGPSpeaker and a BGPPeer
that will internally realize BGP Peering between the BGPSpeaker and the
BGPPeer resource.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;To enable L3 reachability to the Service-Addresses from ISP-network or from
another-neutron-tenant-network entity, the below usecases are introduced :&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Enable&lt;/span&gt; &lt;span class="pre"&gt;direct&lt;/span&gt; &lt;span class="pre"&gt;BGP-Peering&lt;/span&gt; &lt;span class="pre"&gt;(see&lt;/span&gt; &lt;span class="pre"&gt;[2]_)&lt;/span&gt; &lt;span class="pre"&gt;from&lt;/span&gt; &lt;span class="pre"&gt;a&lt;/span&gt; &lt;span class="pre"&gt;Neutron&lt;/span&gt; &lt;span class="pre"&gt;Router&lt;/span&gt; &lt;span class="pre"&gt;towards&lt;/span&gt; &lt;span class="pre"&gt;the&lt;/span&gt;
&lt;span class="pre"&gt;VNFs&lt;/span&gt; &lt;span class="pre"&gt;(or&lt;/span&gt; &lt;span class="pre"&gt;CNFs)&lt;/span&gt; &lt;span class="pre"&gt;on&lt;/span&gt; &lt;span class="pre"&gt;its&lt;/span&gt; &lt;span class="pre"&gt;connected&lt;/span&gt; &lt;span class="pre"&gt;networks.&lt;/span&gt;&lt;/code&gt; This provides L3 reachability to
the service-addresses hosted on such VNFs, as such addresses will be
installed in the Neutron Router’s routing-table by the BGPaaS control
plane. The proposal is to provide facility to directly associate a BGP
Speaker to a neutron-router, that will in turn enable the router to reach
BGP-Control plane learned routes from the VNF.. A single router can be
associated to a BGP speaker and the speaker will be running inside the L3
router namespace.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Enable&lt;/span&gt; &lt;span class="pre"&gt;BGP-Peering&lt;/span&gt; &lt;span class="pre"&gt;over&lt;/span&gt; &lt;span class="pre"&gt;Neutron&lt;/span&gt; &lt;span class="pre"&gt;External&lt;/span&gt; &lt;span class="pre"&gt;Networks&lt;/span&gt; &lt;span class="pre"&gt;from&lt;/span&gt; &lt;span class="pre"&gt;a&lt;/span&gt; &lt;span class="pre"&gt;Neutron&lt;/span&gt; &lt;span class="pre"&gt;Router&lt;/span&gt; &lt;span class="pre"&gt;to&lt;/span&gt;
&lt;span class="pre"&gt;the&lt;/span&gt; &lt;span class="pre"&gt;ISP-PE-Router.&lt;/span&gt;&lt;/code&gt; This allows the ISP-PE-Router to learn the
Service-Addresses over the BGP control plane from Neutron Router. Thereby,
enabling L3-reachability for subscribers on the ISP-side to leverage
services offered by VNFs (and CNFs).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Support&lt;/span&gt; &lt;span class="pre"&gt;BGP&lt;/span&gt; &lt;span class="pre"&gt;peer&lt;/span&gt; &lt;span class="pre"&gt;group&lt;/span&gt; &lt;span class="pre"&gt;feature&lt;/span&gt;&lt;/code&gt; This will allow to transparently scale
bgp peering to a  number of VNFs, whenever VNF clusters are scaled-out or
scaled-in. It supports BGP peering to a group of remote neighbors that are
configured using a range of IP addresses. This can also be used in k8s over
openstack deployment where CNF scale-out/scale-in is a pure k8s operation.
It would be undesirable to call neutron APIs in this case.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;New resources (Network Association, Router Association, Peer Association) will
be added as part of this spec. Association resources provides the below
benefits&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Enables provisioning of certain BGP control plane parameters specific to
BGP-Speaker-to-BGP-Peer binding and also specific to BGP-Speaker-to-Router
binding. For eg: some attributes (status, advertise-extra-routes etc) are
useful when linked to associations rather than directly to parent resources
(speaker, peer). A BGP Peer can be associated to different BGP Speakers, so
having a Status field in bgp-peer won’t be beneficial. It is useful only
when associated to Peer Association resource.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enables the Neutron BGPaaS APIs to provide feedback on the realization
status of BGP Control Plane towards Openstack Tenant. For eg: In this spec,
a new Status field is planned to be introduced. This will allow a
Neutron-BGPaaS backend driver to provide realization-status for different
BGP resources inside Openstack Infra.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+-----------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                               &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="n"&gt;ISP&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;PE&lt;/span&gt; &lt;span class="n"&gt;Router&lt;/span&gt;                 &lt;span class="o"&gt;|---------|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                               &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------------------------------+&lt;/span&gt;        &lt;span class="n"&gt;EBGP&lt;/span&gt;
                        &lt;span class="o"&gt;|&lt;/span&gt;                                 &lt;span class="o"&gt;|&lt;/span&gt;
                        &lt;span class="o"&gt;|&lt;/span&gt;                                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------------------------------+&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                               &lt;span class="o"&gt;|---------|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="n"&gt;Neutron&lt;/span&gt; &lt;span class="n"&gt;Router&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                               &lt;span class="o"&gt;|---------|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------------------------------+&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
                      &lt;span class="o"&gt;|&lt;/span&gt;                                   &lt;span class="o"&gt;|&lt;/span&gt;
                      &lt;span class="o"&gt;|&lt;/span&gt;                                 &lt;span class="n"&gt;EBGP&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------------------------------+&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="n"&gt;VNF&lt;/span&gt; &lt;span class="n"&gt;Cluster&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+-----------------+&lt;/span&gt;   &lt;span class="o"&gt;+-----------------+&lt;/span&gt;    &lt;span class="o"&gt;|---------|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="n"&gt;VM1&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="n"&gt;VM2&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+-----------------+&lt;/span&gt;   &lt;span class="o"&gt;+-----------------+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To advertise the multiple service addresses hosted by VNFs to ISP-PE routers,
2 BGP sessions are created. One BGP session created directly towards the VNFs
from a Neutron Router hosting the neutron-tenant-networks of the VNF. And the
next BGP-Peering towards the ISP-PE-Routers from Neutron Router directly over
the Neutron External Networks.&lt;/p&gt;
&lt;p&gt;Proposal is to enhance existing BGPaas (see &lt;a class="footnote-reference brackets" href="#id16" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;), allow neutron router to be
associated to a BGP Speaker and allow BGP Speaker to peer with both the
internal-Networks and External-Networks present on that Neutron Router. This
will be implemented using enhancements to the neutron-service and
neutron-dynamic-routing.&lt;/p&gt;
&lt;section id="implementation-approaches"&gt;
&lt;h3&gt;Implementation approaches&lt;/h3&gt;
&lt;section id="option-1"&gt;
&lt;h4&gt;Option 1&lt;/h4&gt;
&lt;p&gt;A BGP speaker is spawned inside router namespace, when a neutron-router is
associated to BGP Speaker. BGP speaker will be running inside the L3 router
namespace which enables access to all the neutron-router-interfaces ie. both
internal/external interfaces. BGP functionality provided by OS-Ken will be
reused to excite BGP speaker functionality to run only within the neutron
router namespace.&lt;/p&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BGP&lt;/span&gt; &lt;span class="pre"&gt;Service&lt;/span&gt; &lt;span class="pre"&gt;Plugin&lt;/span&gt;&lt;/code&gt; will be enhanced to accept the request to associate a
BGP speaker to the router. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BGP&lt;/span&gt; &lt;span class="pre"&gt;L3&lt;/span&gt; &lt;span class="pre"&gt;agent&lt;/span&gt; &lt;span class="pre"&gt;extension&lt;/span&gt;&lt;/code&gt; will implement the L3
agent side of BGP enhancements. It will be responsible for realizing
bgpspeaker inside the router-namespace and now bgpspeaker can peer over
networks on the router from inside the router-namespace. BGP speaker can
listen on 0.0.0.0:179 which enables it to listen on all the
neutron-router-interfaces and can peer with the neighbour based on the
configuration.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+---------------+&lt;/span&gt;              &lt;span class="o"&gt;+-----------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;DHCP&lt;/span&gt; &lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Router&lt;/span&gt; &lt;span class="n"&gt;namespace&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;qdhcp&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;qrouter&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+------+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+---+&lt;/span&gt;   &lt;span class="o"&gt;+---+&lt;/span&gt;   &lt;span class="o"&gt;+-----------+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tap&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;qg&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;BGP&lt;/span&gt; &lt;span class="n"&gt;Speaker&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+------+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+---+&lt;/span&gt;   &lt;span class="o"&gt;+---+&lt;/span&gt;   &lt;span class="o"&gt;+-----------+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+---------------+&lt;/span&gt;              &lt;span class="o"&gt;+-----------------------------------+&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------------------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+--------+&lt;/span&gt;               &lt;span class="o"&gt;+-------+&lt;/span&gt;  &lt;span class="o"&gt;+-------+&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="n"&gt;tap&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="n"&gt;qg&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+--------+&lt;/span&gt;               &lt;span class="o"&gt;+-------+&lt;/span&gt;  &lt;span class="o"&gt;+-------+&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                      &lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------------------------------------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="option-2"&gt;
&lt;h4&gt;Option 2&lt;/h4&gt;
&lt;p&gt;In Option 1, since BGP speaker is spawned inside the router namespace, the
speaker is tightly coupled with that router namespace. For a different BGP
Speaker on a different router, wherein that router in turn is realized on the
same network-node hosting the original router, a new instantiation of the BGP
Speaker is required. This could potentially bring in scalability and
performance problems with Option 1.&lt;/p&gt;
&lt;p&gt;In Option 2, the proposal is to create and use VRF for BGP-Peering. VRF device
(see &lt;a class="footnote-reference brackets" href="#id19" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;9&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;) can be used instead of namespace for BGP peering. VRF is a layer 3
master network device with its own associated routing table. It also provides
added benefit of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VRF&lt;/span&gt; &lt;span class="pre"&gt;any&lt;/span&gt;&lt;/code&gt; socket which allows a single process instance to
efficiently provide service across all VRFs. So for N router associated BGP
speakers, N vrfs will be created but a single BGP speaker will serve all of
them.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+---------------+&lt;/span&gt;    &lt;span class="o"&gt;+-----------------+&lt;/span&gt;    &lt;span class="o"&gt;+-----------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;DHCP&lt;/span&gt; &lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Router&lt;/span&gt; &lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;VRF&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;qdhcp&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="n"&gt;qrouter&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;BGP&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+------+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+---+&lt;/span&gt;   &lt;span class="o"&gt;+---+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+---+&lt;/span&gt;   &lt;span class="o"&gt;+---+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="o"&gt;---&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;speaker&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tap&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;qg&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;vr&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;vg&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+------+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+---+&lt;/span&gt;   &lt;span class="o"&gt;+---+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+---+&lt;/span&gt;   &lt;span class="o"&gt;+---+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;    &lt;span class="o"&gt;+-----------------+&lt;/span&gt;    &lt;span class="o"&gt;+-----------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+--------+&lt;/span&gt;      &lt;span class="o"&gt;+-------+&lt;/span&gt;  &lt;span class="o"&gt;+-------+&lt;/span&gt;  &lt;span class="o"&gt;+-------+&lt;/span&gt;  &lt;span class="o"&gt;+-------+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="n"&gt;tap&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="n"&gt;qg&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="n"&gt;vr&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="n"&gt;vg&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+--------+&lt;/span&gt;      &lt;span class="o"&gt;+-------+&lt;/span&gt;  &lt;span class="o"&gt;+-------+&lt;/span&gt;  &lt;span class="o"&gt;+-------+&lt;/span&gt;  &lt;span class="o"&gt;+-------+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                                                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                      &lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------------------------------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Current L3Plugin and L3Agent will continue to provide Neutron-Router
functionality. VRF will be realized by BGP-Dr-Agent and a new VRF is created
when a neutron-router is associated to BGP Speaker. VRF will be used only for
BGP peering and the learnt routes are installed inside router namespace.&lt;/p&gt;
&lt;p&gt;Extra IPs has to be allocated from internal and external subnet pools for the
vr, vg interfaces respectively. These IPs will be used for BGP peering and
the allocation of new IPs can be considered as a short coming with this
option.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="option-3"&gt;
&lt;h4&gt;Option 3&lt;/h4&gt;
&lt;p&gt;VRF device can provide most of the L3 functionalities provided by router
namespace. In this option, the idea is to completely replace the namespace
with VRF device. A new VRF will be created when a neutron-router is created.&lt;/p&gt;
&lt;p&gt;Both L3-Routing as well as BGP can be realized through VRFs. Linux-VRF will
provide neutron router functionality which includes dataplane L3-forwarding
for east-west, north-south and NATing.&lt;/p&gt;
&lt;p&gt;This provides the same advantages as in option 2 and eliminates its
disadvantages. But the main concern with this approach is that it will make a
huge deviation from the existing L3 implementation which will require a lot
of effort and time. This also requires changes to upgrade mechanisms.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The current plan is to implement Option 1 which is simpler and doesn’t
deviate much from the existing implementation. Incase the implementation
option 3 is going to be used, it will be only a gradual replacement (from
namespace to vrf) with proper upgrade path.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="ha-capable-neutron-router-with-bgpaas"&gt;
&lt;h4&gt;HA-Capable Neutron Router with BGPaaS&lt;/h4&gt;
&lt;p&gt;When HA-Capable neutron router is associated to a BGPSpeaker, two BGPSpeaker
instances will be run, one on active router namespace and other on the standby
router namespace. Whenever the failover happens from Active to Standby
Namespace, the BGPSpeaker on Standby will be able to peer with BGP-Peers and
become an Active-BGP-Speaker managing the Router.&lt;/p&gt;
&lt;p&gt;The implementation planned in this spec supports only Centralized Neutron
Routers (both HA and non-HA) and not Distributed Routers.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="rest-api-neutron-client-command-impact"&gt;
&lt;h3&gt;REST API &amp;amp; Neutron client command Impact&lt;/h3&gt;
&lt;p&gt;Use-case a)&lt;/p&gt;
&lt;section id="associate-neutron-router-to-bgp-speaker-api"&gt;
&lt;h4&gt;Associate neutron router to BGP Speaker API&lt;/h4&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speakers&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speaker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;router_associations&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="s2"&gt;"router_association"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"router_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"c930d7f6-ceb7-40a0-8b81-a425dd994ccf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"advertise_extra_routes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;router_id&lt;/span&gt;&lt;/code&gt; represents the UUID of the neutron router to which the BGP
speaker has to be associated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;advertise_extra_routes&lt;/span&gt;&lt;/code&gt; decides whether neutron extra routes on the
neutron router will be redistributed to bgp-peers by the bgpspeaker. Default
is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt; and so all neutron extra routes will be redistributed to every
bgp-peer that is bound to the BGP Speaker. Turning OFF
advertise_extra_routes will disable advertisement of neutron router’s
extra-routes by the bgpspeaker.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The enhancement will support a router to be associated to only a single
BGP speaker. The association of router to speaker and network to speaker
will be a mutually exclusive operation.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;New neutron Client Command:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;bgp&lt;/span&gt; &lt;span class="n"&gt;speaker&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="n"&gt;association&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;advertise&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;extra&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;no&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;advertise&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;extra&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgpspeaker&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="disassociate-neutron-router-from-bgp-speaker-api"&gt;
&lt;h4&gt;Disassociate neutron router from BGP Speaker API&lt;/h4&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt;  &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speakers&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speaker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;router_associations&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;association&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;New neutron Client Command:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;bgp&lt;/span&gt; &lt;span class="n"&gt;speaker&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="n"&gt;association&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgpspeaker&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Deleting a BGP SPeaker will not be permitted, if the speaker already has
multiple associations on itself like peer-associations and
router-associations. Similarly, deletion of a router that is asoociated
to a BGP speaker is also not allowed.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="update-bgp-speaker-router-association"&gt;
&lt;h4&gt;Update BGP Speaker Router Association&lt;/h4&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speakers&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speaker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;router_associations&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;association&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="s2"&gt;"router_association"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"router_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"c930d7f6-ceb7-40a0-8b81-a425dd994ccf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"advertise_extra_routes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;advertise_extra_routes&lt;/span&gt;&lt;/code&gt; field can be set to True or False when updating
the router association.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;New neutron Client Command:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;bgp&lt;/span&gt; &lt;span class="n"&gt;speaker&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="n"&gt;association&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;advertise&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;extra&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;no&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;advertise&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;extra&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgpspeaker&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="list-router-associations-for-a-given-bgp-speaker"&gt;
&lt;h4&gt;List Router associations for a given BGP speaker&lt;/h4&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speakers&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speaker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;router_associations&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="s2"&gt;"router_associations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"router_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"c930d7f6-ceb7-40a0-8b81-a425dd994ccf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"advertise_extra_routes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
      &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'ACTIVE'&lt;/span&gt;
     &lt;span class="p"&gt;},&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"router_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"a330d7f6-ceb7-40a0-8b81-a425dd994bbe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"advertise_extra_routes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
      &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'ACTIVE'&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;status&lt;/span&gt;&lt;/code&gt; attribute helps to know whether Neutron-BGPaaS backend software
has realized the router association successfully on the openstack
infrastructure. Status field can be either &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DOWN&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ACTIVE&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="show-details-for-a-bgp-speaker-router-association"&gt;
&lt;h4&gt;Show details for a BGP speaker Router Association&lt;/h4&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speakers&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speaker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;router_associations&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;association&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="s2"&gt;"router_association"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"router_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"c930d7f6-ceb7-40a0-8b81-a425dd994ccf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"advertise_extra_routes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
      &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'ACTIVE'&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="create-bgp-speaker-peer-association"&gt;
&lt;h4&gt;Create BGP speaker Peer Association&lt;/h4&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speakers&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speaker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;peer_associations&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="s2"&gt;"peer_association"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"peer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"b930d7f6-ceb7-40a0-8b81-a425dd994ccf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;peer_id&lt;/span&gt;&lt;/code&gt; represents the UUID of the BGP peer to which the BGP speaker has
to be associated.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;New neutron Client Command:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;bgp&lt;/span&gt; &lt;span class="n"&gt;speaker&lt;/span&gt; &lt;span class="n"&gt;peer&lt;/span&gt; &lt;span class="n"&gt;association&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgpspeaker&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="delete-bgp-speaker-peer-association"&gt;
&lt;h4&gt;Delete BGP speaker Peer Association&lt;/h4&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt;  &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speakers&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speaker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;peer_associations&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;association&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Deleting a BGP speaker which has peer-associated will not be allowed.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;New neutron Client Command:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;bgp&lt;/span&gt; &lt;span class="n"&gt;speaker&lt;/span&gt; &lt;span class="n"&gt;peer&lt;/span&gt; &lt;span class="n"&gt;association&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgpspeaker&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="list-peer-associations-for-a-given-bgp-speaker"&gt;
&lt;h4&gt;List Peer associations for a given BGP speaker&lt;/h4&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speakers&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speaker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;peer_associations&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="s2"&gt;"peer_associations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"peer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"b930d7f6-ceb7-40a0-8b81-a425dd994ccf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'ACTIVE'&lt;/span&gt;
     &lt;span class="p"&gt;},&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"peer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"a640d7f6-ceb7-40a0-8b81-a425dd994dde"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'ACTIVE'&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;status&lt;/span&gt;&lt;/code&gt; attribute helps to know whether Neutron-BGPaaS backend software
has realized the peer association successfully on the openstack
infrastructure. Status field can be either &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DOWN&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ACTIVE&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="show-details-for-a-bgp-speaker-peer-association"&gt;
&lt;h4&gt;Show details for a BGP speaker Peer Association&lt;/h4&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speakers&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speaker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;peer_associations&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;association&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="s2"&gt;"peer_association"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"peer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"b930d7f6-ceb7-40a0-8b81-a425dd994ccf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'ACTIVE'&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="show-routes-managed-by-bgp-speaker-api"&gt;
&lt;h4&gt;Show routes managed by BGP Speaker API&lt;/h4&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speakers&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speaker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;get_routes&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="s2"&gt;"routes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"192.168.10.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"nexthop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"10.0.0.1"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
              &lt;span class="s2"&gt;"route-type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"local"&lt;/span&gt;
         &lt;span class="p"&gt;},&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"192.168.11.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"nexthop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"10.0.0.5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.6"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
              &lt;span class="s2"&gt;"route-type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"peer"&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt;
       &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;nexthop&lt;/span&gt;&lt;/code&gt; is a list which contains ip addresses that is going to be used
to reach a certain destination cidr.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cidr&lt;/span&gt;&lt;/code&gt; represents the CIDR prefix.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;route-type&lt;/span&gt;&lt;/code&gt; can be local or peer based on whether the routes are local or
learnt from the peer respectively.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The routes can be obtained from the backend. For example, in case of os_ken
backend, rib_get method (see &lt;a class="footnote-reference brackets" href="#id20" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;10&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;) can be used to obtain the routes.&lt;/p&gt;
&lt;p&gt;New Neutron Client Command:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;bgp&lt;/span&gt; &lt;span class="n"&gt;speaker&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="n"&gt;routes&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgpspeaker&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Use-case b)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="create-bgp-peer-group-api"&gt;
&lt;h4&gt;Create BGP Peer Group API&lt;/h4&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"bgp_peer_groups"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"bgppeergroup1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_asn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"4566"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"next_hop_self"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"update_source_ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.20.1.5"&lt;/span&gt;
      &lt;span class="s2"&gt;"auth_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"md5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;passwd&amp;gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;remote_asn&lt;/span&gt;&lt;/code&gt; represents the remote AS number of a BGP peer group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;next_hop_self&lt;/span&gt;&lt;/code&gt; decides whether to modify the nexthop attribute to its own
during BGP advertisement.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;update_source_ip&lt;/span&gt;&lt;/code&gt; forces BGP to use the IP address specified while
talking to a BGP neighbor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;auth_type&lt;/span&gt;&lt;/code&gt; determines the authentication algorithm. Supported algorithms
are  none and md5, none by default.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;password&lt;/span&gt;&lt;/code&gt; represents the authentication password for the specified
authentication type.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;New neutron Client Commands:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;bgp&lt;/span&gt; &lt;span class="n"&gt;peer&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hop&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;no&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hop&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;update_source&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;remote&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;asn&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;asn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="delete-bgp-peer-group-api"&gt;
&lt;h4&gt;Delete BGP Peer Group API&lt;/h4&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Deletion of peer-group will succeed only if there are no BGP-Peers referring
to this peer-group.&lt;/p&gt;
&lt;p&gt;New Neutron Client Commands:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;bgp&lt;/span&gt; &lt;span class="n"&gt;peer&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="create-a-bgp-peer-using-a-pre-created-peer-group-api"&gt;
&lt;h4&gt;Create a bgp-peer using a pre-created peer-group API&lt;/h4&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;peers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"bgp_peer"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
      &lt;span class="s2"&gt;"peer_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"a930d7f6-ceb7-40a0-8b81-a425dd994ccf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"bgppeer1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"listen_range"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.2.1.0/24"&lt;/span&gt;
      &lt;span class="s2"&gt;"listen_limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
      &lt;span class="s2"&gt;"auth_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"md5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;passwd&amp;gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;peer_group_id&lt;/span&gt;&lt;/code&gt; represents the UUID of the BGP peer group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;listen_range&lt;/span&gt;&lt;/code&gt; defines a prefix range to be associated with the peer group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;listen_limit&lt;/span&gt;&lt;/code&gt; defines the maximum number of BGP peers that can be created
automatically.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are new fields to the existing BGP peer API and are optional parameters.
A BGP-Peer-Group can be re-used by multiple BGP Peers.&lt;/p&gt;
&lt;p&gt;Changed Neutron Client Commands ((see &lt;a class="footnote-reference brackets" href="#id17" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;bgp&lt;/span&gt; &lt;span class="n"&gt;peer&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;listen&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;range&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;listen&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;listen&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;bgp&lt;/span&gt; &lt;span class="n"&gt;speaker&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;peer&lt;/span&gt; &lt;span class="n"&gt;mybgpspeaker&lt;/span&gt; &lt;span class="n"&gt;bgpppeer1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;peer-group&lt;/span&gt;&lt;/code&gt; attribute is introduced in the already existing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;bgp&lt;/span&gt; &lt;span class="pre"&gt;peer&lt;/span&gt;&lt;/code&gt;
neutron client command. It specifies the name/UUID of the BGP peer group that
has to be used by BGP Peer.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="create-bgp-peers-with-update-source-and-next-hop-self-parameters-api"&gt;
&lt;h4&gt;Create BGP peers with update-source and next-hop-self parameters API&lt;/h4&gt;
&lt;p&gt;As part of the enhancement, new attributes are introduced for the BGP peer
model. These are next_hop_self and update_source_ip. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;next_hop_self&lt;/span&gt;&lt;/code&gt; decides
whether to modify the nexthop attribute to its own during BGP advertisement.
And &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;update_source_ip&lt;/span&gt;&lt;/code&gt; forces BGP to use the IP address specified while
talking to a BGP neighbor.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bgp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;peers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"bgp_peer"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
      &lt;span class="s2"&gt;"auth_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"none"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_as"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"1001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"bgppeer1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"peer_ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"10.0.0.3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"next_hop_self"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"update_source_ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.2.0.15"&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Changed Neutron Client Commands:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;bgp&lt;/span&gt; &lt;span class="n"&gt;peer&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hop&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;remote&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;bgppeer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;update-source-ip&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;next-hop-self&lt;/span&gt;&lt;/code&gt; are introduced in the existing
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;bgp&lt;/span&gt; &lt;span class="pre"&gt;peer&lt;/span&gt;&lt;/code&gt; neutron client command.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="backend-for-reference-implementation"&gt;
&lt;h4&gt;Backend for reference implementation&lt;/h4&gt;
&lt;p&gt;os-ken can be used to handle BGP (see &lt;a class="footnote-reference brackets" href="#id15" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; ).
os-ken is able to start bgp speaker using BGPSpeaker class and
it is possible to receive event notifications (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BGP_BEST_PATH_CHANGED&lt;/span&gt;&lt;/code&gt;)
which can be then used to populate routes inside the namespace.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;bgp_peers&lt;/span&gt;&lt;/code&gt; table will be updated to incorporate the new fields.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Field&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;update_source_ip&lt;/p&gt;
&lt;p&gt;next_hop_self&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;
&lt;p&gt;Boolean&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Forces BGP to use the IP address
specified while talking to a BGP neighbor
Setting to True enables all published
routes to carry BGPSpeaker IP address
over the BGP Control Plane towards this
BGP Peer.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;New table &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;bgp_speaker_router_bindings&lt;/span&gt;&lt;/code&gt; will be created to manage the
speaker to router association.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Field&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;
&lt;p&gt;bgp_speaker_id
router_id&lt;/p&gt;
&lt;p&gt;advertise_extra_routes&lt;/p&gt;
&lt;p&gt;status&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;
&lt;p&gt;uuid-str
uuid-str&lt;/p&gt;
&lt;p&gt;Boolean&lt;/p&gt;
&lt;p&gt;String&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID of the BGP speaker router
association
UUID of the BGP speaker
UUID of the router to which the BGP
speaker has to be associated
Decides whether neutron extra routes
on the neutron router will be
advertised to bgp-peers
Shows whether Neutron-BGPaaS backend
software has realized the router
association successfully on the
openstack infrastructure. Status field
can be either DOWN or ACTIVE.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Similarly, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;id&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;status&lt;/span&gt;&lt;/code&gt; field will be introduced in the existing
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;bgp_speaker_peer_bindings&lt;/span&gt;&lt;/code&gt; tables.&lt;/p&gt;
&lt;p&gt;New table &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;bgp_peer_group&lt;/span&gt;&lt;/code&gt;  will be created to manage bgp peer group.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Field&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id
name
project_id
remote_asn
update_source_ip&lt;/p&gt;
&lt;p&gt;next_hop_self&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str
String
String
Integer
String&lt;/p&gt;
&lt;p&gt;Boolean&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID of the BGP peer group
Human readable name of the BGP peer group
Owner of the BGP peer group
Remote AS number of a BGP peer group
Forces BGP to use the IP address
specified while talking to a BGP neighbor
decides whether to modify the nexthop
attribute to its own during BGP
advertisement&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;There can be security impacts with the introuduction of peer groups which
support automatic peering requests from peers within a pre-configured
listen-range. This is of major concern if we support this option for external
networks.&lt;/p&gt;
&lt;p&gt;And this problem can be resolved using authentication which will be supported
in peer-groups.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There can be performance impact based on the selection of the implementation
approaches.&lt;/p&gt;
&lt;p&gt;Accurate testing is however needed to understand the overhead.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Manu B &amp;lt;&lt;a class="reference external" href="mailto:manubk2020%40gmail.com"&gt;manubk2020&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt; (IRC: manubk)&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;REST API update.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;BGP plugin, L3 agent extension to handle BGP:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Associate router to bgp speaker&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Disassociate router from bgp speaker.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HA support for BGP speaker&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support new peer group APIs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New attributes for BGP peer APIs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI update.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests and CI related changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit Test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functional test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API test
Perhaps this is something that can be easily tested end-to-end with fullstack
tests. Need more investigation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;New API and changes to legacy APIs like neutron-router and neutron-bgpaas must
be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id11" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://tools.ietf.org/html/rfc4271"&gt;https://tools.ietf.org/html/rfc4271&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://tools.ietf.org/html/rfc4271#section-8"&gt;https://tools.ietf.org/html/rfc4271#section-8&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id13" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron-dynamic-routing/latest"&gt;https://docs.openstack.org/neutron-dynamic-routing/latest&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id14" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.sdxcentral.com/networking/nfv/definitions/virtual-network-function"&gt;https://www.sdxcentral.com/networking/nfv/definitions/virtual-network-function&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id15" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id10"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://opendev.org/openstack/os-ken/src/branch/master/os_ken/services/protocols/bgp/bgpspeaker.py#L225"&gt;https://opendev.org/openstack/os-ken/src/branch/master/os_ken/services/protocols/bgp/bgpspeaker.py#L225&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id16" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/admin/config-bgp-dynamic-routing.html"&gt;https://docs.openstack.org/neutron/latest/admin/config-bgp-dynamic-routing.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id17" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron-dynamic-routing/latest/cli/index.html"&gt;https://docs.openstack.org/neutron-dynamic-routing/latest/cli/index.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id18" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron-dynamic-routing/latest/contributor/testing.html"&gt;https://docs.openstack.org/neutron-dynamic-routing/latest/contributor/testing.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id19" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;9&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.kernel.org/doc/Documentation/networking/vrf.txt"&gt;https://www.kernel.org/doc/Documentation/networking/vrf.txt&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id20" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;10&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/os-ken/latest/library_bgp_speaker_ref.html#os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.rib_get"&gt;https://docs.openstack.org/os-ken/latest/library_bgp_speaker_ref.html#os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.rib_get&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Mon, 06 May 2024 00:00:00 </pubDate></item><item><title>Active-active L3 Gateway with Multihoming</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2024.1/active-active-l3-gateway-with-multihoming.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/2002687"&gt;https://bugs.launchpad.net/neutron/+bug/2002687&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently Neutron routers only support one external gateway port and ECMP
default routes can only be added manually as extra static routes. Likewise,
BFD is not configurable for ECMP routes. This specification provides an
extension to the existing Neutron API for configuring multiple external
gateways with automatic addition of ECMP default routes and BFD for those
routes. It also discusses the problem of scheduling multiple gateway ports per
router on different chassis.  OVN is chosen as a primary backend.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Some network designs include multiple L3 gateways to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Share the load across different gateways: both in terms of different
OVN chassis hosting different gateway ports and sharing the processing
load and upstream gateways handling parts of the north-south flows;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide independent network paths for the north-south direction (e.g. via
different ISPs) for resiliency without relying on the same L2.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Having multi-homing implemented at the instance level imposes additional burden
on the end user of a cloud and support requirements for the guest OS, whereas
utilizing ECMP and BFD at the router side alleviates the need for instance-side
awareness of a more complex routing setup.&lt;/p&gt;
&lt;p&gt;Adding more than one gateway port implies extending the existing data model
which was described in the &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/xena/multiple-external-gateways.html"&gt;multiple external gateways spec&lt;/a&gt;. However, it left
adding additional gateway routes out of scope leaving this to future
improvements around dynamic routing. Also the focus of neutron-dynamic-routing
has so far been around advertising routes, not accepting new ones from the
external peers - so dynamic routing support like this is a very different
subject. However, manual addition of extra routes does not utilize the default
gateway IP information available from subnets in Neutron while this could be
addressed by implementing an extra conditional behavior when adding more than
one gateway port to a router.&lt;/p&gt;
&lt;p&gt;ECMP routes can result in black-holing of traffic if the next-hop of a
route becomes unreachable. &lt;a class="reference external" href="https://www.rfc-editor.org/rfc/rfc5880"&gt;BFD&lt;/a&gt; is a standard protocol adopted by IETF
for next-hop failure detection which can be used for route eviction. OVN
supports BFD &lt;a class="reference external" href="https://github.com/ovn-org/ovn/commit/6e0a69ad4bcdf9e4cace5c73ef48ab06065e8519"&gt;as of v21.03.0&lt;/a&gt; with a data model that allows enabling
BFD on a per next-hop basis by associating BFD session information with routes,
however, it is not modeled at the Neutron level even if a backend supports it.&lt;/p&gt;
&lt;p&gt;Maintaining too many BFD sessions can have a performance impact as periodic
protocol messages are going to consume CPU cycles of a host. The implementation
will aim to minimize the amount of BFD sessions necessary per destination. One
way to do it is to reuse the BFD session information across routers’ default
routes and extra routes if the peer endpoint and the rest of the session
configuration matches. However, care should be taken by operators when it comes
to the amount of routers they would like to use with BFD configured.&lt;/p&gt;
&lt;p&gt;From the Neutron data model perspective, ECMP for routes is already a supported
concept since &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/wallaby/l3-router-support-ecmp.html"&gt;ECMP support spec&lt;/a&gt; got implemented in Wallaby (albeit the
spec focused on the L3-agent based implementation).&lt;/p&gt;
&lt;p&gt;As for OVN and BFD, the OVN database state needs to be populated by Neutron
based on the data from the Neutron database, therefore, data model changes to
the Neutron DB is needed to represent the BFD session parameters.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="db-impact"&gt;
&lt;h3&gt;DB Impact&lt;/h3&gt;
&lt;section id="core-model"&gt;
&lt;h4&gt;Core Model&lt;/h4&gt;
&lt;p&gt;Currently there are two ways in which router to gateway port relationship is
expressed in Neutron:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gw_port_id&lt;/span&gt;&lt;/code&gt; foreign key in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routers&lt;/span&gt;&lt;/code&gt; table which is set to a
UUID of the router port that has a type of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network:router_gateway&lt;/span&gt;&lt;/code&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routerports&lt;/span&gt;&lt;/code&gt; table which was &lt;a class="reference external" href="https://opendev.org/openstack/neutron/commit/93012915a3445a8ac8a0b30b702df30febbbb728"&gt;added for referential integrity&lt;/a&gt;
purposes and stores &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;router_id&lt;/span&gt;&lt;/code&gt; to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port_id&lt;/span&gt;&lt;/code&gt; mappings along with a
redundant &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port_type&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In terms of the representation of multiple gateway ports in the Neutron DB the
proposal follows the &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/xena/multiple-external-gateways.html"&gt;multiple external gateways spec&lt;/a&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Keep the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routers&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routerports&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ports&lt;/span&gt;&lt;/code&gt; tables as they are now
but start storing multiple &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network:router_gateway&lt;/span&gt;&lt;/code&gt; ports per router in the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routerports&lt;/span&gt;&lt;/code&gt; table;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For backwards-compatibility store a single gateway port id in
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routers.gw_port_id&lt;/span&gt;&lt;/code&gt;.  The compatibility gateway port will be stored along
with the other gateway ports in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routerports&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron.db.models.l3.Router&lt;/span&gt;&lt;/code&gt; class with a new attribute
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gw_ports&lt;/span&gt;&lt;/code&gt; that will map to all relevant &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network:router_gateway&lt;/span&gt;&lt;/code&gt; ports
stored in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routerports&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="bfd-and-ecmp-route-behavior-modeling"&gt;
&lt;h4&gt;BFD and ECMP Route Behavior Modeling&lt;/h4&gt;
&lt;p&gt;Each external gateway info dictionary of a router should contain additional
information about the policy around handling of default routes derived from the
subnets associated with the gateway ports of a router. This is needed so that
Neutron as a CMS has the required state to specify to OVN whether ECMP routes
are wanted and whether BFD needs to be enabled for them instead of just
passing those options through at the time of addition of an external gateway
to a router. Therefore, this information needs to be stored along the router.&lt;/p&gt;
&lt;p&gt;The following additional columns are proposed for the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;router_extra_attributes&lt;/span&gt;&lt;/code&gt; table:&lt;/p&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_default_route_ecmp&lt;/span&gt;&lt;/code&gt; is a router-level policy on whether ECMP default
routes should be used or not (if the L3 service plugin supports them).&lt;/p&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_default_route_bfd&lt;/span&gt;&lt;/code&gt; is a router-level policy on whether BFD should be
used for checking whether the next-hop of a default route is reachable (if
the L3 service plugin supports BFD).&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/ovn-org/ovn/blob/v22.12.0/ovn-nb.ovsschema#L612-L636"&gt;OVN modeling of BFD&lt;/a&gt; will be used to implement the support for BFD sessions
for default routes.&lt;/p&gt;
&lt;p&gt;OVN allows making a BFD session for a particular static route to use a
different destination IP for checking reachability rather than the next hop of
the static route itself (by storing the BFD peer IP address in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dst_ip&lt;/span&gt;&lt;/code&gt;
field in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BFD&lt;/span&gt;&lt;/code&gt; table). This is a useful semantic for separating the
control plane and data plane and can be used for static routes of Neutron
routers too. However, when it comes to default routes inferred from gateway
port to subnet associations, Neutron’s behavior should be to use the next hop
of the default route as a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dst_ip&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;OVN models the BFD table as follows (see &lt;a class="reference external" href="https://www.ovn.org/support/dist-docs/ovn-nb.5.txt"&gt;ovn-nb docs&lt;/a&gt; for more information):&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dst_ip&lt;/span&gt;&lt;/code&gt; - a BFD peer IP address;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;min_tx&lt;/span&gt;&lt;/code&gt; - an integer specifying the minimum interval (milliseconds, &amp;gt;=1)
that OVN would use when transmitting the BFD control packet (minus jitter);&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;min_rx&lt;/span&gt;&lt;/code&gt; - an integer specifying the minimum interval (milliseconds)
between the received BFD control packets that OVN is capable of supporting
(minus the jitter applied by the sender). Can be set to 0 to state that
BFD control packet transmission from the BFD peer is not desired;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;detect_mult&lt;/span&gt;&lt;/code&gt; - an integer (&amp;gt;= 1) specifying the detection time multiplier.
The negotiated  transmit  interval, multiplied  by  this  value, provides the
Detection Time for the receiving system in Asynchronous mode.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OVN includes the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;options&lt;/span&gt;&lt;/code&gt; field that includes a map of string-string pairs
which is reserved for future use. A similar field or extra columns can be
added later to the Neutron model to account for additional extensions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The proposed approach for this spec is limited to optionally enabling BFD for
inferred default routes only leaving a more advanced BFD model with per extra
static route BFD sessions for the future iterations (e.g. during the
implementation of the &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/xena/bfd_support.html"&gt;BFD support spec&lt;/a&gt; spec).&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="rest-api-changes"&gt;
&lt;h3&gt;Rest API Changes&lt;/h3&gt;
&lt;section id="router-api"&gt;
&lt;h4&gt;Router API&lt;/h4&gt;
&lt;p&gt;The API changes augment the changes from the &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/xena/multiple-external-gateways.html"&gt;multiple external gateways spec&lt;/a&gt;
but also include additional changes behavioral changes, thus, a different name
for an API extension is used in this specification:
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external-gateway-multihoming&lt;/span&gt;&lt;/code&gt; and API changes are listed here in full.&lt;/p&gt;
&lt;p&gt;New attributes are also added as extra router attributes and the API is
extended to handle those in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;router&lt;/span&gt;&lt;/code&gt; API resource (a separate extension
is added per attribute):&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_default_route_ecmp&lt;/span&gt;&lt;/code&gt; is a router-level policy on whether ECMP
default routes should be used or not (if the L3 service plugin supports
them).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_default_route_bfd&lt;/span&gt;&lt;/code&gt; is a router-level policy on whether BFD should
be used for checking whether the next-hop of a default route is reachable (if
the L3 service plugin supports BFD).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external-gateway-multihoming&lt;/span&gt;&lt;/code&gt; extension a new router API resource
attribute is added called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateways&lt;/span&gt;&lt;/code&gt; which is a list of
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt; structures.&lt;/p&gt;
&lt;p&gt;The first element of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateways&lt;/span&gt;&lt;/code&gt; list is special for
compatibility purposes as it contains the same information as the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt; does. When &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_default_route_ecmp&lt;/span&gt;&lt;/code&gt; is set on
a router to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;false&lt;/span&gt;&lt;/code&gt; it also defines the default gateway placed into the
routers routing table (while the OVN driver currently does not support routing
for the multi-segment network case, the placement of a gateway port would
matter for inferring the default gateway based on the subnet used on a network
segment).&lt;/p&gt;
&lt;p&gt;The order of the rest of the list is ignored.&lt;/p&gt;
&lt;p&gt;Duplicates in the list (that is multiple external gateways with the same
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network_id&lt;/span&gt;&lt;/code&gt;) are allowed: in that case multiple gateway ports will be
attached to the same network (this can be used to have the active-active setup
when external gateways are available on the same network). However, attaching
multiple gateway ports to different networks with overlapping subnet ranges
will cause routing issues, so that kind of overlap is not allowed.&lt;/p&gt;
&lt;p&gt;Updating &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt; also updates the first element of
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateways&lt;/span&gt;&lt;/code&gt; and it leaves the rest of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateways&lt;/span&gt;&lt;/code&gt;
unchanged.  Setting &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt; to an empty value removes a
single (compatibility) gateway from the set of gateway ports of a router and
chooses an existing extra gateway as a replacement for the compatibility
gateway instead.&lt;/p&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateways&lt;/span&gt;&lt;/code&gt; attribute cannot be set in
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/routers&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/routers/{router_id}&lt;/span&gt;&lt;/code&gt; requests,
instead it can be managed via sub-methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/routers/{router_id}/add_external_gateways&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Accepts a list of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt; structures. Adding gateways to
the same network is allowed provided that fixed IPs (if specified) are not
used yet. If one or more gateways are present for a router already then
the first item in the list for addition will become an extra gateway. If none
are present, the first item will be treated as a compatibility gateway.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/routers/{router_id}/update_external_gateways&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Accepts a list of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt; structures.  The external
gateways to be updated are identified by the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network_id&lt;/span&gt;&lt;/code&gt; field and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_fixed_ips&lt;/span&gt;&lt;/code&gt; found in the PUT request. Updating &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_snat&lt;/span&gt;&lt;/code&gt; is
only possible at the per-router basis on the first item specified. Updating
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_fixed_ips&lt;/span&gt;&lt;/code&gt; is possible without recreating a port.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/routers/{router_id}/remove_external_gateways&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Accepts a list of potentially partial &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt;
structures.  A combination of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network_id&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_fixed_ips&lt;/span&gt;&lt;/code&gt;
fields from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt; structure is used to identify
a particular gateway to be removed. Other keys can be present but
their values are ignored.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The add/update/remove PUT sub-methods respond with the whole router
object just as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST/PUT/GET&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/routers&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="extra-routes-api-ecmp"&gt;
&lt;h4&gt;Extra routes API: ECMP&lt;/h4&gt;
&lt;p&gt;As the &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/wallaby/l3-router-support-ecmp.html"&gt;ECMP support spec&lt;/a&gt; notes, there are no API changes to make to support
ECMP routes per se: multiple routes to the same destination and different
next-hops can already be specified when adding extra routes. However, that spec
focused on the agent-based implementation - part of the work to implement this
spec is to check whether the same is true for the OVN-based L3 implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="extra-routes-api-bfd"&gt;
&lt;h4&gt;Extra routes API: BFD&lt;/h4&gt;
&lt;p&gt;In the absence of a full BFD API, users will have an option to specify a policy
on the routers (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_default_route_bfd&lt;/span&gt;&lt;/code&gt;).&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="ovn-driver-changes"&gt;
&lt;h3&gt;OVN driver changes&lt;/h3&gt;
&lt;p&gt;In general, we will update the existing OVN driver to handle the presence of
multiple gateway ports wherever gateway ports are currently handled in the
existing code.  A few areas of interest are highlighted below.&lt;/p&gt;
&lt;section id="router-level-external-ids"&gt;
&lt;h4&gt;Router level External IDs&lt;/h4&gt;
&lt;p&gt;There are a couple of router level external IDs in the existing implementation
which do not work with multiple gateway ports:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;ovn_const.OVN_GW_PORT_EXT_ID_KEY&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ovn_const.OVN_GW_NETWORK_EXT_ID_KEY&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These will be deprecated and replaced by methods that look up the required
information at runtime.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="l3-scheduler-changes"&gt;
&lt;h4&gt;L3 Scheduler Changes&lt;/h4&gt;
&lt;p&gt;One of the main use cases for routers with multiple gateway ports is
resiliency.  Whenever there are multiple gateway ports present for a single
router, we want to ensure diverse placement of these ports across chassis to
minimize impact of chassis failure.&lt;/p&gt;
&lt;p&gt;This will be implemented by updating the &lt;cite&gt;leastloaded&lt;/cite&gt; scheduler to apply
soft anti-affinity when scheduling gateway ports for routers with multiple
gateway ports.&lt;/p&gt;
&lt;p&gt;No changes will be made to the &lt;cite&gt;chance&lt;/cite&gt; scheduler.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="out-of-scope"&gt;
&lt;h2&gt;Out of Scope&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;BFD session data model and API;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;BFD authentication as it is not implemented in the OVN BFD implementation
while it is present in the protocol RFC itself. Therefore, the data model
should be extensible to support this in the future;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enabling BFD for extra routes. For now the spec will only address the
inferred routes leaving this for future iterations;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Solving the distributed SNAT problem.
One direction is to use conntrack state synchronization between the gateway
ports. Other ideas involve making smarter control plane choices about where
this conntrack state should exist instead of distributing it
everywhere - this can be done by ensuring that processing of flows is done
locally to the instance but there are downsides to that as well which needs
to be considered more carefully&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dealing with asymmetric routing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Conntrack can be utilized to avoid responses generated by instances to go
via the route different from the one the request came in on in presence of
ECMP routes. OVN has support for making the reply traffic take the
symmetric path.
This can be configured by utilizing the &lt;a class="reference external" href="https://github.com/ovn-org/ovn/blob/v22.12.0/ovn-nb.ovsschema#L453-L455"&gt;options column&lt;/a&gt; in the logical
router static routes table in OVN which allows configuring
&lt;a class="reference external" href="https://github.com/ovn-org/ovn/blob/v22.12.0/ovn-nb.xml#L3312-L3319"&gt;ECMP symmetric reply&lt;/a&gt; by setting &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ecmp_symmetric_reply&lt;/span&gt;&lt;/code&gt; option to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;true&lt;/span&gt;&lt;/code&gt; (it is modeled at the route level in OVN as well).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Routes in Neutron could have an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ecmp_symmetric_reply&lt;/span&gt;&lt;/code&gt; option to specify
a policy on whether to enable &lt;a class="reference external" href="https://github.com/ovn-org/ovn/blob/v22.12.0/ovn-nb.xml#L3312-L3319"&gt;ECMP symmetric reply&lt;/a&gt; depending on whether
the L3 service plugin supports it or not.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;However, the &lt;a class="reference external" href="https://github.com/ovn-org/ovn/commit/4fdca656857d4a5caeec35ae813888cb9e403e5e"&gt;commit introducing the feature&lt;/a&gt; in OVN notes a limitation on
its use: it can only be used on gateway routers, not distributed routers
that have a gateway port due to the dependency of the ingress pipeline
logic of the logical router on the hypervisor-local CT state.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Accepting ECMP routes via dynamic routing protocols. The current aim is to
utilize the default gateway information available in Neutron subnets to
configure default gateway ECMP routes or to use the extra routes extension.
This specification is a building block for the future support of dynamic
routing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modeling of route metrics. While there are cases where one default route
could be preferred over the other for the same destination, neither Neutron
nor OVN model this concept today;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implementation of BFD for the non-OVN L3 implementation based on Linux
namespaces.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Frode Nordahl &amp;lt;&lt;a class="reference external" href="mailto:frode.nordahl%40canonical.com"&gt;frode&lt;span&gt;.&lt;/span&gt;nordahl&lt;span&gt;@&lt;/span&gt;canonical&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt; (~fnordahl)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dmitrii Shcherbakov &amp;lt;&lt;a class="reference external" href="mailto:dmitrii.shcherbakov%40canonical.com"&gt;dmitrii&lt;span&gt;.&lt;/span&gt;shcherbakov&lt;span&gt;@&lt;/span&gt;canonical&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt; (~dmitriis)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add the new REST API by making neutron-lib and Neutron changes to the API,
core Neutron and OVN integration code;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change the DB schema to add new attributes and create relevant DB migrations;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement support for external-gateway-multihoming extension in the OVN
driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the OVN L3 &lt;cite&gt;leastloaded&lt;/cite&gt; scheduler to apply soft anti-affinity when
scheduling gateway ports for routers with multiple gateway ports.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the CLI in order to utilize the newly added rest API;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the relevant documentation;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement relevant unit and functional tests using the existing facilities
in Neutron.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Wed, 06 Mar 2024 00:00:00 </pubDate></item><item><title>Expose backend hints in the port API, hint ovs-tx-steering</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2023.1/ovs-tx-steering.html</link><description>

&lt;p&gt;RFE: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1990842"&gt;https://bugs.launchpad.net/neutron/+bug/1990842&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Introduce a port attribute that allows passing in backend specific hints
mainly to allow backend specific performance tuning.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Some of our performance sensitive users would like to tweak Open vSwitch’s Tx
packet steering option &lt;a class="footnote-reference brackets" href="#id5" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; under OpenStack.&lt;/p&gt;
&lt;p&gt;This is available since Open vSwitch v2.17.0. &lt;a class="footnote-reference brackets" href="#id6" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, &lt;a class="footnote-reference brackets" href="#id7" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;We propose to introduce two new extension: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port-hints&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port-hint-ovs-tx-steering&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The purpose of decomposing this feature to two extensions is
extensibility: to allow other hints in the future. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port-hints&lt;/span&gt;&lt;/code&gt;
signals the presence of a new port attribute, for details see
below. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port-hint-foobar&lt;/span&gt;&lt;/code&gt; signals what values of the new port attribute
(or which is the same: what hints) are known to a Neutron instance.&lt;/p&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port-hints&lt;/span&gt;&lt;/code&gt; adds a new port attribute: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hints&lt;/span&gt;&lt;/code&gt;.  Its default
policy is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;admin_only&lt;/span&gt;&lt;/code&gt;.  Its value is a dict (by default empty).
The dict is keyed by the standard mechanism driver aliases as in &lt;a class="footnote-reference brackets" href="#id8" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.
This spec allows only a single key: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;openvswitch&lt;/span&gt;&lt;/code&gt;. Other keys for
other mechanism drivers may be introduced by later specs.  The value
for a mechanism_driver is possibly a complex structure, but at least
a dict on the top level.  In this spec we only partially define its
format - introducing one hint. This is marked by the second extension
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port-hint-ovs-tx-steering&lt;/span&gt;&lt;/code&gt;.  Definition of other hints is left to
future specs. Here consider this partial body for a create port request:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"hints"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"openvswitch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"other_config"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"tx-steering"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"thread"&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="s2"&gt;"hash"&lt;/span&gt;&lt;span class="p"&gt;}}}&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Everything in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hints&lt;/span&gt;&lt;/code&gt; is interpreted not as a demand, but as a
suggestion. That is, neutron is free to ignore some or all of the
requested hints without returning an error response or putting the
port into an error status. Particularly neutron is free to ignore the
requested hints when the port is bound by a different mechanism driver.&lt;/p&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hints&lt;/span&gt;&lt;/code&gt; can be set at port create or update, but there’s no guarantee
that an update to the hints after the port was bound will have any effect.&lt;/p&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hints&lt;/span&gt;&lt;/code&gt; is intentionally not named &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding:hints&lt;/span&gt;&lt;/code&gt; and it should
not be affecting the binding process and decision.&lt;/p&gt;
&lt;p&gt;In the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;openstack&lt;/span&gt;&lt;/code&gt; CLI we propose to expose the above API feature as:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;hint&lt;/span&gt; &lt;span class="n"&gt;HINT&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ALIAS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HINT&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;VALUE&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;hint&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="n"&gt;unset&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;hints&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;hint&lt;/span&gt; &lt;span class="n"&gt;ovs&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;steering&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;hint&lt;/span&gt; &lt;span class="n"&gt;ovs&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;steering&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The above CLI syntax allows key:value type hints, and can be extended
to allow boolean hints if needed.  There is an arbitrary but documented
mapping between a HINT-ALIAS=HINT-VALUE and the fully fledged data
structure passed to the API. The openstack CLI also allows an arbitrary
JSON value in the –hint parameter which it passes to the API as-is.&lt;/p&gt;
&lt;p&gt;Given the ovs-tx-steering hint passed in, ovs-agent can set the
corresponding OVS interface’s other_config (using the python native
interface of course, not ovs-vsctl):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;ovs&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vsctl&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="n"&gt;Interface&lt;/span&gt; &lt;span class="n"&gt;ovs&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="n"&gt;other_config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;steering&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;ovs&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vsctl&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="n"&gt;Interface&lt;/span&gt; &lt;span class="n"&gt;ovs&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="n"&gt;other_config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;steering&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The default value of hint &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ovs-tx-steering&lt;/span&gt;&lt;/code&gt; is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;thread&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;section id="api-impact"&gt;
&lt;h3&gt;API Impact&lt;/h3&gt;
&lt;p&gt;Add a new admin_only field to the port resource called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hints&lt;/span&gt;&lt;/code&gt;. This
field can be present in GET, POST and PUT requests. This field cannot be
longer than 4095 characters. For its semantics, please see above.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="db-impact"&gt;
&lt;h3&gt;DB Impact&lt;/h3&gt;
&lt;p&gt;Introduce a new table &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;porthints&lt;/span&gt;&lt;/code&gt; and autojoin it with the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ports&lt;/span&gt;&lt;/code&gt;
table.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="client-impact"&gt;
&lt;h3&gt;Client Impact&lt;/h3&gt;
&lt;p&gt;Relevant changes in osc and openstacksdk.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests in neutron-tempest-plugin.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Bence Romsics &amp;lt;&lt;a class="reference external" href="mailto:bence.romsics%40gmail.com"&gt;bence&lt;span&gt;.&lt;/span&gt;romsics&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openvswitch.org/en/latest/topics/userspace-tx-steering/"&gt;https://docs.openvswitch.org/en/latest/topics/userspace-tx-steering/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openvswitch/ovs/blob/7af5c33c1629b309cbcbe3b6c9c3bd6d3b4c0abf/NEWS#L103"&gt;https://github.com/openvswitch/ovs/blob/7af5c33c1629b309cbcbe3b6c9c3bd6d3b4c0abf/NEWS#L103&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openvswitch/ovs/commit/c18e707b2f259438633af5b23df53e1409472871"&gt;https://github.com/openvswitch/ovs/commit/c18e707b2f259438633af5b23df53e1409472871&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://opendev.org/openstack/neutron/src/commit/31af8d1539c9c88be12c37120a6d43df528349bd/setup.cfg#L98-L112"&gt;https://opendev.org/openstack/neutron/src/commit/31af8d1539c9c88be12c37120a6d43df528349bd/setup.cfg#L98-L112&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 24 Oct 2023 00:00:00 </pubDate></item><item><title>L3/BGP - Allow to configure the BGP peer connect mode</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2024.2/l3bgp-peer-connect-mode.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/2040001"&gt;https://bugs.launchpad.net/neutron/+bug/2040001&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This RFE intends to implement a configuration option to allow the Operator to
change the Neutron Dynamic Routing (n-d-r) speaker’s default BGP connect mode
to all supported modes: ACTIVE, PASSIVE or BOTH.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;When using n-d-r, the speaker’s current behaviour is to work in ACTIVE mode
which will not create a local TCP socket on TCP 179 port. Therefore, in the
switch’s BGP session, it needs to be configured as PASSIVE and not initiate
TCP connections.&lt;/p&gt;
&lt;p&gt;Operators could have a switch brand that does not follow correctly the RFC 4271
&lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; regarding with the BGP FSM (8.2).&lt;/p&gt;
&lt;p&gt;When the n-d-r and the switch has a health BGP session, the Operator could run
a maintenance window in the switch or in the n-d-r agent and the session could
flap and go down for while and on the switch side, the BGP session state can
change to IDLE.&lt;/p&gt;
&lt;p&gt;According to RFC 4271(8.2.2.), when a BGP session is in IDLE state, it refuses
all inbound BGP connection attempts, and starts a TCP connection to the
peer(n-d-r) and n-d-r speaker’s will not answer because n-d-r is in ACTIVE mode
and has no listen port for this. If the switch correctly follow the RFC
regarding BGP PASSIVE mode when enabled, it will ignore it and accept the
incoming connection from the n-d-r and the connection will be restablished,
regardless of the IDLE state.&lt;/p&gt;
&lt;p&gt;That is definitely a switch-side issue but when having this situation, we could
allow the Operator to change the default behaviour of n-d-r speaker’s from
ACTIVE and set it as PASSIVE or BOTH using a n-d-r configuration option and
then open the local TCP socket on the TCP 179 port in order to anwser incoming
TCP connections.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This proposal implements a configuration option to allow the Operator to change
the n-d-r speaker’s default BGP connect mode from ACTIVE to PASSIVE or BOTH.
For Operators who do not have the problem described above, it is not necessary
to change anything as the BGP connection mode will remain as ACTIVE.&lt;/p&gt;
&lt;p&gt;To change the n-d-r speaker’s default BGP connect mode, a new configuration
option should be enabled via [BGP] section in the n-d-r agent configuration
file.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;* ``bgp_connect_mode = both``
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;cite&gt;bgp_connect_mode&lt;/cite&gt; values supported would be:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;active&lt;/cite&gt; initiate the TCP connection to establish the BGP session and do not
require to open a local TCP socket on port 179. The default value for
&lt;cite&gt;bgp_connect_mode&lt;/cite&gt; must be &lt;cite&gt;active&lt;/cite&gt; to keep the current behaviour.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;passive&lt;/cite&gt; open a local TCP socket on port 179 and wait for an incoming TCP
connection from the BGP peer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;both&lt;/cite&gt; open a local TCP socket on port 179 and wait for an incoming TCP
connection from the BGP peer. Additionally, a connection could be initiated
to establish the BGP session with the peer.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="neutron-dynamic-routing-impact"&gt;
&lt;h3&gt;Neutron Dynamic Routing Impact&lt;/h3&gt;
&lt;p&gt;When the n-d-r agent is started:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;if the option &lt;cite&gt;bgp_connect_mode&lt;/cite&gt; is ommited or has the value &lt;cite&gt;active&lt;/cite&gt; the BGP
connection mode will remain as ACTIVE and it will not create a local TCP
socket on port 179.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;if the option &lt;cite&gt;bgp_connect_mode&lt;/cite&gt; has the value &lt;cite&gt;passive&lt;/cite&gt; the BGP connection
mode will be used as PASSIVE and a local TCP socket on port 179 will be
opened.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;if the option &lt;cite&gt;bgp_connect_mode&lt;/cite&gt; has the value &lt;cite&gt;both&lt;/cite&gt; the BGP connection mode
will be used as BOTH and a local TCP socket on port 179 will be opened.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Because n-d-r could start the agent as an unprivileged user, systemd will
require for the n-d-r agent service to have net bind capability to allow for
creation of the local TCP socket on port 179.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;The Operator will have to ensure the safety of the n-d-r agent when using
&lt;cite&gt;bgp_connect_mode&lt;/cite&gt; as &lt;cite&gt;passive&lt;/cite&gt; or &lt;cite&gt;both&lt;/cite&gt;, and create local firewall rules to
only allow incoming TCP connection from BGP peers.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignees:
* Tiago Pires &amp;lt;&lt;a class="reference external" href="mailto:tiagohp%40gmail.com"&gt;tiagohp&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;
* Roberto Bartzen Acosta &amp;lt;&lt;a class="reference external" href="mailto:rbartzen%40gmail.com"&gt;rbartzen&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement a new configuration option.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement relevant unit and functional tests using the existing facilities
in Neutron Dynamic Routing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit/functional tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Information about the &lt;cite&gt;bgp_connect_mode&lt;/cite&gt; configuration option.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://datatracker.ietf.org/doc/html/rfc4271"&gt;https://datatracker.ietf.org/doc/html/rfc4271&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 24 Oct 2023 00:00:00 </pubDate></item><item><title>L3/BGP - Make BGP Speaker peer sessions resilient to infrastructure outage</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2024.2/l3bgp-resilient-peer-sessions.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/2006145"&gt;https://bugs.launchpad.net/neutron/+bug/2006145&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This RFE intends to implement resilient support for BGP peer sessions
established by the BGP speaker. Nowadays, the Neutron Dynamic Routing service
architecture depends on some type of message between the DRAgent service and
the Neutron server. However, these communications are strongly dependent on the
messaging service availability (such as RabbitMQ), and any transient/permanent
failures in OpenStack infrastructure nodes may affect prefix advertising via
BGP.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;When we are using dynamic routing with BGP to advertise network address
prefixes in a cloud infrastructure, all the network traffic depends on the
correct operation by the BGP peer elements. The DRAgent has a crucial role in
that scenario because this service is responsible for advirtise all L3 prefixes
in a North/South communication, being a single point of vulnerability for the
cloud operation.&lt;/p&gt;
&lt;p&gt;The current DRAgent reference design &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; using two separated periodic tasks as
described below:&lt;/p&gt;
&lt;p&gt;State Report periodic task (DrAgentWithStateReport class):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;+------------------------------------------------+
|DrAgentWithStateReport class                    |
|                                                |
|     +------------------------------------+     |
|     |heartbeat = _report_state           |     |
|     |interval=CONF.AGENT.report_interval |     |
|     |  call _report_state                |     |
|     +------------------+-----------------+     |
|                        |                       |
|     +------------------+-----------------+     |
|     |_report_state polling task          |     |
|     |                                    |     |
|     | RPC processing                     |     |
|     |   if agent_status == revived       |     |
|     |     call schedule_full_resync      |     |
|     +------------------+-----------------+     |
|                        |                       |
|     +------------------+-----------------+     |
|     |schedule_full_resync                |     |
|     +------------------------------------+     |
|                                                |
+------------------------------------------------+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;BGP DRAgent periodic task (BgpDrAgent class):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;+---------------------------------------+
|BgpDrAgent class                       |
|                                       |
|   +-------------------------------+   |
|   |periodic_resync polling task   |   |
|   |interval=CONF.periodic_interval|   |
|   |  call _periodic_resync_helper |   |
|   +---------------+---------------+   |
|                   |                   |
|   +---------------+---------------+   |
|   |_periodic_resync_helper        |   |
|   | if full_sync or resync/reason |   |
|   |   call sync_state             |   |
|   +---------------+---------------+   |
|                   |                   |
|   +---------------+---------------+   |
|   |sync_state                     |   |
|   |                               |   |
|   | if bgp_speaker_id == None     |   |
|   |   remove speaker from DRAgent |   |
|   |                               |   |
|   | Exception (MessagingTimeout)  |   |
|   |   call schedule_full_resync   |   |
|   +--------------+----------------+   |
|                  |                    |
|   +--------------+----------------+   |
|   |schedule_full_resync           |   |
|   +-------------------------------+   |
|                                       |
+---------------------------------------+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;These two periodic tasks have independently configured &lt;cite&gt;interval&lt;/cite&gt; ranges, the
&lt;cite&gt;periodic_interval&lt;/cite&gt; for BGP DRAgent task, and the &lt;cite&gt;AGENT.report_interval&lt;/cite&gt;
for the heartbeat report state. However, a full resync request can come from
both periodic tasks, and the sync_state method will be processed. The case of
the RPC heartbeat response with agent_status &lt;cite&gt;revived&lt;/cite&gt; activates this entire
flow described above until the speaker is removed from the DRAgent. For the
case where an &lt;cite&gt;exception&lt;/cite&gt; occurs in the sync_state method, a full resync is
scheduled (according to the flow described above) until the speaker is removed
from the DRAgent.&lt;/p&gt;
&lt;p&gt;Regardless of the origin of the full resync request, the caching mechanism
apparently is not working, as the agent was previously configured and after
receiving a &lt;cite&gt;revived&lt;/cite&gt; status via RPC it simply removes the speaker from the
DRAgent, and reschedules a future resync to later be re-included (depending on
the configured periodic intervals). When the speaker is removed from DRAgent
the BGP peer sessions are closed and will only be reestablished if the speaker
is re-added.&lt;/p&gt;
&lt;p&gt;This problem can be manifested in two different ways:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;When the messaging service/RabbitMQ is offline and does not respond for a
long interval &lt;cite&gt;AMQP server is unreachable&lt;/cite&gt; (note the timeouts configured for
Neutron agent_down); and then RMQ/RPC becomes active again.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When the messaging service/RabbitMQ queues are under a lot of pressure and/or
experiencing &lt;cite&gt;exception&lt;/cite&gt; timeouts, such as: &lt;cite&gt;Timed out waiting for a reply&lt;/cite&gt;;
and then RMQ/RPC becomes active again.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;To solve the problem described above, the proposal is to introduce a new
speaker cache logic for the DRAgent can keep the speaker settings and the BGP
peer sessions in case of RPC Exceptions, and/or reestablishment of
communication via RPC. In addition, to not remove the BGP speaker configuration
from DRAgent due to transient failures in RPC communication, it is required to
change the &lt;cite&gt;get_bgp_speakers&lt;/cite&gt; empty returns handling logic to first schedule a
full sync, and then allow the BGP speaker to be removed in the next periodic
sync.&lt;/p&gt;
&lt;p&gt;To enable the new DRAgent speaker cache mechanism, a new config option should
be enabled via [BGP] section in bgp_dragent.ini file.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;* ``speaker_cache_timeout = 300``
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This configuration option enable the DRAgent to keep the speaker settings and
related BGP peer sessions until the configured timeout (in seconds). The
purpose of this timeout cache is prevent errors in the resync checking logic
so that no speaker removed until the timeout condition is satisfied.&lt;/p&gt;
&lt;p&gt;The default value for &lt;cite&gt;speaker_cache_timeout&lt;/cite&gt; must be zero and thus maintain
the current DRAgent behavior. Any non-zero value should affect DRAgent behavior
as described below:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;State Report periodic task: with the &lt;cite&gt;revived&lt;/cite&gt; RPC status, the DRAgent must
be start the cache timeout timer, and set the &lt;cite&gt;cache_out_of_sync&lt;/cite&gt; flag as
True. If the DRAgent performs the sync_state method before the
&lt;cite&gt;cache_out_of_sync&lt;/cite&gt; becomes to False, then the full sync process must be
ignored, and wait for the next periodic check.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DRAgent periodic task: if the sync_state method throws any &lt;cite&gt;exception&lt;/cite&gt; during
operation, the DRAgent must be start the cache timeout timer, and set the
&lt;cite&gt;cache_out_of_sync&lt;/cite&gt; flag as True. Similar to the case described above, if the
DRAgent performs the sync_state method before the &lt;cite&gt;cache_out_of_sync&lt;/cite&gt; becomes
to False, then the full sync process must be ignored, and wait for the next
periodic check.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cache timeout task: if another &lt;cite&gt;revived&lt;/cite&gt; or &lt;cite&gt;Exception&lt;/cite&gt; event occurs during
the timer count, the cache task must reset the timeout interval count and
start again. Otherwise, the cache task must terminate at the expiry of the
configured timeout, and set the &lt;cite&gt;cache_out_of_sync&lt;/cite&gt; flag to False.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Default workflow: If the &lt;cite&gt;speaker_cache_timeout&lt;/cite&gt; is empty or set to zero; or
if the configured cache timeout timer has expired - &lt;cite&gt;cache_out_of_sync&lt;/cite&gt; flag
is False; any periodic task should be run a full resync.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="db-impact"&gt;
&lt;h3&gt;DB Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-changes"&gt;
&lt;h3&gt;Rest API Changes&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Primary assignees:
Roberto Bartzen Acosta &amp;lt;&lt;a class="reference external" href="mailto:rbartzen%40gmail.com"&gt;rbartzen&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement a new cache logic in DRAgent speaker resync.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement relevant unit and functional tests using the existing facilities
in Neutron Dynamic Routing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Information about the DRAgent speaker caching support.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit/functional tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://opendev.org/openstack/neutron-dynamic-routing/src/branch/master/neutron_dynamic_routing/services/bgp/agent/bgp_dragent.py"&gt;https://opendev.org/openstack/neutron-dynamic-routing/src/branch/master/neutron_dynamic_routing/services/bgp/agent/bgp_dragent.py&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 24 Oct 2023 00:00:00 </pubDate></item><item><title>Flavor/service provider support for routers in the ML2/OVN L3 plugin</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2023.2/ml2ovn-router-flavors.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/2020823"&gt;https://bugs.launchpad.net/neutron/+bug/2020823&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In &lt;a class="reference external" href="https://review.opendev.org/q/topic:bp%252Fmulti-l3-backends"&gt;Multiple L3 backends&lt;/a&gt;, functionality was added to the ML2/OVS mechanism
driver to support L3 routers implemented by different back-end drivers.
Recently, OpenStack deployers in the Telco / 5G industry have expressed a
strong interest to have the same support with the ML2/OVN mechanism driver.
This specification proposes to implement that functionality.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Since early in the development of Neutron, the community recognized the need to
provide frameworks to enable operators and users of a cloud deployment to
configure and select from a set of options different implementations of
services such as VPNs, firewalls, routers, etc. This has led over the years to
proposals and additions to Neutron such as &lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/ServiceTypeFramework"&gt;Neutron/Service Type Framework&lt;/a&gt;,
&lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/liberty/neutron-flavor-framework.html"&gt;Service Flavor Framework&lt;/a&gt; and the aforementioned &lt;a class="reference external" href="https://review.opendev.org/q/topic:bp%252Fmulti-l3-backends"&gt;Multiple L3 backends&lt;/a&gt;.
All this is represented in the API by &lt;a class="reference external" href="https://docs.openstack.org/api-ref/network/v2/index.html#networking-flavors-framework-v2-0-current-flavor-service-profile"&gt;Networking Flavors Framework&lt;/a&gt;,
&lt;a class="reference external" href="https://docs.openstack.org/api-ref/network/v2/index.html#service-providers"&gt;Service Providers&lt;/a&gt; and the &lt;a class="reference external" href="https://docs.openstack.org/api-ref/network/v2/index.html#l3-flavors-extension-l3-flavors"&gt;L3 flavors extension&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As of the writing of this specification, operators using ML2/OVN cannot take
advantage of all these existing frameworks to offer different implementations
(flavors from here on) of vrouters to their users. As a consequence, Neutron
cannot serve a use case where Telco operators want to provide at the same time
different grades of vrouters, such as:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;OVN vrouters for their IT / back-office workloads.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Specialized vrouters outside OVN for their 5G mobile networks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Specialized vrouters outside OVN for their 4G mobile networks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other types of specialized vrouters.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposal is to add to the ML2/OVN L3 plugin the ability to process
different flavors of vrouters. The default flavor will be the native OVN
vrouter.&lt;/p&gt;
&lt;p&gt;To achieve this, all the OVN specific functionality in the ML2/OVN L3 plugin
related to vrouters and floating IPs will be refactored to a separate driver.
Once this is done, the L3 plugin will be responsible for performing only the
Neutron DB processing steps related to vrouters and floating IPs, while letting
separate drivers to take care of all the backend processing. These drivers will
listen and act on events notifications sent by the refactored L3 plugin for the
creation, update and deletion of vrouters and floating IPs. Each driver will be
responsible to act only on those events that pertain to its flavor.&lt;/p&gt;
&lt;p&gt;Cloud administrators will configure, load and associate with flavor names
drivers for backends different to OVN. The following diagram illustrates the
proposed scenario:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+--------+&lt;/span&gt;          &lt;span class="o"&gt;+------------+&lt;/span&gt;               &lt;span class="o"&gt;+------------+&lt;/span&gt;    &lt;span class="o"&gt;+------+&lt;/span&gt;    &lt;span class="o"&gt;+------+&lt;/span&gt;    &lt;span class="o"&gt;+-----------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;Event&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|---&amp;gt;|&lt;/span&gt; &lt;span class="n"&gt;NBDB&lt;/span&gt; &lt;span class="o"&gt;|---&amp;gt;|&lt;/span&gt; &lt;span class="n"&gt;SBDB&lt;/span&gt; &lt;span class="o"&gt;|---&amp;gt;|&lt;/span&gt; &lt;span class="n"&gt;OVN&lt;/span&gt; &lt;span class="n"&gt;Controllers&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Notifications&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Driver&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;+------+&lt;/span&gt;    &lt;span class="o"&gt;+------+&lt;/span&gt;    &lt;span class="o"&gt;+-----------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|--------------&amp;gt;|&lt;/span&gt; &lt;span class="n"&gt;flavor&lt;/span&gt; &lt;span class="n"&gt;OVN&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;+------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;+------------+&lt;/span&gt;    &lt;span class="o"&gt;+-----------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;Event&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|---&amp;gt;|&lt;/span&gt; &lt;span class="n"&gt;Backend&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;ReST&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Requests&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;L3&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Notifications&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Driver&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;+-----------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;API&lt;/span&gt;   &lt;span class="o"&gt;|---------&amp;gt;|&lt;/span&gt;   &lt;span class="n"&gt;plugin&lt;/span&gt;   &lt;span class="o"&gt;|--------------&amp;gt;|&lt;/span&gt;  &lt;span class="n"&gt;flavor&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;+------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;+------------+&lt;/span&gt;    &lt;span class="o"&gt;+-----------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;Event&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|---&amp;gt;|&lt;/span&gt; &lt;span class="n"&gt;Backend&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Notifications&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Driver&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;+-----------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|--------------&amp;gt;|&lt;/span&gt;  &lt;span class="n"&gt;flavor&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------+&lt;/span&gt;          &lt;span class="o"&gt;+------------+&lt;/span&gt;               &lt;span class="o"&gt;+------------+&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;                             &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+-------------+&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
                  &lt;span class="n"&gt;Updates&lt;/span&gt; &lt;span class="o"&gt;+------&amp;gt;|&lt;/span&gt;   &lt;span class="n"&gt;Neutron&lt;/span&gt;   &lt;span class="o"&gt;|&amp;lt;------+&lt;/span&gt; &lt;span class="n"&gt;Reads&lt;/span&gt;
                                  &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;database&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
                                  &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
                                  &lt;span class="o"&gt;+-------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In this diagram, backend means any combinations of agents and databases
(outside the purview of Neutron) that a driver needs to instantiate routers and
floating IPs in the data plane. This specification implementation will include
a driver for OVN and the necessary scaffolding to enable other drivers to be
configured in a Neutron deployment, but the drivers themselves and their
associated databases and agents will be provided by third parties.&lt;/p&gt;
&lt;p&gt;Once drivers are configured, users will specify the required flavor when
creating vrouters. The OVN flavor will be the default and will be denoted by
specifying no flavor in the create request. The following commands illustrate
how to create a thrid party flavor vrouter:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ openstack network flavor list
+--------------------------------------+----------------------------+---------+---------------+------------------------------------------------------+
| ID                                   | Name                       | Enabled | Service Type  | Description                                          |
+--------------------------------------+----------------------------+---------+---------------+------------------------------------------------------+
| e47c1c5c-629b-4c48-b49a-78abe6ac7696 | user-defined-router-flavor | True    | L3_ROUTER_NAT | User defined flavor for routers in the L3 OVN plugin |
+--------------------------------------+----------------------------+---------+---------------+------------------------------------------------------+

$ openstack router create router-of-user-defined-flavor --flavor e47c1c5c-629b-4c48-b49a-78abe6ac7696
+-------------------------+--------------------------------------+
| Field                   | Value                                |
+-------------------------+--------------------------------------+
| admin_state_up          | UP                                   |
| availability_zone_hints |                                      |
| availability_zones      |                                      |
| created_at              | 2023-06-08T20:26:01Z                 |
| description             |                                      |
| enable_ndp_proxy        | None                                 |
| external_gateway_info   | null                                 |
| flavor_id               | e47c1c5c-629b-4c48-b49a-78abe6ac7696 |
| id                      | fe110d50-f994-4593-86a4-fc2ecca34c38 |
| name                    | router-of-user-defined-flavor        |
| project_id              | b807321af03f44dc808ff06bbc845804     |
| revision_number         | 1                                    |
| routes                  |                                      |
| status                  | ACTIVE                               |
| tags                    |                                      |
| tenant_id               | b807321af03f44dc808ff06bbc845804     |
| updated_at              | 2023-06-08T20:26:01Z                 |
+-------------------------+--------------------------------------+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As of the writing of this specification, the openstack client doesn’t allow the
specification of a flavor ID when creating a vrouter. Adding this functionality
to the client will be part of this specification’s implementation.&lt;/p&gt;
&lt;p&gt;The OVN flavor driver will be loaded by default when the L3 plugin starts.
This is an example of the steps a cloud administrator will follow to configure
and load drivers for other flavors:&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Add the service provider to neutron.conf:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;service_providers&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;service_provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;L3_ROUTER_NAT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;defined&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ovn_l3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;service_providers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_defined&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserDefined&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Re-start the neutron server and verify the user defined provider has been
loaded:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ openstack network service provider list
+---------------+--------------+---------+
| Service Type  | Name         | Default |
+---------------+--------------+---------+
| L3_ROUTER_NAT | user-defined | False   |
| L3_ROUTER_NAT | ovn          | True    |
+---------------+--------------+---------+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a service profile for the router flavor:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ openstack network flavor profile create --description "User defined router flavor profile" --enable --driver neutron.services.ovn_l3.service_providers.user_defined.UserDefined
+-------------+--------------------------------------------------------------------+
| Field       | Value                                                              |
+-------------+--------------------------------------------------------------------+
| description | User defined router flavor profile                                 |
| driver      | neutron.services.ovn_l3.service_providers.user_defined.UserDefined |
| enabled     | True                                                               |
| id          | a717c92c-63f7-47e8-9efb-6ad0d61c4875                               |
| meta_info   |                                                                    |
| project_id  | None                                                               |
+-------------+--------------------------------------------------------------------+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create the router flavor:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ openstack network flavor create --service-type L3_ROUTER_NAT --description "User defined flavor for routers in the L3 OVN plugin" user-defined-router-flavor
+---------------------+------------------------------------------------------+
| Field               | Value                                                |
+---------------------+------------------------------------------------------+
| description         | User defined flavor for routers in the L3 OVN plugin |
| enabled             | True                                                 |
| id                  | e47c1c5c-629b-4c48-b49a-78abe6ac7696                 |
| name                | user-defined-router-flavor                           |
| service_profile_ids | []                                                   |
| service_type        | L3_ROUTER_NAT                                        |
+---------------------+------------------------------------------------------+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add service profile to router flavor:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ openstack network flavor add profile user-defined-router-flavor a717c92c-63f7-47e8-9efb-6ad0d61c4875
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;No REST API impact is expected.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="db-impact"&gt;
&lt;h3&gt;DB Impact&lt;/h3&gt;
&lt;p&gt;No DB impact is expected.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Miguel Lavalle irc: mlavalle, email: &lt;a class="reference external" href="mailto:mlavalle%40redhat.com"&gt;mlavalle&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Re-factor the OVN vrouters and floating IPs (NAT) functionality embedded in
the L3 plugin to a separate driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement a drivers controller for the L3 plugin that will load automatically
the driver for OVN routers and floating IPs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the the ML2/OVN maintenance task so vrouters of third party flavors
are not synched with the NBDB.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add functionality to the openstack client to enable users to specify a flavor
when creating a vrouter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Provided inline in the text above.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 05 Jun 2023 00:00:00 </pubDate></item><item><title>Configurable Security Group rules added by default to the new Security Groups</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2023.2/configurable-default-sg-rules.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1983053"&gt;https://bugs.launchpad.net/neutron/+bug/1983053&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;For every project, Neutron always creates security group called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default&lt;/span&gt;&lt;/code&gt;. It
is created always when first time security groups are going to be used or
requested to be listed via API. For each of such &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default&lt;/span&gt;&lt;/code&gt; security group
Neutron automatically creates 4 hardcoded rules. Those rules allow:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;all &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;IPv4&lt;/span&gt;&lt;/code&gt; egress traffic from the port,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;all &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;IPv6&lt;/span&gt;&lt;/code&gt; egress traffic from the port,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;all &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;IPv4&lt;/span&gt;&lt;/code&gt; ingress traffic to the port incoming from other ports which are
using the same security group,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;all &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;IPv6&lt;/span&gt;&lt;/code&gt; ingress traffic to the port incoming from other ports which are
using the same security group.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For any other security group created by user, Neutron automatically creates 2
rules which allows:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;all &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;IPv4&lt;/span&gt;&lt;/code&gt; egress traffic from the port,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;all &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;IPv6&lt;/span&gt;&lt;/code&gt; egress traffic from the port,&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There is at least couple of issues with such approach:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;it is a known fact that the security group rules with remote_group_id (rule 3.
and 4. above) don’t scale well e.g. with neutron-openvswitch-agent &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;some operators would like to define different rules to be created by
default for each new project.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, those rules created by default by Neutron can be easily removed by
the security group owner, but having possibility to define different set of
rules added automatically to each security group could make it easier for users
and administrators of the cloud.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;To solve the problem described above, proposal is to introduce new API to create
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;security&lt;/span&gt; &lt;span class="pre"&gt;group&lt;/span&gt; &lt;span class="pre"&gt;rules&lt;/span&gt; &lt;span class="pre"&gt;template&lt;/span&gt;&lt;/code&gt; used to create new security group rules for
each new security group.
To keep backward compatibility with the existing hardcoded rules, by default
Neutron will have configured the same 4 rules as are hardcoded today (see above
for defails). Cloud admin will be able to delete those rules and create new ones
which will be then used by Neutron for every new security group.
In case when list of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default_security_group_rule&lt;/span&gt;&lt;/code&gt; is empty, new security
groups will be created without any rules created by default.&lt;/p&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;New API resource called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default_security_group_rule&lt;/span&gt;&lt;/code&gt; will be introduced.
Details of the API are below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/default-security-group-rules&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;List default security group rules used to create rules for every new
Security Group&lt;/p&gt;
&lt;p&gt;Response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"default_security_group_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"egress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"ethertype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"IPv6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"3c0e45ff-adaf-4124-b083-bf390e5482ff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"port_range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"port_range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_ip_prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"used_in_default_security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"used_in_non_default_security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"egress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"ethertype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"IPv4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"93aa42e5-80db-4581-9391-3a608bd0e448"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"port_range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"port_range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_ip_prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"used_in_default_security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"used_in_non_default_security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ingress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"ethertype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"IPv6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"3c0e45ff-adaf-4124-b083-bf390e5482ff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"port_range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"port_range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"PARENT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_ip_prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"used_in_default_security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"used_in_non_default_security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ingress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"ethertype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"IPv4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"93aa42e5-80db-4581-9391-3a608bd0e448"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"port_range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"port_range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"PARENT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_ip_prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"used_in_default_security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"used_in_non_default_security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ingress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"ethertype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"IPv6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"3c0e45ff-adaf-4124-b083-bf390e5482ff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"port_range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"port_range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_ip_prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"used_in_default_security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"used_in_non_default_security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Allow SSH connections over IPv6"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ingress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"ethertype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"IPv4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"3c0e45ff-adaf-4124-b083-bf390e5482ff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"port_range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"port_range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"remote_ip_prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"used_in_default_security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"used_in_non_default_security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Allow SSH connections over IPv4"&lt;/span&gt;
  &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/default-security-group-rules&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Create default security group rule used to create rules for every new
Security Group&lt;/p&gt;
&lt;p&gt;Request:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"default_security_group_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ingress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"port_range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"80"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"ethertype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"IPv4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"port_range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"80"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"default_security_group_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ingress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"ethertype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"IPv4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2bc0accf-312e-429a-956e-e4407625eb62"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"port_range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"port_range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"remote_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"remote_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"remote_ip_prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"used_in_default_security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"used_in_non_default_security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/default-security-group-rules/{rule_id}&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Show default security group rule used to create rules for every new
Security Group&lt;/p&gt;
&lt;p&gt;Response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"security_group_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"egress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"ethertype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"IPv6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"3c0e45ff-adaf-4124-b083-bf390e5482ff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"port_range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"port_range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"remote_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"remote_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"remote_ip_prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"used_in_default_security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"used_in_non_default_security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DELETE&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/default-security-group-rules/{rule_id}&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Delete default security group rule used to create rules for every new
Security Group&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="db-impact"&gt;
&lt;h3&gt;DB Impact&lt;/h3&gt;
&lt;p&gt;Default security group rule DB table:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Id of default security group rule.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;direction&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Direction in which the security group
rule is applied.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;ethertype&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Must be IPv4 or IPv6.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;remote_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The remote group UUID to associate
with this security group rule.
Special value &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PARENT&lt;/span&gt;&lt;/code&gt; can be also
used and it means to always use
id of the security group in which
will be created with such rule.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;remote_address_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The remote address group UUID to
associate with this security group
rule.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;protocol&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The IP protocol can be represented by
a string, an integer, or null.
Valid strings or integers are the
same as for the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;security&lt;/span&gt; &lt;span class="pre"&gt;group&lt;/span&gt; &lt;span class="pre"&gt;rule&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;port_range_min&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The minimum port number in the
range that is matched by the security
group rule.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;port_range_max&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The maximum port number in the
range that is matched by the security
group rule.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;remote_ip_prefix&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The remote IP prefix that is matched
by this security group rule.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;standard_attr_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Ingeger&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Id of the associated standard
attribute record.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;used_in_default_sg&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Boolean&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;If it is set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt; such rule
will be used in a template for the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default&lt;/span&gt;&lt;/code&gt; security group which is
created automatically for every
project. Default value is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;False&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;used_in_non_default_sg&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Boolean&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;If it is set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt; such rule
will be used in a template for the
every &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;non&lt;/span&gt; &lt;span class="pre"&gt;default&lt;/span&gt;&lt;/code&gt; security group.
Default value is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;False&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;New API will be by default available only for the admin users.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Slawek Kaplonski &amp;lt;&lt;a class="reference external" href="mailto:skaplons%40redhat.com"&gt;skaplons&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt; (IRC: slaweq)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;REST API update.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB schema update.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security Group DB code update.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI update.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests and CI related changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit Test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API test&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;New API must be documented in the Neutron API reference document.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.opendev.org/p/openstack-networking-train-ptg#L348"&gt;https://etherpad.opendev.org/p/openstack-networking-train-ptg#L348&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Thu, 18 May 2023 00:00:00 </pubDate></item><item><title>Port extension to create hardware offloaded ports</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2023.2/hardware-offload-port-extension.html</link><description>

&lt;p&gt;Launchpad bug: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/2013228"&gt;https://bugs.launchpad.net/neutron/+bug/2013228&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The aim of the RFE is to create a new port extension to allow to create ports
with hardware offloaded capabilities.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The RFE &lt;a class="footnote-reference brackets" href="#id9" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; introduced the capability of creating a port that could use the
hardware offload support implemented in Open vSwitch &lt;a class="footnote-reference brackets" href="#id10" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. This feature was
implemented in the following set of patches (initially for ML2/OVS): &lt;a class="footnote-reference brackets" href="#id11" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;,
&lt;a class="footnote-reference brackets" href="#id12" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and &lt;a class="footnote-reference brackets" href="#id13" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In order to create a port with hardware offload capabilities, it is needed to
define the VNIC type and set a specific value in the port binding profile:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;vnic&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="n"&gt;direct&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="s1"&gt;'{"capabilities": ["switchdev"]}'&lt;/span&gt; &lt;span class="n"&gt;port_hwol&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This method to create a port has several drawbacks:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The port binding profile field is an admin only parameter by default.
The values contained in this field can have references to PCI addresses of
the host and should not be modified by a non-admin user.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Actually this parameter should not be written by Neutron, only by Nova when
the port is bound.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This RFE proposes to create a new port extension, called
“port-hardware-offload”, that will replace the need of manually defining the
port binding profile information when creating the port; please note that
this is referring only to the port creation process. This API extension
consists of a string parameter that will be “None” by default. This string
will be the hardware offload type; OpenStack Neutron and Nova are currently
supporting only “switchdev” &lt;a class="footnote-reference brackets" href="#id14" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. The strings allowed by the API will be
limited to a set of defined constants.&lt;/p&gt;
&lt;p&gt;This new string parameter will be passed to Nova along with the port
information dictionary. Nova will use this parameter instead of the port
binding profile information to command &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-vif&lt;/span&gt;&lt;/code&gt; to create the
corresponding layer 1 port (a devlink port &lt;a class="footnote-reference brackets" href="#id11" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id15" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Because of this Nova-Neutron communication, this RFE is going to be implemented
in two steps:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The first one will implement only the Neutron and OSC (plus the OpenstackSDK
bits) code. The port dictionary passed to Nova will contain both the new
parameter added in this RFE and the port binding profile, that will be added
internally by Neutron when the new paramter is not “None”.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The second step involves the Nova implementation. This change implies that
Nova can read the port new parameter and create the corresponding port. The
port binding profile information passed by Neutron will be irrelevant.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The scope of this RFE, as discussed during the presentation of this new
feature in the Neutron drivers meeting, involves only the first step. The
Nova code change will be covered in other RFE and spec.&lt;/p&gt;
&lt;/div&gt;
&lt;section id="client-impact"&gt;
&lt;h3&gt;Client Impact&lt;/h3&gt;
&lt;p&gt;The OSC and OpenstackSDK projects will be updated in order to be able to create
a port using this new extension. Port creation example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;vnic&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="n"&gt;direct&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;hardware&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;offload&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="n"&gt;switchdev&lt;/span&gt; &lt;span class="n"&gt;port_hwol&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The new string field will be visible when showing the port resource.&lt;/p&gt;
&lt;p&gt;This spec is not covering the Nova migration from reading the port binding
profile to using the new parameter provider in the port definition. As
commented in the first section, Neutron will still populate the port binding
profile as long as the “hardware-offload-type” is provided in the port
creation command. In order to stop users to create a port with the old
method, the OSC will check if the “capabilities” key is provided inside the
port binding profile and a warning will be printed in the command line,
encouraging the user to create the port using the “hardware-offload-type”
parameter.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Proposed attribute:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;COLLECTION_NAME&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"hardware_offload_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;converters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;VALID_HWOL_TYPES&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Sample REST calls:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ports&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="o"&gt;...&lt;/span&gt;
       &lt;span class="s2"&gt;"hardware_offload_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"switchdev"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="s2"&gt;"hardware_offload_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"switchdev"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;This RFE proposes to create a child table to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ports&lt;/span&gt;&lt;/code&gt;, called
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port_hardware_offload&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;table class="docutils align-default" id="id16"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;&lt;strong&gt;Port hardware offload&lt;/strong&gt;&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;port_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the port object&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;hardware_offload_type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String to indicate the hardware
offload type&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;By default, this new field will be writable by the admin only. However, the
admin can consider changing the rule owner and allow any project user to create
a port defining this parameter:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DocumentedRuleDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'create_port:hardware_offload_type'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;check_str&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ADMIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;scope_types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'project'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;operations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ACTION_POST&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This rule change was completely discouraged for the rule
‘create_port:binding:profile’ for the reasons provided in the problem
description.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The port resource view will now require a new “JOIN” operation between the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ports&lt;/span&gt;&lt;/code&gt; table and the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ports_hardware_offload&lt;/span&gt;&lt;/code&gt; table when building the
port OVO. However there will be a 1:1 relationship between both tables and the
data retrieved from the child table is minimal (two columns).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-impact"&gt;
&lt;h3&gt;Other Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignees:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Rodolfo Alonso Hernandez &amp;lt;&lt;a class="reference external" href="mailto:ralonsoh%40redhat.com"&gt;ralonsoh&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt; (IRC: ralonsoh)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;API implementation (neutron-lib and Neutron).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Database migration (Neutron)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI implementation (OpenstackSDK and OSC)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests and CI related changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit/functional tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fullstack API tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Document the new way to create hardware offload ports and deprecate the older
method.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id9" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;[RFE] SR-IOV accelerated OVS integration
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1627987"&gt;https://bugs.launchpad.net/neutron/+bug/1627987&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://mail.openvswitch.org/pipermail/ovs-dev/2017-April/330606.html"&gt;https://mail.openvswitch.org/pipermail/ovs-dev/2017-April/330606.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id11" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id3"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id7"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/os-vif/+/460278"&gt;https://review.opendev.org/c/openstack/os-vif/+/460278&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/neutron/+/275616"&gt;https://review.opendev.org/c/openstack/neutron/+/275616&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id13" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/neutron/+/499203"&gt;https://review.opendev.org/c/openstack/neutron/+/499203&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id14" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.kernel.org/networking/switchdev.html"&gt;https://docs.kernel.org/networking/switchdev.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id15" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.kernel.org/doc/html/next/networking/devlink/devlink-port.html"&gt;https://www.kernel.org/doc/html/next/networking/devlink/devlink-port.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Thu, 04 May 2023 00:00:00 </pubDate></item><item><title>Tunnel based mirroring (ERSPAN, GRE) for Tap-as-a-service</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2023.2/erspan-for-tap-as-a-service.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/2015471"&gt;https://bugs.launchpad.net/neutron/+bug/2015471&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Mirroring is a widely used tool to analyse traffic of switch ports.
The Tap-as-a-service project was created to allow admins to mirror traffic
of one Neutron port to another Neutron port.&lt;/p&gt;
&lt;p&gt;Mirroring can also be done by encapsulating the traffic into a tunnel, like
GRE (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Generic&lt;/span&gt; &lt;span class="pre"&gt;Routing&lt;/span&gt; &lt;span class="pre"&gt;Encapsulation&lt;/span&gt;&lt;/code&gt;) or ERSPAN (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Encapsulated&lt;/span&gt; &lt;span class="pre"&gt;Remote&lt;/span&gt;
&lt;span class="pre"&gt;Switch&lt;/span&gt; &lt;span class="pre"&gt;Port&lt;/span&gt; &lt;span class="pre"&gt;Analyzer&lt;/span&gt;&lt;/code&gt;). ERSPAN first was used widely in Cisco switches, and
GRE is widely used as tunneling protocol.&lt;/p&gt;
&lt;p&gt;ERSPAN protocol has 3 versions of which the last two is adapted, these are
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;version&lt;/span&gt; &lt;span class="pre"&gt;1&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;version&lt;/span&gt; &lt;span class="pre"&gt;2&lt;/span&gt;&lt;/code&gt; (the other versioning uses TYPE I, II and III,
and TYPE II is version 1 and TYPE III is version 2)
For more details see the &lt;a class="reference external" href="https://datatracker.ietf.org/doc/id/draft-foschiano-erspan-02.txt"&gt;ERSPAN draft from Cisco&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Since OVS 2.10 it is possible to use ERSPAN with OVS
(see &lt;a class="reference external" href="https://docs.openvswitch.org/en/latest/faq/configuration/"&gt;OVS basic configuration&lt;/a&gt;, and &lt;a class="reference external" href="http://www.openvswitch.org//support/dist-docs/ovs-fields.7.txt"&gt;OVS protocol header fields&lt;/a&gt;) both
ERSPAN v1 and v2, see &lt;a class="reference external" href="https://github.com/openvswitch/ovs/commit/4ee9f056871872c3758abd291ccba9710b0c0479"&gt;erspan NEWS update commit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Since OVN v22.12.0 it is possible to create mirrors with OVN
(see &lt;a class="reference external" href="https://www.ovn.org/support/dist-docs-branch-22.12/ovn-nbctl.8.html"&gt;OVN 22.12 nbctl man page&lt;/a&gt;, and &lt;a class="reference external" href="https://github.com/ovn-org/ovn/commit/323f978cbf4599568fcca9edec8ed53c076d2664"&gt;OVN commit that introduced mirroring&lt;/a&gt;).&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;OVN only supports ERSPAN v1, and with OVN it is also possible to create
a clean GRE type mirror.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This specification proposes an extension to the current tap-as-a-service
(TAAS) API to allow the users to create ERSPAN or GRE mirrors from Neutron
ports to a remote IP, and proposes the necessary backend changes to the
current OVS driver of TAAS and proposes a new driver for OVN to use ERSPAN
or GRE mirroring with OVN.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Mirroring traffic can be useful in many situations for operators, for example
to debug network issues.&lt;/p&gt;
&lt;p&gt;Tap-as-a-service provided a solution for traffic mirroring by allowing to
create tap-flows and mirror the traffic of them to the related tap-service.
Each tap-flow and tap-service can be attached to a Neutron port, so the port
attached to tap-flow is the source of the mirrored traffic and the port of
tap-service is the destination of the mirroring.
There is a N-1 relation between tap-flows and tap-services.
This mirroring model is mirroring traffic from one Neutron port to another
Neutron port over a Neutron network.&lt;/p&gt;
&lt;p&gt;An ERSPAN or GRE mirror is a good solution when an operator needs to mirror
traffic from the cloud (from Neutron ports) to an analyser outside the cloud.&lt;/p&gt;
&lt;section id="use-cases"&gt;
&lt;h3&gt;Use Cases&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;As an operator I want to mirror the traffic from a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Neutron&lt;/span&gt; &lt;span class="pre"&gt;port&lt;/span&gt;&lt;/code&gt; to a
network analyser that can be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;outside&lt;/span&gt; &lt;span class="pre"&gt;of&lt;/span&gt; &lt;span class="pre"&gt;my&lt;/span&gt; &lt;span class="pre"&gt;cloud&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As an operator I want to mirror the traffic from a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Neutron&lt;/span&gt; &lt;span class="pre"&gt;port&lt;/span&gt;&lt;/code&gt;
to a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Floating&lt;/span&gt; &lt;span class="pre"&gt;IP&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As an operator I want to mirror the traffic of a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Neutron&lt;/span&gt; &lt;span class="pre"&gt;port&lt;/span&gt;&lt;/code&gt; to
a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dedicated&lt;/span&gt; &lt;span class="pre"&gt;infra&lt;/span&gt; &lt;span class="pre"&gt;network&lt;/span&gt;&lt;/code&gt;, to avoid overloading the tenant networks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As an operator I want to use the extra headers ERSPAN provides (i.e.:
original VLAN, original CoS in case of version 1 ERSPAN).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposal is to use OVS and OVN builtin ERSPAN version 1 and GRE mirroring
features. For using ERSPAN or GRE with OVS a port is added to an OVS bridge
with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;type=erspan&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;type=gre&lt;/span&gt;&lt;/code&gt; in case of GRE.&lt;/p&gt;
&lt;p&gt;As ERSPAN is a modification of GRE, with some extra ERSPAN specific
headers (see &lt;a class="reference external" href="https://datatracker.ietf.org/doc/id/draft-foschiano-erspan-02.txt"&gt;ERSPAN draft from Cisco&lt;/a&gt;), OVS creates the tunnel from the
previously created OVS port to the destination IP. This means that the mirrored
traffic is encapsulated to an ERSPAN/GRE tunnel.&lt;/p&gt;
&lt;p&gt;Example wireshark dump of an ICMP echo reply:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Frame&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;148&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;wire&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1184&lt;/span&gt; &lt;span class="n"&gt;bits&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;148&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt; &lt;span class="n"&gt;captured&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1184&lt;/span&gt; &lt;span class="n"&gt;bits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Ethernet&lt;/span&gt; &lt;span class="n"&gt;II&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RealtekU_79&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;79&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Dst&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RealtekU_91&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;91&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Internet&lt;/span&gt; &lt;span class="n"&gt;Protocol&lt;/span&gt; &lt;span class="n"&gt;Version&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;100.109.0.84&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Dst&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;100.109.0.142&lt;/span&gt;
&lt;span class="n"&gt;Generic&lt;/span&gt; &lt;span class="n"&gt;Routing&lt;/span&gt; &lt;span class="n"&gt;Encapsulation&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ERSPAN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Encapsulated&lt;/span&gt; &lt;span class="n"&gt;Remote&lt;/span&gt; &lt;span class="n"&gt;Switch&lt;/span&gt; &lt;span class="n"&gt;Packet&lt;/span&gt; &lt;span class="n"&gt;ANalysis&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;II&lt;/span&gt;
&lt;span class="n"&gt;Ethernet&lt;/span&gt; &lt;span class="n"&gt;II&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;d5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;d5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Dst&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Internet&lt;/span&gt; &lt;span class="n"&gt;Protocol&lt;/span&gt; &lt;span class="n"&gt;Version&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.39&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Dst&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.47&lt;/span&gt;
&lt;span class="n"&gt;Internet&lt;/span&gt; &lt;span class="n"&gt;Control&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="n"&gt;Protocol&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This means that the source IP of the tunnel is the IP of the host on which the
ERSPAN port is created (in my virtual env it is 100.109.0.84).
In the above example the 2 inner IPs (10.0.0.47 and 10.0.0.39) are the fixed
IPs of 2 Openstack ports (VMs).&lt;/p&gt;
&lt;p&gt;The outer protocol source IP (100.109.0.84) is the IP of the host on which the
mirror port is created, thus outside of the cloud, and in the control of the
admin.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This spec doesn’t specify the source address (mac or IP) of the tunnel.
So this is the task of the admin and out of scope for this spec.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The outer protocol destination IP (100.109.0.142) in this case is also outside
of the cloud, and Openstack Neutron control, and another host on which I can
run tcpdump.&lt;/p&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The current API model of TAAS uses two high level objects: &lt;cite&gt;tap-services&lt;/cite&gt; and
&lt;cite&gt;tap-flows&lt;/cite&gt;. The tap-flow represents the source of the mirrored traffic,
and a tap-service represents the destination of the mirrored traffic. For
one tap-service multiple tap-flows can be attached. For details please check
the &lt;a class="reference external" href="https://docs.openstack.org/api-ref/network/v2/index.html#tap-as-a-service"&gt;tap-as-a-service API reference&lt;/a&gt;.
Both a tap-flow and a tap-service are referencing a Neutron port, and the
traffic on that port will be the source of the mirror (in case of a tap-flow),
or the destination of the mirror (in case of a tap-service).&lt;/p&gt;
&lt;div class="admonition warning"&gt;
&lt;p class="admonition-title"&gt;Warning&lt;/p&gt;
&lt;p&gt;Mirroring only works for traffic which is allowed by security-groups.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The above API model is not useful when the intent is to implement mirroring
using ERSPAN or GRE tunnels, because the traffic source is a bridge port
(in the case of OVS) or a logical switch port (in the case of OVN) and the
destination is represented only by an IP address.&lt;/p&gt;
&lt;p&gt;The proposal is to introduce a new high level API for ERSPAN or GRE mirroring:
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tap_mirror&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This solution keeps the current API clean and not overloaded, and makes it
easier for operators to expect the right behaviour after API operations.&lt;/p&gt;
&lt;p&gt;The proposed API is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;admin&lt;/span&gt; &lt;span class="pre"&gt;only&lt;/span&gt;&lt;/code&gt;, to avoid the overloading of infrastructure
networks by tenants.&lt;/p&gt;
&lt;p&gt;The suggested API request:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/taas/tap_mirrors&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Create a tap mirror that mirrors traffic from a Neutron port to an
external IP:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"tap_mirror"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"mirror-traffic-of-server-a0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Mirror the traffic from server-a0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"directions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"IN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"OUT"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"port_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"1a1a5a96-e8cb-11ed-9678-9b663820b519"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"remote_ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"172.31.1.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"mirror_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"erspanv1"&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="s2"&gt;"gre"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port_id&lt;/span&gt;&lt;/code&gt; is the source of the mirroring, this is a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Neutron&lt;/span&gt; &lt;span class="pre"&gt;port&lt;/span&gt;&lt;/code&gt;.
One port can be attached to one tap_mirror only.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Only VM ports can be used as the source of the mirroring.&lt;/p&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;remote_ip&lt;/span&gt;&lt;/code&gt;: The IP of the remote end of the tunnel.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This API proposal keeps the current TAAS API’s N-1 relationship between
source and destination. Multiple source ports’ traffic can be mirrored to
one destination IP.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;mirror_type&lt;/span&gt;&lt;/code&gt; field is to select between ERSPAN and GRE.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;directions&lt;/span&gt;&lt;/code&gt; is a dictionary with &lt;cite&gt;direction:tunnel_id&lt;/cite&gt; pairs.
The current tap-as-a-service API allows the operator to select the direction
when the &lt;cite&gt;tap-flow&lt;/cite&gt; is created, it can be: IN, OUT, BOTH.
This specification proposes to keep &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;IN&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;OUT&lt;/span&gt;&lt;/code&gt; as the keys of the
dictionary. Meaning of the directions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;IN&lt;/span&gt;&lt;/code&gt;: the traffic towards the port, and into the VM attached to it
(ingress traffic).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;OUT&lt;/span&gt;&lt;/code&gt;: traffic from the port, out of the VM attached to the port (egress
traffic).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;cite&gt;tunnel_id&lt;/cite&gt; will be the value of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;directions&lt;/span&gt;&lt;/code&gt; dictionary, this is
the identifier of the ERSPAN or GRE session between the source and
destination.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;There is a big difference in the GRE and ERSPAN id size: GRE has 32 bits
key size but ERSPAN has only 10 bits for ERSPAN session ID.
This must be documented and validated on the API.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonition warning"&gt;
&lt;p class="admonition-title"&gt;Warning&lt;/p&gt;
&lt;p&gt;It is not possible to create tunnel (GRE or ERSPAN) with the same
tunnel_id to the same remote_ip from the same port with OVN. This means
that the tunnel_id can’t be the same for the 2 directions.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Both GRE and ERSPAN handle the fragmentation, so if the mirrored traffic’s
packet size with the extra headers is bigger than the MTU on the interface,
the packet in the tunnel will be sent fragmented.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;For the GRE type mirroring 8 octet extra header is added over IP headers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For ERSPAN 8 octet is added for GRE, 8 octet is added for ERSPAN and
an extra trailing 4 byte CRC is added, so in summary 20 octets extra
header is added in this case.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;The proposed API definition:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;mirror_types_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'erspan'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'gre'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'tap_mirror'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'port_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'enforce_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'directions'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'type:dict'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s1"&gt;'IN'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:integer'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="s1"&gt;'OUT'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:integer'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
            &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'remote_ip'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:ip_address'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'mirror_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mirror_types_list&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="db-impact"&gt;
&lt;h3&gt;DB Impact&lt;/h3&gt;
&lt;p&gt;To persist the new &lt;cite&gt;tap_mirror&lt;/cite&gt; in the DB, a new table &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tapmirrors&lt;/span&gt;&lt;/code&gt; is
needed:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s1"&gt;'tapmirrors'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;db_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UUID_FIELD_SIZE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
              &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'project_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;db_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PROJECT_ID_FIELD_SIZE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;db_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NAME_FIELD_SIZE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
              &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;db_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DESCRIPTION_FIELD_SIZE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'port_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UUID_FIELD_SIZE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
              &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'directions'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'remote_ip'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IP_ADDR_FIELD_SIZE&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'mirror_type'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mirror_type_enum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This also means that a new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;TapMirror&lt;/span&gt;&lt;/code&gt; DB model will be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ovn-driver-for-mirroring"&gt;
&lt;h3&gt;OVN driver for mirroring&lt;/h3&gt;
&lt;p&gt;The following shows the API call to create a tap_mirror based on version
1 ERSPAN and the corresponding backend changes:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ # REST API operation
$ curl -g -i -X POST http://&amp;lt;host_ip:9696&amp;gt;/networking/v2.0/taas/tap_mirrors \
  -d '{"tap_mirror": {"name": "mirror1", "port_id": "54c4b09f-8b3d-4685-b66d-ce22c67956a9",
                      "directions": {"OUT": 42}, "remote_ip": "100.109.0.142",
                      "mirror_type": "erspan"}}'

$ # backend changes
$ sudo ovn-nbctl mirror-list
mirror_out_297b12c0-e9a5-11ed-9f90-07946c615270:
  Type     :  erspan
  Sink     :  100.109.0.142
  Filter   :  from-lport
  Index/Key:  42

$ sudo ovs-vsctl show
    Bridge br-int
        ...
        Port ovn-my_mirror2
            Interface ovn-mirror_out_297b12c0-e9a5-11ed-9f90-07946c615270
                type: erspan
                options: {erspan_idx="42", erspan_ver="1", key="42", remote_ip="100.109.0.142"}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Using GRE is very similar: the OVN mirror type will be GRE and the
OVS port type will be GRE.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Description of the above port options:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;erspan_idx&lt;/span&gt;&lt;/code&gt; is a in hex, and it is the index field in ERSPAN header.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;erspan_ver&lt;/span&gt;&lt;/code&gt; is the version, for version 1 erspan it is 1.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;key&lt;/span&gt;&lt;/code&gt; is SpanID or Session ID field in the ERSPAN header.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;ERSPAN &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;index&lt;/span&gt;&lt;/code&gt; field is not specified as OVN doesn’t allow to set it
separately from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;key-tunnel_id&lt;/span&gt;&lt;/code&gt; field. When OVN allows the setting
of it, a future  TAAS change can handle it.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Example packet headers from Wireshark:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;Generic Routing Encapsulation (ERSPAN)
    Flags and Version: 0x1000
    Protocol Type: ERSPAN (0x88be)
    Sequence Number: 18
Encapsulated Remote Switch Packet ANalysis Type II
    0001 .... .... .... = Version: Type II (1)
    .... 0000 0000 0000 = Vlan: 0
    000. .... .... .... = COS: 0
    ...0 0... .... .... = Encap: Originally without VLAN tag (0)
    .... .0.. .... .... = Truncated: Not truncated (0)
    .... ..00 0000 0010 = SpanID: 42
    0000 0000 0000 .... .... .... .... .... = Reserved: 0
    .... .... .... 0000 0000 0000 0010 0000 = Index: 66

Index: 66: this is from ``erspan_idx=42``. Note that OVN's ``mirror-add``
command (and the OVN ovn-nb.ovsschema) accepts one `index` parameter and
uses that for OVS' ``key`` and ``erspan_idx`` parameters, but erspan_idx
is a hex value, so this is probably a bug or not fully considered thing
in OVN.

SpanId: 42: this is from ``key=42``
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With OVN to mirror both ingress and egress traffic of the source port
2 mirrors must be created (as the OVN mirror can have only &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;from-lport&lt;/span&gt;&lt;/code&gt; or
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;to-lport&lt;/span&gt;&lt;/code&gt; as direction), and attached to the port
(&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;logical-switch-port&lt;/span&gt;&lt;/code&gt;), one with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;filter=from-lport&lt;/span&gt;&lt;/code&gt; and one
with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;filter=to-lport&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;OVN implementation of mirroring allows the user to create a
mirror by selecting a direction as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;filter&lt;/span&gt;&lt;/code&gt; with ovn-nbctl,
or via ovsdb (see &lt;a class="reference external" href="https://github.com/ovn-org/ovn/blob/v22.12.0/ovn-nb.ovsschema#L309-L324"&gt;ovn-nb.ovsschema mirror table&lt;/a&gt;)&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;So if the user creates a tap_mirror with direction &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;IN&lt;/span&gt;&lt;/code&gt; the filter will be
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;to-lport&lt;/span&gt;&lt;/code&gt;, if &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;OUT&lt;/span&gt;&lt;/code&gt; the filter will be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;from-lport&lt;/span&gt;&lt;/code&gt; and in case of
both &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;IN&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;OUT&lt;/span&gt;&lt;/code&gt; in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;directions&lt;/span&gt;&lt;/code&gt; dictionary 2 mirrors will be
created one with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;to-lport&lt;/span&gt;&lt;/code&gt; and one with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;from-lport&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The above means that in case of mirroring both ingress and egress traffic
tap-as-a-service will create 2 ERSPAN or GRE ports on br-int for each
tap_mirror.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ovs-driver-changes"&gt;
&lt;h3&gt;OVS driver changes&lt;/h3&gt;
&lt;p&gt;To keep consistency between the 2 drivers, this specification proposes to use
GRE and ERSPAN version 1 for OVS drive also.&lt;/p&gt;
&lt;p&gt;The end-to-end call will look like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ # REST API operation
$ curl -g -i -X POST http://&amp;lt;host_ip:9696&amp;gt;/networking/v2.0/taas/tap_mirrors \
  -d '{"tap_mirror": {"name": "mirror1", "port_id": "54c4b09f-8b3d-4685-b66d-ce22c67956a9",
                      "direction": "IN", "remote_ip": "100.109.0.142", "tunnel_id": "42",
                      "mirror_type": "erspan"}}'

$ # Backend changes
$ sudo ovs-vsctl show
    Bridge br-tap
        ...
        Port mirror_in_ed6046d
        Interface mirror_in_ed6046d
            type: erspan
            options: {erspan_idx="42", erspan_ver="1", key="2", remote_ip="100.109.0.84"}

$ sudo ovs-ofctl dump-flows  br-tap
   ...
   ... priority=20,dl_dst=fa:16:3e:d3:3a:d1 actions=output:"mirror_in_ed6046d"
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For details on what the port properties &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;key&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;erspan_idx&lt;/span&gt;&lt;/code&gt; mean, see
&lt;a class="reference internal" href="#ovn-driver-for-mirroring"&gt;OVN driver for mirroring&lt;/a&gt; .&lt;/p&gt;
&lt;p&gt;For the details on how the case will be handled when both &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;IN&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;OUT&lt;/span&gt;&lt;/code&gt;
direction will be selected by the user see &lt;a class="reference internal" href="#ovn-driver-for-mirroring"&gt;OVN driver for mirroring&lt;/a&gt;.
OVS driver will create 2 OVS ports (type=erspan or type=gre) for the 2
directions like OVN does.&lt;/p&gt;
&lt;p&gt;For the two directions 2 different flows will be installed on &lt;cite&gt;br-tap&lt;/cite&gt; with
different output port in the action field:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ # Direction IN
$ sudo ovs-ofctl dump-flows  br-tap
...
... priority=20,dl_dst=fa:16:3e:d3:3a:d1 actions=output:"mirror_in_ed6046d"

$ # Direction OUT
$ sudo ovs-ofctl dump-flows  br-tap
...
... priority=20,dl_src=fa:16:3e:d3:3a:d1 actions=output:"mirror_out_ed6046d"
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="out-of-scope"&gt;
&lt;h2&gt;Out of Scope&lt;/h2&gt;
&lt;p&gt;This specification is not proposing to make the OVN driver fully compatible
with the current OVS or SRIOV driver. So the proposed OVN driver will
implement only ERSPAN.&lt;/p&gt;
&lt;p&gt;To make OVN driver fully feature compatible with the current OVS or SRIOV
driver can be part of a future specification.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Lajos Katona (~lajoskatona) &amp;lt;&lt;a class="reference external" href="mailto:lajos.katona%40est.tech"&gt;lajos&lt;span&gt;.&lt;/span&gt;katona&lt;span&gt;@&lt;/span&gt;est&lt;span&gt;.&lt;/span&gt;tech&lt;/a&gt;&amp;gt;, &amp;lt;&lt;a class="reference external" href="mailto:katonalala%40gmail.com"&gt;katonalala&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add new REST API extension for tap-as-a-service, neutron-lib and
tap-as-a-service changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change tap-as-a-service db schema accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adapt ovsdbapp to make it possible to manipulate both ovsdb and ovn-northd
and create mirrors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change OVS driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new ERSPAN only OVN tap-as-a-service driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adapt the documentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement the necessary tests.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;end-to-end test in tempest can be done using Floating IPs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adapt OpenstackSDK and the necessary CLI code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adapt Heat to make it possible to create ERSPAN mirrors.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Wed, 26 Apr 2023 00:00:00 </pubDate></item><item><title>[OVN] - IPv6 Distributed routing</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2023.1/ovn-ipv6-dvr.html</link><description>

&lt;p&gt;RFE: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1998609"&gt;https://bugs.launchpad.net/neutron/+bug/1998609&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This RFE intends to implement distributed routing support for IPv6 only or
dual-stack usage scenarios. Distributed routing is already a reality for IPv4
FIP addresses and the benefits of implementing DVR for IPv6 are the same as
for IPv4 FIP addresses.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;When we are using an IPv6 only or dual-stack deployment, the traffic for IPv6
addresses remains centralized by the gateway port of the router. DVR support
for IPv4 FIP addresses has already implemented in neutron using the
enable_distributed_floating_ip flag in the [ovn] section - ml2_conf.ini file.&lt;/p&gt;
&lt;p&gt;This issue affects both End Users and Deployers:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;For End Users - (Network performance) Since traffic is centralized, all
network applications need to go through the gateway router port chassis
resident &amp;lt;-&amp;gt; compute node (via tunneling - e.g. Geneve) before reaching
the endpoint. In case the gw router port is on the same chassis as the VM
compute node, this is not applicable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For Deployers - (Additional settings for dynamic routing) As the IPv6 GUA
subnet is associated behind the router’s gw port, it is necessary to
advertise this subnet dynamically to the border network element (which
routes the external/internal traffic of IPv6 prefixes). It could be
statically, but it is not feasible when we talk about large scale
deployments. So, we need to enable additional settings like BGP with the
neutron-dynamic-routing, for example.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the compute node where the VM is running knows the path to send packets
to external networks (with the help of routing protocols configured on each
compute node, e.g. using FRR), outgoing traffic may work directly to the
border. However, the incoming traffic will always be forwarded to the
router’s gw port, as it is the only one that knows how to respond the
Neighbor Solicitation to the IPv6 GUA address of the VM.&lt;/p&gt;
&lt;p&gt;DVR Use case:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The provider networks must be stretched over the Underlay Network and each
Compute Node would have the bridge for external traffic. In an L3 Leaf-Spine
Underlay, for example, the network to be reached is for the Underlay Network
be able to stretch an L2 domain(VLAN) via VXLAN as dataplane and BGP EVPN as
Control Plane. In this solution, the Leaf switches would need to work as HW
VTEP Gateways to initiate and terminate the VXLANs tunnels and use BGP EVPN
to learn and advertise the MAC Addresses from the Compute Node’s provider
network.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;W&lt;/span&gt; &lt;span class="n"&gt;PATH&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;Compute&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;OVS&lt;/span&gt; &lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;external&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bridge&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mapping&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;FRR&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;BGP&lt;/span&gt; &lt;span class="n"&gt;EVPN&lt;/span&gt; &lt;span class="n"&gt;type2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;W&lt;/span&gt; &lt;span class="n"&gt;spine&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;leaf&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;reverse&lt;/span&gt; &lt;span class="n"&gt;flow&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="n"&gt;PATH&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;Compute&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;OVS&lt;/span&gt; &lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;external&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bridge&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mapping&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;FRR&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;BGP&lt;/span&gt; &lt;span class="n"&gt;EVPN&lt;/span&gt; &lt;span class="n"&gt;type2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="n"&gt;Border&lt;/span&gt; &lt;span class="n"&gt;Leaf&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;external&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;To solve the problem described above, the proposal is to introduce a new NAT
rule for the IPv6 GUA addresses that are allocated to VMs (OVN understands
IPv6 GUA like a FIP). Even though it is a global address, the ovn-controller
running on the chassis needs this rule to start responding to Neighbor
Advertisements for IPv6 just like it does with GARPs for IPv4 FIP’s.&lt;/p&gt;
&lt;p&gt;To enable the IPv6 DVR NAT rule management, a new config option should be
enabled via [ovn] section in ml2_conf.ini file.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;* ``enable_distributed_ipv6 = True``
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This option is similar to a configuration option to enable DVR for FIP’s:
enable_distributed_floating_ip.&lt;/p&gt;
&lt;section id="ovn-impact"&gt;
&lt;h3&gt;OVN Impact&lt;/h3&gt;
&lt;p&gt;OVN support of distributed routing for an IPv6 GUA follows the same idea of
the IPv4 case &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. For the ovn-controller, the external_ip and local_ip can
contain IPv4 or IPv6 addresses. Therefore, the contract rule for creating the
IPv6 NAT rule remains the same used for FIP IPv4 addresses.&lt;/p&gt;
&lt;p&gt;NAT rule fields (OVN):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nb"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dnat_and_snat&lt;/span&gt;
&lt;span class="n"&gt;logical_ip&lt;/span&gt;  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;same&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt; &lt;span class="n"&gt;IPv6&lt;/span&gt; &lt;span class="n"&gt;GUA&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;
&lt;span class="n"&gt;external_ip&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;same&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt; &lt;span class="n"&gt;IPv6&lt;/span&gt; &lt;span class="n"&gt;GUA&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;
&lt;span class="n"&gt;logical_port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt; &lt;span class="n"&gt;logical&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;
&lt;span class="n"&gt;external_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Managed&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="n"&gt;Neutron&lt;/span&gt;
&lt;span class="n"&gt;external_mac&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt; &lt;span class="n"&gt;MAC&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The external_ip and logical_ip used in the NAT rule are the same (e.g. VM
GUA). With this entry, the OVN should add logical flows to respond to IPv6
Neighbor Solicitation requests for the IPv6 GUA directly by ovn-controller
on the chassis where the VM resides.&lt;/p&gt;
&lt;p&gt;We know that there is no NAT for IPv6, so this special rule that translates
the GUA address to itself is only used to create the flows in the chassis
where the VM resides. Without this rule, the compute node does not know how
to respond to that IPv6 GUA and centralize the communication through the
router’s GW port (via Geneve tunnel if the router resides on another host).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="neutron-impact"&gt;
&lt;h3&gt;Neutron Impact&lt;/h3&gt;
&lt;p&gt;The NAT rules for FIP IPv4 are managed by Neutron floating ips database.
In the case of the NAT rule for IPv6 GUA addresses, we need to create a
“fake translation rule” for the address associated with a VM. IPv6 addresses
are allocated to VMs during port creation and managed via ipv6_address_mode
(static, SLAAC, DHCPv6 Stateful, or DHCPv6 Stateless).&lt;/p&gt;
&lt;p&gt;This means that port creation and deletion events manage IPv6 addresses and
MAC addresses allocated to a VM. In this case, the creation of the NAT rule
for IPv6 GUA can follow the port creation and deletion process provided by
ovn_client in the OVN driver.&lt;/p&gt;
&lt;p&gt;The port structure provides the IPv6 address (subnet), the VM MAC address,
and the logical_port but to create a NAT rule it is necessary to allocate
this rule to the router, being necessary to search for the id of the router
associated with the port of the VM.&lt;/p&gt;
&lt;p&gt;IPv6 GUA NAT rule creation:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'dnat_and_snat'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s1"&gt;'logical_ip'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IPv6_ADDRESS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s1"&gt;'external_ip'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IPv6_ADDRESS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s1"&gt;'logical_port'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PORT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s1"&gt;'external_ids'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;EXTERNAL_IDS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s1"&gt;'external_mac'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;EXTERNAL_MAC&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;_nb_idl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_nat_rule_in_lrouter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gw_lrouter_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;IPv6 GUA NAT rule deletion:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'dnat_and_snat'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s1"&gt;'logical_ip'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IPv6_ADDRESS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s1"&gt;'external_ip'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IPv6_ADDRESS&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;_nb_idl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete_nat_rule_in_lrouter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gw_lrouter_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For IPv4 FIP NAT rules, the external_ids has important fields such as the
fip_key, for example, but for IPv6 the external_ids information is not
relevant. So, we can set common port information in that field to keep
tracking. The neutron dnat_and_snat rule is composed with the following
information in the external_ids:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;external_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OVN_PORT_EXT_ID_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OVN_DEVID_EXT_ID_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;OVN_NETWORK_NAME_EXT_ID_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OVN_ROUTER_NAME_EXT_ID_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The common port information is stored in the OVN “NAT:external_ids”
dictionary:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ ovn-nbctl list NAT
 _uuid               : 4ab3ef03-c832-4635-bce9-779d1092fc89
 allowed_ext_ips     : []
 exempted_ext_ips    : []
 external_ids        : {"neutron:device_id"=
                                 "a467f63b-8159-4e87-83ce-d6b55ed4401f",
                        "neutron:network_name"=
                               neutron-b3110178-9798-4951-a681-2e12301001f8,
                        "neutron:port_id"=
                                 "9910cdd5-d764-403c-ae35-565930107c7a",
                        "neutron:router_name"=
                               neutron-a00e21fa-4332-4e26-8e34-73a24cbf46d1}
 external_ip         : "2001:db8:1234:1::33"
 external_mac        : "fa:16:3e:1d:31:57"
 external_port_range : ""
 logical_ip          : "2001:db8:1234:1::33"
 logical_port        : "9910cdd5-d764-403c-ae35-565930107c7a"
 options             : {}
 type                : dnat_and_snat
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="ipv6-dvr-events"&gt;
&lt;h3&gt;IPv6 DVR events&lt;/h3&gt;
&lt;p&gt;Neutron will configure the NAT rule for the IPv6 distributed routing
reacting to the following events:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;VM port creation: with this event, neutron create a NAT rule for the
IPv6 GUA address allocated to the VM. If the VM does not have a router
associated with the VM subnet, do not create the IPv6 NAT rule.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VM port deletion: same behavior as the VM port creation, this event is
received and neutron must delete the NAT rule attached to the router. If the
VM does not have a router associated with the VM subnet, do not delete
the IPv6 NAT rule.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Router port creation: if this event is received, it is necessary to check
if the added port is in the same subnet associated with the previously
created VM port. This means neutron must create the IPv6 NAT rule if the
router port is associated with the VM subnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Router port deletion: same behavior as the router port creation, this means
neutron must delete the IPv6 NAT rule if the router port is associated
with the VM subnet.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="fip-ipv4-impact"&gt;
&lt;h3&gt;FIP IPv4 Impact&lt;/h3&gt;
&lt;p&gt;Until now, the only NAT rule of type ‘dnat_and_snat’ was used exclusively
for FIP’s, therefore, the functions that search the OVN database for NAT
rules of type ‘dnat_and_snat’, need to filter for exclusive FIP rules.
One idea would be to create a new constant in external_ids to set the IP
version, but it might be enough just to look for rules that have the
OVN_FIP_EXT_ID_KEY fieldset.&lt;/p&gt;
&lt;p&gt;The change in neutron OVN NAT lookup for FIP’s may require changes in
existing tests for floating ips.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="db-impact"&gt;
&lt;h3&gt;DB Impact&lt;/h3&gt;
&lt;p&gt;No new column entries or tables are needed to implement this RFE. IPv6 and
MAC address information is already recorded on ports associated with VMs.&lt;/p&gt;
&lt;p&gt;However, to ensure consistency of information between neutron and OVN, it
is necessary to implement a check for IPv6 NAT rules during ovn_db_sync.
For VMs already created before enabling ‘enable_distributed_ipv6’ flag,
neutron will notify in the log about the config differences when it is
restarted. The NAT rules for IPv6 GUA will be automatically added or
removed when executing a SYNC_MODE_REPAIR.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignees:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Roberto Bartzen Acosta &amp;lt;&lt;a class="reference external" href="mailto:rbartzen%40gmail.com"&gt;rbartzen&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit/functional tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Information about the IPv6 distributed routing support.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://mail.openvswitch.org/pipermail/ovs-discuss/2022-December/052126.html"&gt;https://mail.openvswitch.org/pipermail/ovs-discuss/2022-December/052126.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Fri, 16 Dec 2022 00:00:00 </pubDate></item><item><title>OVN Neutron Agent and hardware offloaded QoS extension</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2023.1/ovn-neutron-agent.html</link><description>

&lt;p&gt;Launchpad bug: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1998608"&gt;https://bugs.launchpad.net/neutron/+bug/1998608&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The aim of the RFE is to define the architecture of a new generic OVN agent
that will execute any needed functionality, being extensible as any other ML2
agent. The first functionality to be implemented will be the hardware
offloaded QoS extension.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;ML2/OVN is a mechanism driver that doesn’t have backend agents. This mechanism
driver exposes two agent types: the OVN controller agent and the metadata
agent. The OVN controller agent is a representation of the status of the
ovn-controller service on the node; the metadata agent is the service that
provides the metadata to the virtual machines.&lt;/p&gt;
&lt;p&gt;However the ML2/OVN mechanism driver does not have an agent to perform the
local Open vSwitch service configuration as in ML2/OVS, with extension drivers
(like QoS or Trunk). The ovn-controller reads the OVN Southbound database to
configure the local OVS database.&lt;/p&gt;
&lt;p&gt;The lack of an agent running on the local node, owned by Neutron, prevents us
from implementing some functionalities currently not supported by OVN nor the
drivers. For example, and this will be the first feature that the OVN agent
will implement, hardware offloaded ports cannot apply the OVS QoS rules due to
limitations in the drivers, in particular the ones for the NVIDIA Mellanox
ConnectX-5 network cards &lt;a class="footnote-reference brackets" href="#id5" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;0&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This RFE proposes to create a generic agent running on the compute node. This
agent will be called “OVN Neutron Agent”. The execution of this agent is
discretionary and will be needed only if the specific features implemented
on it are requested in a particular compute node. In other words, initially
this service will be needed if a compute node has hardware offloaded ports
and QoS is needed (new features could be implemented in the future).&lt;/p&gt;
&lt;p&gt;Unlike other mechanism driver agents (like in ML2/OVS or ML2/SRIOV), this
agent does not implement an RPC client. The information required to work
will be retrieved from the local OVS database, the OVN Northbound database
and the OVN Southbound database. It will be discussed in a future RFE to
include RPC capabilities to have a direct connection to the Neutron
server and the Neutron database.&lt;/p&gt;
&lt;section id="extensible-functionalities"&gt;
&lt;h3&gt;Extensible functionalities&lt;/h3&gt;
&lt;p&gt;The new agent functionalities will be defined via extensions. It will use
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron.agent.agent_extensions_manager.AgentExtensionsManager&lt;/span&gt;&lt;/code&gt; class
to load the configured OVN Neutron Agent extensions. It will use the same
configuration variable “agent.extensions” used by other ML2 agents. The OVN
Neutron Agent extensions will inherit from
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron_lib.agent.extensions.AgentExtension&lt;/span&gt;&lt;/code&gt; and will be loaded during the
agent startup by the agent extension manager.&lt;/p&gt;
&lt;p&gt;As commented before, the OVN agent will have active OVN Northbound, OVN
Southbound and local OVS database connections, using the corresponding IDL
classes. These classes will monitor a certain set of tables and will
register a set of events. Each extension must report what tables and events
are needed during the startup process. The extensions will inherit from a
specific OVN Neutron Agent extension class (derived from the mentioned
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;AgentExtension&lt;/span&gt;&lt;/code&gt;) that will provide API methods to retrieve this
information.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ovn-agent-status-report"&gt;
&lt;h3&gt;OVN agent status report&lt;/h3&gt;
&lt;p&gt;This new OVN Neutron Agent needs to be tracked in the Neutron server.
There are currently two types of agents: the “OVN Controller agent”/”OVN
Controller Gateway agent” and the “OVN metadata agent”. This RFE will
introduce the “OVN Neutron Agent” type. This is a generic name matching
the goal of this spec that is to create a generic OVN agent to implement
all needed functionalities that the OVN controller cannot provide
(metadata will be the next feature to be implemented there, migrated
from the current “OVN metadata agent”).&lt;/p&gt;
&lt;p&gt;The reporting mechanism will be the same as the one implemented in the
OVN metadata agent. When the Southbound table “SB_Global” is updated,
the agent will update a key in the “external_ids” dictionary. Please check
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron.agent.ovn.metadata.agent.SbGlobalUpdateEvent&lt;/span&gt;&lt;/code&gt; for an
implementation example. This variable will be read by the server that will
check the timestamp and determine the agent status.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="qos-for-hardware-offloaded-ports"&gt;
&lt;h3&gt;QoS for hardware offloaded ports&lt;/h3&gt;
&lt;p&gt;The first feature (extension) that will be implemented within this agent
is the QoS extension for hardware offloaded ports. Because of the current
drivers limitations, these ports cannot be properly configured with the
current QoS rules.&lt;/p&gt;
&lt;p&gt;This RFE proposes to use the corresponding “ip-link” &lt;a class="footnote-reference brackets" href="#id6" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; commands (or
their “pyroute2” equivalents) to configure the port representor virtual
function rates (maximum and minimum). This is similar to what is done in
ML2/SRIOV for a virtual function (VF).&lt;/p&gt;
&lt;p&gt;A port representor (or a devlink port &lt;a class="footnote-reference brackets" href="#id7" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;) is an API to expose the device
information; it is not a physical port but a representative of a hardware
port. The devlink port is connected to the local OVS switch; using the
“devlink” tool (or the “pyroute2” equivalent), it is possible to retrieve
the port information, including the physical function (PF) PCI address.
E.g.:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ devlink port show enp4s0f1_5 -jp
 "port": {
     "pci/0000:04:00.1/65542": {
         "type": "eth",
         "netdev": "enp4s0f1_5",
         "flavour": "pcivf",
         "pfnum": 1,
         "vfnum": 5,
         "splittable": false,
         "function": {
             "hw_addr": "fa:16:3e:f8:7b:10"
         }
     }
 }
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With the PF PCI address, it is possible to retrieve the PF name, that will
be stored in:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ cat /sys/bus/pci/devices/$pf_pci_address/net
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Using the ML2/SRIOV class &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PciDeviceIPWrapper&lt;/span&gt;&lt;/code&gt;, it is possible to set the
maximum and minimum rates of a VF, knowing the VF index and the PF name.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ovn-qos-information-location"&gt;
&lt;h3&gt;OVN QoS information location&lt;/h3&gt;
&lt;p&gt;The OVN QoS information is stored in two different places (due to how QoS
is currently implemented in ML2/OVN and core OVN):&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The maximum bandwidth (“rate”) and maximum burst (“burst”) limits are stored
in the “Qos:bandwidth” dictionary:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ ovn-nbctl list Qos
 _uuid               : 376303c4-5290-4c4e-a489-d35894315199
 action              : {}
 bandwidth           : {rate=1000, burst=800}
 direction           : to-lport
 external_ids        : {"neutron:port_id"="89a81cc0-7b3e-473d-8c01-2539cf2a9a6a"}
 match               : "outport == \"89a81cc0-7b3e-473d-8c01-2539cf2a9a6a\""
 priority            : 2002
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The minimum bandwidth rate is stored in the “Logical_Switch_Port:options”
dictionary:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ ovn-nbctl list Logical_Switch_Port
 _uuid               : 502b3852-4a46-4fcb-9b49-03063cfc0b34
 addresses           : ["fa:16:3e:c4:b8:29 10.0.0.8"]
 dhcpv4_options      : a7e4cfb1-ef22-490a-9ffe-fea04de3fe1c
 dhcpv6_options      : []
 dynamic_addresses   : []
 enabled             : true
 external_ids        : {...(skipped)}
 ha_chassis_group    : []
 name                : "e6808371-c9ac-4015-94a3-7f16ac3fbb2d"
 options             : {mcast_flood_reports="true", qos_min_rate="1000",
                        requested-chassis=u20ovn}
 parent_name         : []
 port_security       : ["fa:16:3e:c4:b8:29 10.0.0.8"]
 tag                 : []
 tag_request         : []
 type                : ""
 up                  : true
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="ovn-qos-events"&gt;
&lt;h3&gt;OVN QoS events&lt;/h3&gt;
&lt;p&gt;The hardware offloaded QoS extension will configure the QoS setting on a
port reacting to the following events (please check the working POC &lt;a class="footnote-reference brackets" href="#id8" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;
for more information):&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The local OVS interface creation: with this event, the OVN monitor will
store what ports are bound to the local instance. It will store the
Neutron port ID (stored in the “Interface.external_ids:iface-id” string)
and the OVS port name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The local OVS interface deletion: this event will trigger the QoS reset
and the interface local cache deletion.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The OVN Southbound “Port_Binding” creation event: this event is received
after a port is created in a local OVS. If this event is received, that
will trigger the QoS update of the local port. It’s worth mentioning that
this event happens always after the local OVS interface creation; that
means the OVN monitor has already registered that this port is bound
locally.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The OVN Northbound “Logical_Switch_Port” register change: if minimum
bandwidth of a locally bound LSP changes, this event triggers the QoS
update.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The OVN Northbound “QoS” register change: similar to the previous one
but affecting the maximum bandwidth limit.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;This RFE does not introduce any API change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;This RFE does not introduce any model change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Each monitor will have a connection to the local OVS database and the remotes
OVN Northbound and Southbound databases. The connection to the remote OVN
databases can have a severe impact on the load of the OVN database node (that
are usually the OpenStack controllers). This initial implementation will
subscribe to the following tables:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Northbound: QoS, Logical_Switch_Port and Logical_Switch&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Southbound: Chassis, Encap, Port_Binding, Datapath_Binding and SB_Global&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This performance impact should be reduced by:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Reducing the number of agents on the node. The next step to be implemented
(out of scope in this RFE) is to move the OVN metadata agent functionality
to this new OVN Neutron agent. That will reduce the Southbound database
connections to one single agent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Find a way to store the minimum bandwidth information outside the Logical
Switch Port. By not subscribing to this table, the Northbound connection
will reduce the load notably. The Logical Switch Port is one of the most
populated and active ones; not locally caching nor receiving its updates
will reduce the impact on the OVN database.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-impact"&gt;
&lt;h3&gt;Other Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignees:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Rodolfo Alonso Hernandez &amp;lt;&lt;a class="reference external" href="mailto:ralonsoh%40redhat.com"&gt;ralonsoh&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt; (IRC: ralonsoh)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;OVN monitor implementation and the hardware offloaded QoS extension.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests and CI related changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit/functional tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The hardware offloaded QoS extension requires specific hardware to
test this feature. Currently is not possible to implement any
tempest test on the CI.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Information about how to configure and spawn the OVN monitor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Information about the hardware offloaded QoS extension.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;0&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugzilla.redhat.com/show_bug.cgi?id=2002406"&gt;https://bugzilla.redhat.com/show_bug.cgi?id=2002406&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://man7.org/linux/man-pages/man8/ip-link.8.html"&gt;https://man7.org/linux/man-pages/man8/ip-link.8.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.kernel.org/doc/html/latest/networking/devlink/devlink-port.html"&gt;https://www.kernel.org/doc/html/latest/networking/devlink/devlink-port.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/neutron/+/866480"&gt;https://review.opendev.org/c/openstack/neutron/+/866480&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Sat, 10 Dec 2022 00:00:00 </pubDate></item><item><title>Strict minimum bandwidth support for tunnelled networks</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2023.1/strict-minimum-bandwidth-tunnelled-networks.html</link><description>

&lt;p&gt;Launchpad bug: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1991965"&gt;https://bugs.launchpad.net/neutron/+bug/1991965&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The aim of the RFE is to improve the previous implemented RFE Strict minimum
bandwidth support &lt;a class="footnote-reference brackets" href="#id8" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Since &lt;a class="footnote-reference brackets" href="#id8" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, Neutron has the ability to model the available bandwidth of the
physical interfaces (ingress and egress) connected to the physical networks
(flat and VLAN networks). This information is collected by Placement and
used to spawn virtual machines with network ports on compute nodes with
enough bandwidth. That guarantees a minimum port throughput.&lt;/p&gt;
&lt;p&gt;This feature is currently implemented in three backends: ML2/SR-IOV, ML2/OVS
and ML2/OVN. The full list of related patches can be reviewed at &lt;a class="footnote-reference brackets" href="#id9" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, most of the current deployments do not use physical backed networks
(flat or VLAN) but overlay networs (VXLAN and Geneve). Of course those
deployments use ML2/OVS and ML2/OVN; ML2/SR-IOV does not support tunnelled
networks. That leads to an existing gap in the currently implemented feature:
there is no way to model tunnelled networks.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This RFE proposes a way to model the available bandwidth for tunnelled
networks in compute nodes. This implementation will be limited to ML2/OVS
and ML2/OVN backends.&lt;/p&gt;
&lt;p&gt;The referred backends handle the overlay traffic sending and receiving this
traffic from a host interface, that acts as a VTEP &lt;a class="footnote-reference brackets" href="#id10" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. This host interface
is identified by an IP address, known as “local_ip” in the ML2 plugin
configuration file &lt;a class="footnote-reference brackets" href="#id11" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This RFE proposes to use the same configuration options provided in &lt;a class="footnote-reference brackets" href="#id8" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;,
adding a static string constant to define a resource provider in Placement
that could be configurable by the administrator. This string will be the
suffix of the resource provider name, same as Neutron uses the physical
bridge names to build their resource provider names. For example
“u20ovn:OVN Controller agent:rp_tunnelled”, being “rp_tunnelled” the provided
string. The default value will be “rp_tunnelled”. This configuration variable
will be stored in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[ml2]&lt;/span&gt;&lt;/code&gt; section and will be accesible from the Neutron
server and the OVS agent:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ml2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;tunnelled_network_rp_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;custom_rp_name&lt;/span&gt;  &lt;span class="c1"&gt;# "rp_tunnelled" by default.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Example of ML2/OVS configuration section:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ovs&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;resource_provider_bandwidths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;br0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;EGRESS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;INGRESS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;rp_tunnelled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;EGRESS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;INGRESS&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Example of ML2/OVN configuration, stored in the local database of the OVS
service:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="nd"&gt;@u20ovn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="c1"&gt;# ovs-vsctl list open_vswitch .&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;external_ids&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;u20ovn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;ovn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bridge&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;ovn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bridge&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mappings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"public:br-ex"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;ovn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cms&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"enable-chassis-as-gw,&lt;/span&gt;
                                 &lt;span class="n"&gt;resource_provider_bandwidths&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4001&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5001&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;rp_tunnelled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4001&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="n"&gt;resource_provider_inventory_defaults&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;allocation_ratio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;min_unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="n"&gt;resource_provider_hypervisors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;u20ovn&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;rp_tunnelled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;u20ovn&lt;/span&gt;&lt;span class="s2"&gt;",&lt;/span&gt;
                &lt;span class="n"&gt;ovn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;encap&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"192.168.10.40"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;ovn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;encap&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;geneve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;ovn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;remote&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"tcp:192.168.10.40:6642"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"a55c8d85-2071-4452-92cb-95d15c29bde7"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that in ML2/OVN, it is mandatory to define the tunnelled resource provider assignation to
the host in the “resource_provider_hypervisors” list.&lt;/p&gt;
&lt;p&gt;This new string constant cannot be used as a physical bridge name. To avoid
any possible clash, there will be a new check when parsing the physical
network bridge mappings.&lt;/p&gt;
&lt;p&gt;A host with ML2/OVN backend with a physical network (mapped to the physical
bridge “br-ex”) and a tunnelled network will report the following resource
provider tree:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ openstack resource provider list
+--------------------------------------+------------------------------------------+------------+--------------------------------------+--------------------------------------+
| uuid                                 | name                                     | generation | root_provider_uuid                   | parent_provider_uuid                 |
+--------------------------------------+------------------------------------------+------------+--------------------------------------+--------------------------------------+
| 8f0e060d-bf63-42a1-85e6-710c8b2fccc8 | u20ovn                                   |         10 | 8f0e060d-bf63-42a1-85e6-710c8b2fccc8 | None                                 |
| cb101b60-527b-5264-8e7f-213c7b88e9e1 | u20ovn:OVN Controller agent              |          1 | 8f0e060d-bf63-42a1-85e6-710c8b2fccc8 | 8f0e060d-bf63-42a1-85e6-710c8b2fccc8 |
| 521f53a6-c8c0-583c-98da-7a47f39ff887 | u20ovn:OVN Controller agent:br-ex        |         20 | 8f0e060d-bf63-42a1-85e6-710c8b2fccc8 | cb101b60-527b-5264-8e7f-213c7b88e9e1 |
| dfdbf43f-f60b-577c-bae8-3dcea448c735 | u20ovn:OVN Controller agent:rp_tunnelled |          6 | 8f0e060d-bf63-42a1-85e6-710c8b2fccc8 | cb101b60-527b-5264-8e7f-213c7b88e9e1 |
+--------------------------------------+------------------------------------------+------------+--------------------------------------+--------------------------------------+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;A new static trait will be added to represent this resource provider:
“CUSTOM_NETWORK_TUNNEL_PROVIDER”. This is what identify that this resource
provider is for tunnelled networks. E.g.:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ openstack resource provider trait list $rp_tun
+----------------------------------+
| name                             |
+----------------------------------+
| CUSTOM_VNIC_TYPE_NORMAL          |
| CUSTOM_VNIC_TYPE_DIRECT          |
| CUSTOM_VNIC_TYPE_DIRECT_PHYSICAL |
| CUSTOM_VNIC_TYPE_MACVTAP         |
| CUSTOM_VNIC_TYPE_VDPA            |
| CUSTOM_VNIC_TYPE_REMOTE_MANAGED  |
| CUSTOM_VNIC_TYPE_BAREMETAL       |
| CUSTOM_NETWORK_TUNNEL_PROVIDER   |
+----------------------------------+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This is an example of a port resource request, sent to Nova when creating a
virtual machine. The port has a minimum bandwidth rule of 500 kbps, egress
direction:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'resource_request'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'request_groups'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'c51c6f07-8e01-548c-9756-d5e54a780bb6'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'CUSTOM_NETWORK_TUNNEL_PROVIDER'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'CUSTOM_VNIC_TYPE_NORMAL'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
         &lt;span class="s1"&gt;'resources'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'NET_BW_EGR_KILOBIT_PER_SEC'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s1"&gt;'same_subtree'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'c51c6f07-8e01-548c-9756-d5e54a780bb6'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This spec is not considering the case of shared resource providers. For
example when the same interface is shared between a VLAN/flat network and
and overlay network. What this spec is proposing is to provide the
scheduling functionality to ports in overlay networks. In case of having
shared resources, the administrator will need to split bandwidth assignation
between resource providers. Currently Placement API nor Neutron cannot
provide a way to model a shared resource.&lt;/p&gt;
&lt;/div&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;This RFE does not introduce any API change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;This RFE does not introduce any model change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-impact"&gt;
&lt;h3&gt;Other Impact&lt;/h3&gt;
&lt;p&gt;Currently there is no support for minimum bandwidth QoS rules for tunnelled
networks, neither in Placement nor in the ML2 backend (OVS, OVN). However,
it is possible to have ports with those type of QoS rules (maybe inherited
from the network QoS policy). With this feature, the minimum bandwidth QoS
rules won’t be discarded, like now, when the port resource request is built
(that is the Placement blob to request a specific bandwidth in a specific
network).&lt;/p&gt;
&lt;p&gt;A new check will be added to inform about those ports located on
tunnelled networks with minimum bandwidth QoS rules. The output of this check
will be a log with the list of ports, their networks and QoS policies. This
spec is considering the current Neutron implementation:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;ML2/OVS rejects the assignation of a QoS policy with minimum bandwidth rules
and prevents from binding a port with them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The ML2/OVN mechanism driver implemented the minimum bandwidth rule support
recently and does not prevent this scenario. However this functionality was
implemented in Zed release; it is unlikely that many deployments are in this
state (with ports located in overlay networks with QoS policies and minimum
bandwidth rules).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This spec does not consider the rebuild of the current allocations. Any port
already present in a host that creates a new resource provider for tunnelled
networks, won’t be allocated. Once there is standard a procedure to perform
this action, a new spec/bug will be created to track this improvement, but
this is out of scope in this spec.&lt;/p&gt;
&lt;p&gt;Part of this RFE will be to document the alternatives the user has to, in
case of having a port with minimum bandwidth rules before enabling this
feature, create the needed allocations:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Live migrate the VM with the port. That will trigger the Placement
scheduling and the allocation creation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detach and attach again the port to the VM. That will have the same
effect. This functionality was added to Nova in Wallaby.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignees:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Rodolfo Alonso Hernandez &amp;lt;&lt;a class="reference external" href="mailto:ralonsoh%40redhat.com"&gt;ralonsoh&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt; (IRC: ralonsoh)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;ML2 plugin update.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Migration script to log those existing ports with minimum bandwidth rules
in tunnelled networks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation, including the methods to re-created the allocations for pre-
created ports.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests and CI related changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit/functional tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fullstack tests: increase the current fullstack tests coverage to check
this new feature.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests: create a VM with a minimum bandwidth port, update the
QoS policy and minimum bandwidth rule limits, unset the QoS policy,
migrate the VM.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Ammend the “Strict minimum bandwidth support” &lt;a class="footnote-reference brackets" href="#id8" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; documentation, adding this
new improvement.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id6"&gt;3&lt;/a&gt;,&lt;a role="doc-backlink" href="#id7"&gt;4&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;[RFE] Strict minimum bandwidth support (egress)
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1578989"&gt;https://bugs.launchpad.net/neutron/+bug/1578989&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id9" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/q/%25231578989"&gt;https://review.opendev.org/q/%25231578989&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://networklessons.com/cisco/ccnp-encor-350-401/introduction-to-virtual-extensible-lan-vxlan"&gt;https://networklessons.com/cisco/ccnp-encor-350-401/introduction-to-virtual-extensible-lan-vxlan&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id11" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/599c81767ea7aa3bde7a64ff57b20f34fb314548/neutron/conf/plugins/ml2/drivers/ovs_conf.py#L44-L50"&gt;https://github.com/openstack/neutron/blob/599c81767ea7aa3bde7a64ff57b20f34fb314548/neutron/conf/plugins/ml2/drivers/ovs_conf.py#L44-L50&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Mon, 03 Oct 2022 00:00:00 </pubDate></item><item><title>Metadata rate limit</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/2023.1/metadata-rate-limit.html</link><description>

&lt;p&gt;Launchpad Bug:
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1989199"&gt;https://bugs.launchpad.net/neutron/+bug/1989199&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The metadata agents currently do not limit the number of requests they try to
process. Mis-behaved instances repetitively querying the metadata endpoint can
incur a high load on services above the metadata-agents (Nova and Neutron).&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Platform administrators would benefit from being able to rate-limit requests
handled by metadata in order to protect other OpenStack components from DoS.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Rate-limiting should be configurable via the config files&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Requests should be rate-limited by source IP&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The default settings for the rate-limiting should not impact the normal
provisioning of an instance (eg. through cloud-init)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The metadata agent (both in the case of OVN and OVS/linuxbridge) receive
instances requests through an haproxy process it configures.&lt;/p&gt;
&lt;p&gt;We could leverage haproxy’s stick-tables to implement rate-limiting, similar
to what is done in this haproxy configuration example &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. Concretely,
requests coming-in from IPs that have a request rate above a configured
threshold would receive 429s from haproxy, without hitting the metadata-agent.&lt;/p&gt;
&lt;p&gt;As far as configuration is concerned, we would introduce some new directives
to enable the rate-limiting and to configure the thresholds and time-window
sizes.&lt;/p&gt;
&lt;p&gt;In order to accommodate some events that normally occur during the life of an
instance (for example: cloud-init, periodic refresh of the network-metadata),
we could make the rate-limit burstable, for example: limit the request rate
to 30 over 60s and to 10 over 5s. This could be implemented by creating two
stick-tables holding the request rates over a long base window and over a
short burst window and by denying requests coming from an IP when its request
rate crosses either the base or the burst threshold.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="impact"&gt;
&lt;h2&gt;Impact&lt;/h2&gt;
&lt;section id="configuration-impact"&gt;
&lt;h3&gt;Configuration impact&lt;/h3&gt;
&lt;p&gt;Add new configuration directives to enable and control the rate-limiting:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;rate_limit_enabled (bool): Whether or not to enable request rate-limiting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;base_window_duration (seconds): Duration of the base window&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;burst_window_duration (seconds): Duration of the burst window&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;base_query_rate_limit (short): Limit of the query rate expressed over the
duration of the base window.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;burst_query_rate_limit (short): Limit of the query rate expressed over the
duration of the burst window.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="metadata-s-haproxy-impact"&gt;
&lt;h3&gt;Metadata’s haproxy impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add two backends meant to hold the stick-tables storing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;http_req_rate&lt;/span&gt;&lt;/code&gt;
per ip for the base window and for the burst window.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the listener, deny requests with 429 if &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;src_http_req_rate&lt;/span&gt;&lt;/code&gt; is greater
than the configured threshold of either the base or burst limits.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the listener, track requests in both the base and burst stick-tables.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Guillaume Espanel &amp;lt;&lt;a class="reference external" href="mailto:guillaume.espanel%40gmail.com"&gt;guillaume&lt;span&gt;.&lt;/span&gt;espanel&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests to ensure haproxy’s configuration is built according to the
config parameters.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;HAProxy Rate Limiting: Four Examples, July 30, 2019
&lt;a class="reference external" href="https://www.haproxy.com/blog/four-examples-of-haproxy-rate-limiting/#sliding-window-rate-limiting"&gt;https://www.haproxy.com/blog/four-examples-of-haproxy-rate-limiting/#sliding-window-rate-limiting&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Fri, 09 Sep 2022 00:00:00 </pubDate></item><item><title>Firewall Group Ordering on Port Association</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/zed/fwaas-group-ordering.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1979816"&gt;https://bugs.launchpad.net/neutron/+bug/1979816&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, packets will sometimes be passed, and other times be blocked,
depending on the ordering of groups applied to a port. This is contrary
to the existing FWaaS spec, which states that a packet will be allowed so long
as any group on the port would allow the packet.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;When multiple firewall groups are applied to a port, the order in which the
groups are evaluated can change whenever one of the groups is modified. Therefore,
the combined firewall ruleset that results from multiple firewall groups is
rearranged unintentionally. This can result in certain traffic being allowed or
denied when the opposite behavior would be intended.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Similar to &lt;cite&gt;firewall_policy_rule_associations_v2&lt;/cite&gt;, the
&lt;cite&gt;firewall_group_port_associations_v2&lt;/cite&gt; table should have a required
&lt;cite&gt;position&lt;/cite&gt; column to maintain the order in which &lt;cite&gt;firewall groups&lt;/cite&gt; are
applied to ports.&lt;/p&gt;
&lt;p&gt;In addition, modification of this ordering should be limited by user role.
For example, an openstack administrator may want a particular group to always be
applied first or last, regardless of which groups are added to a port by a tenant.
In iptables, this is typically referred to as &lt;cite&gt;HEAD&lt;/cite&gt; and &lt;cite&gt;TAIL&lt;/cite&gt; rules. All &lt;cite&gt;HEAD&lt;/cite&gt;
groups should be applied first, in order. All &lt;cite&gt;TAIL&lt;/cite&gt; groups should be applied last,
in order. All other groups would be applied in between, again, in order. Only
openstack users with the &lt;cite&gt;admin&lt;/cite&gt; role should have access to the &lt;cite&gt;HEAD&lt;/cite&gt; and &lt;cite&gt;TAIL&lt;/cite&gt;
tiers by default.&lt;/p&gt;
&lt;p&gt;Ex.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;firewall_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;port_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;position&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;tier&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;da4be831-907b-43d9-86e0-b14a3bd391fc&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;efb7d60e-d3fc-4f97-91ed-ca71d930bb7c&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HEAD&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;0814e179-d2be-464a-a9d4-e13c94451532&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;efb7d60e-d3fc-4f97-91ed-ca71d930bb7c&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HEAD&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;33ce9937-d9db-48b8-a65d-05fa3a75844a&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;efb7d60e-d3fc-4f97-91ed-ca71d930bb7c&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;null&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;6b3172af-9ae0-40e4-b455-c70de7c80c24&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;efb7d60e-d3fc-4f97-91ed-ca71d930bb7c&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;null&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;70a7087e-c6ae-4cef-9b30-35e702746b68&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;efb7d60e-d3fc-4f97-91ed-ca71d930bb7c&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;TAIL&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;ff1e5eda-c285-4ec2-80f8-49f1a6d77347&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;efb7d60e-d3fc-4f97-91ed-ca71d930bb7c&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;TAIL&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;cite&gt;Position&lt;/cite&gt; should auto-increment if the &lt;cite&gt;position&lt;/cite&gt; keyword is not specified. If the
&lt;cite&gt;position&lt;/cite&gt; keyword is specified, and that number is available, that number is used.
If the number is already used, the existing groups are shifted downward from that point,
and the new group is applied in its place. For example, if positions 1-5 are in use, and
position 2 is added, the table would be updated as follows:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;position&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;new position&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;New Group (2)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;3&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;3&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;4&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;5&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;5&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;6&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;&lt;cite&gt;PUT&lt;/cite&gt; and &lt;cite&gt;POST&lt;/cite&gt; types for &lt;cite&gt;/v2.0/fw/firewall_groups&lt;/cite&gt; will be updated to support the addition
of &lt;cite&gt;position&lt;/cite&gt; and &lt;cite&gt;tier.&lt;/cite&gt;&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Response bodies should include the new fields.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;# Create (POST)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"ports"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
             &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;
         &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"FW_GROUP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"tier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"HEAD"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Update (PUT)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"ports"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
             &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;
         &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"FW_GROUP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"tier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"TAIL"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;2. &lt;cite&gt;GET&lt;/cite&gt; requests for both list and show methods should include the new values
in their responses.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;# List/Show (GET) Response&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"ingress_firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"egress_firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"FW_GROUP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"ports"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
                 &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;
             &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s2"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"tier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"TAIL"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;&lt;cite&gt;position&lt;/cite&gt; and &lt;cite&gt;tier&lt;/cite&gt; are to be added to the &lt;cite&gt;firewall_group_port_associations_v2&lt;/cite&gt; table.&lt;/p&gt;
&lt;p&gt;Existing entries should be assigned consecutive &lt;cite&gt;position&lt;/cite&gt; numbers starting at 1, and the
default &lt;cite&gt;tier&lt;/cite&gt; value of &lt;cite&gt;null.&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Firewall Group Port associations&lt;/strong&gt;&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;position&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Y&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Position at which this firewall group is evaluated&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;tier&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Y&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Tier at which this firewall group exists (HEAD, TAIL, null) Default: null&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.opendev.org/p/fwaas-api-evolution-spec"&gt;https://etherpad.opendev.org/p/fwaas-api-evolution-spec&lt;/a&gt;
&lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/newton/fwaas-api-2.0.html"&gt;https://specs.openstack.org/openstack/neutron-specs/specs/newton/fwaas-api-2.0.html&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 29 Jul 2022 00:00:00 </pubDate></item><item><title>Floating IP distributed</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/zed/custom-floatingip-distributed.html</link><description>

&lt;p&gt;Launchpad Bug:
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1978039"&gt;https://bugs.launchpad.net/neutron/+bug/1978039&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron adds distributed attributes to each Floating IP. Users can set this
attribute according to their actual environment and use requirements.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Neutron supports setting the floating IP to distributed. External traffic
can go directly to the compute node without passing through the network
node, and increases the network performance. This is very useful for the
demand for high-performance networks.&lt;/p&gt;
&lt;p&gt;However, we can decide whether floating ips are distributed or centralized by
setting configuration option(ovn backend) or setting router’s “distributed”
attribute(ovs dvr mode). This is global. After configuration, all floating
ips are centralized or distributed.&lt;/p&gt;
&lt;p&gt;The actual use may be complicated:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Not all vms with floating ip may require high-performance networks, and may
only be exposed to the outside world to provide services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Due to equipment conditions, some compute nodes are not equipped with
external network card. If enable distributed, the vm of this compute node
cannot allocate floating ip.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Add new API extension to extend &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;floatingip&lt;/span&gt;&lt;/code&gt; resource in Neutron with
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;distributed&lt;/span&gt;&lt;/code&gt; attribute.
If not set this attribute, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;distributed&lt;/span&gt;&lt;/code&gt; attribute of the router
will be used for the floating ip &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;section id="server-side-changes"&gt;
&lt;h3&gt;Server side changes&lt;/h3&gt;
&lt;p&gt;A new API extension of Neutron will be added with new attribute for the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;floatingip&lt;/span&gt;&lt;/code&gt; resource. This new attribute will be called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;distributed&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;l3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FLOATINGIPS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"distributed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;converters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_boolean_if_not_none&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ATTR_NOT_SPECIFIED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="db-impact"&gt;
&lt;h3&gt;DB Impact&lt;/h3&gt;
&lt;p&gt;Extend the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;floatingips&lt;/span&gt;&lt;/code&gt; table with boolean column &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;distributed&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;New API extension: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;floatingip-distributed&lt;/span&gt;&lt;/code&gt; introducing new floatingip
attribute: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;distributed&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="client-impact"&gt;
&lt;h3&gt;Client Impact&lt;/h3&gt;
&lt;p&gt;Relevant changes in OSC and openstacksdk to add support for new floatingip’s
attribute. To enable it for floatingip, it should be something like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;floating&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;distributed&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and to disable it:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;floating&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;centralized&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and update it:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;floating&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;distributed&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;centralized&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functional test.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests in neutron-tempest-plugin.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;ZhouHeng &amp;lt;&lt;a class="reference external" href="mailto:zhouhenglc%40inspur.com"&gt;zhouhenglc&lt;span&gt;@&lt;/span&gt;inspur&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Neutron Drivers meeting, June 24, 2022
&lt;a class="reference external" href="https://meetings.opendev.org/meetings/neutron_drivers/2022/neutron_drivers.2022-06-24-14.00.log.html#l-116"&gt;https://meetings.opendev.org/meetings/neutron_drivers/2022/neutron_drivers.2022-06-24-14.00.log.html#l-116&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Mon, 27 Jun 2022 00:00:00 </pubDate></item><item><title>Multiple routed provider segment per host</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/zed/multiple-routed-provider-network-per-compute.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1764738"&gt;https://bugs.launchpad.net/neutron/+bug/1764738&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The proposed spec is to extend the current feature routed provider
networks &lt;a class="footnote-reference brackets" href="#id11" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;0&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; to allow provisioning more than one segment per physical
network.&lt;/p&gt;
&lt;p&gt;There is currently a limitation for a compute node to only have an
interface on one segment in a multisegment network. Operators that
want to extend IP range will have to provision new networks which
degrade user experience, or increase the broadcast domain which does
not scale.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;As an operator I want to extend IP pool without creating multiple
networks. I also want to limit the brodcast domain.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The change is limited to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;OVS&lt;/span&gt; &lt;span class="pre"&gt;agent&lt;/span&gt;&lt;/code&gt;, it will be still possible to
implement it for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;linux-bridge&lt;/span&gt;&lt;/code&gt;. That is said, this implementation
is out of the scope of the proposed spec.&lt;/p&gt;
&lt;p&gt;The main purpose is to add the support for an interface of a compute
node to be attached to more than one segment of a given network.&lt;/p&gt;
&lt;p&gt;This implies changes on different components. The DHCP agent currently
only supports one interface per network. It will be necessary to
extend it to support more domains per network. The VLAN manager that
maintains details of VLAN ports for OVS by using network id will have
to be updated to use segment id instead. The agent will have to be
updated to support the feature and finally the limitation that rejects
such case will have to be removed.&lt;/p&gt;
&lt;section id="vlan-manager"&gt;
&lt;h3&gt;VLAN Manager&lt;/h3&gt;
&lt;p&gt;The current implementation for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VLAN&lt;/span&gt; &lt;span class="pre"&gt;manager&lt;/span&gt;&lt;/code&gt; that maintains
internal VLAN mapping to external network segmentation ids is using
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network&lt;/span&gt; &lt;span class="pre"&gt;ids&lt;/span&gt;&lt;/code&gt; as principal identifier &lt;a class="footnote-reference brackets" href="#id12" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.  This will have to
be updated to use a combination of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network&lt;/span&gt; &lt;span class="pre"&gt;ids&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;segment&lt;/span&gt; &lt;span class="pre"&gt;ids&lt;/span&gt;&lt;/code&gt;.
This should not implies upgrade impact as they are in-memory and
recalculated after restarts.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="dhcp-agent"&gt;
&lt;h3&gt;DHCP Agent&lt;/h3&gt;
&lt;p&gt;Using multiple segments per network implies more than one network
domain. The current DHCP agent supports one domain per network
&lt;a class="footnote-reference brackets" href="#id13" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A DHCP port is plugged to the internal bridge using the local VLAN
provided by the VLAN manager for a given network. This means that the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DHPC&lt;/span&gt; &lt;span class="pre"&gt;Process&lt;/span&gt;&lt;/code&gt; running can address reauest for one domain. To reflect
the current desire of multiple domains per network, a DHCP port should
be plugged to br-int per combination of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network&lt;/span&gt; &lt;span class="pre"&gt;id&lt;/span&gt; &lt;span class="pre"&gt;/&lt;/span&gt; &lt;span class="pre"&gt;segmentation&lt;/span&gt;
&lt;span class="pre"&gt;id&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The proposed implementation is to avoid changing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DHCP&lt;/span&gt; &lt;span class="pre"&gt;Process&lt;/span&gt;&lt;/code&gt;
logic to make it supporting more than one interface per VLAN as it
will add complexity and may imply upgrade impact.  Instead, it has
been considered to keep the well trusted logic of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DHCP&lt;/span&gt; &lt;span class="pre"&gt;Process&lt;/span&gt;&lt;/code&gt;
to use one per segmentation id. One may in future consider to revisit
this implementation.&lt;/p&gt;
&lt;p&gt;The benefit of having one &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DHCP&lt;/span&gt; &lt;span class="pre"&gt;Process&lt;/span&gt;&lt;/code&gt; running per local VLAN will
limit the changes and avoid upgrade impact. For a deployment already
running routed network provider, two &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DHCP&lt;/span&gt; &lt;span class="pre"&gt;process&lt;/span&gt;&lt;/code&gt; will be
running. One considered as legacy running under &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/net-id/pid&lt;/span&gt;&lt;/code&gt;, and
an other running at &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/seg-id/net-id/pid&lt;/span&gt;&lt;/code&gt;. It will involve the
operator to remove the legacy port using opentack API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="limitations"&gt;
&lt;h3&gt;Limitations&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The proposed spec only implies OVS support but it should be
possible to provide the same kind of support for
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;linux-bridge&lt;/span&gt;&lt;/code&gt;. A change has been proposed with &lt;a class="footnote-reference brackets" href="#id14" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; with related
spec &lt;a class="footnote-reference brackets" href="#id16" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; It implies an upgrade impact which can be mitigated like
for this proposed OVS implementation. Also that the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;linux-bridge&lt;/span&gt;&lt;/code&gt; implementation can take benefit of the change in
DHCP agent which is missed in the proposed change for
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;linux-bridge&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For a given fixed ip, during scheduling Nova will not be able
creating a port a the segment related to the subnet of the fixed
ip. It’s an already known limitation. Bug 1979959 &lt;a class="footnote-reference brackets" href="#id20" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;9&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; has been
reported to address the issue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A regression has been noted since the bug 1952730 &lt;a class="footnote-reference brackets" href="#id19" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, with routed
provider segments created are not taken into account. Bug 1979958
&lt;a class="footnote-reference brackets" href="#id18" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="notes"&gt;
&lt;h3&gt;Notes&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In its process Nova needs to retrieve network details &lt;a class="footnote-reference brackets" href="#id15" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. In case
of a given network with multiple segments the process will use the
first segment that it discovers with a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;physcal_network&lt;/span&gt;&lt;/code&gt;. This is
a design issue that is already known. The process change is not
expected to fix it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To have Nova schedule instances on hosts based on segments where
ports are attached to. Aggregates are created per segment &lt;a class="footnote-reference brackets" href="#id17" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. The
process is using segment ids as names. It is still expected to
continue creating aggregates with the new segment created for a
given network. This should not bring any issue.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="primary-assignees"&gt;
&lt;h3&gt;Primary Assignees&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Sahid Orentino Ferdjaoui&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id11" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;0&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/admin/config-routed-networks.html"&gt;https://docs.openstack.org/neutron/latest/admin/config-routed-networks.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/master/neutron/plugins/ml2/drivers/openvswitch/agent/vlanmanager.py#L87"&gt;https://github.com/openstack/neutron/blob/master/neutron/plugins/ml2/drivers/openvswitch/agent/vlanmanager.py#L87&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id13" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/master/neutron/agent/linux/dhcp.py#L286"&gt;https://github.com/openstack/neutron/blob/master/neutron/agent/linux/dhcp.py#L286&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id14" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/neutron/+/623115"&gt;https://review.opendev.org/c/openstack/neutron/+/623115&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id15" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/nova/blob/master/nova/network/neutron.py#L2141"&gt;https://github.com/openstack/nova/blob/master/nova/network/neutron.py#L2141&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id16" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/neutron-specs/+/657170"&gt;https://review.opendev.org/c/openstack/neutron-specs/+/657170&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id17" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id10"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://opendev.org/openstack/neutron/src/branch/master/neutron/services/segments/plugin.py#L180"&gt;https://opendev.org/openstack/neutron/src/branch/master/neutron/services/segments/plugin.py#L180&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id18" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1979958"&gt;https://bugs.launchpad.net/neutron/+bug/1979958&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id19" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1952730"&gt;https://bugs.launchpad.net/neutron/+bug/1952730&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id20" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;9&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/nova/+bug/1979959"&gt;https://bugs.launchpad.net/nova/+bug/1979959&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Thu, 17 Mar 2022 00:00:00 </pubDate></item><item><title>Distributed Router Advertisement on Openvswitch Agent</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/zed/ovs_agent_ext_ra.html</link><description>

&lt;p&gt;RFE: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1961011"&gt;https://bugs.launchpad.net/neutron/+bug/1961011&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron L3 router will run &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;radvd&lt;/span&gt;&lt;/code&gt; to send out RA (Router Advertisement)
packets to notify the guests about the subnet ManagedFlag, LinkMTU and prefix
of IPv6 subnet. This is fine to work for small scale clouds, or long stand
clouds with no changes. But for large scale cloud environments, management
complexity increases.&lt;/p&gt;
&lt;p&gt;Neutron openvswitch agent can be considered as a distributed SDN controller,
this spec describes how to make RA work on each compute node in distributed
mode without any extra processes.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;radvd&lt;/span&gt;&lt;/code&gt; is spawned in L3 router namespaces, which will multicast a
RA on the subnet from the router interface, reaching all attached VMs.
Current radvd config looks like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;fd65326&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c4&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;AdvSendAdvert&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;MinRtrAdvInterval&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;MaxRtrAdvInterval&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;AdvLinkMTU&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;AdvManagedFlag&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;prefix&lt;/span&gt; &lt;span class="n"&gt;fda7&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;a5cc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3460&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;AdvOnLink&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;AdvAutonomous&lt;/span&gt; &lt;span class="n"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In order to do such work, L3 agent needs to do:
* start a process manager for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;radvd&lt;/span&gt;&lt;/code&gt;
* render the config for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;radvd&lt;/span&gt;&lt;/code&gt;
* monitor the extra process in case of unexpected exit
* respawn the process if something changes&lt;/p&gt;
&lt;p&gt;For a DVR router, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;radvd&lt;/span&gt;&lt;/code&gt; will be run in every local router namespace
on the compute node as well.&lt;/p&gt;
&lt;p&gt;In certain cases, this increases the number of server processes, increases
the resource consumption of the server, increases the failure point and reduces
the processing performance of the L3 agent.&lt;/p&gt;
&lt;p&gt;There is a defect of current RA mechanism. It forces the subnet to have
association with a Neutron router, if you want Neutron to manage the IPv6
related configurations &lt;a class="footnote-reference brackets" href="#id4" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. Then if a subnet does not connect to a router,
no radvd answers the RS request, no RA back. VMs under isolated networks
will get failed to find out how to do with IPv6 address, how to configure
IPv6 address, how to do with DHCPv6.&lt;/p&gt;
&lt;p&gt;So, this agent extension will make isolated networks can work for IPv6.
VM under it will get RA about the IPv6 subnets prefixes, autonomous address
configuration flag, managed address configuration flag and other configuration
flag and so on. VMs under the isolated networks are going to work with IPv6
based on these flags.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Adds an agent extension for Neutron openvswitch agent to send RA out to local
guests in a more natural and graceful style.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This extension is only for openvswitch agent, other mechanism drivers
will not be considered, because this new extension will rely on the
openflow protocol and principle.&lt;/p&gt;
&lt;/div&gt;
&lt;section id="solution-proposed"&gt;
&lt;h3&gt;Solution Proposed&lt;/h3&gt;
&lt;p&gt;The new agent extension will use os-ken(ryu) &lt;a class="footnote-reference brackets" href="#id3" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; to assemble the RA packets,
and then directly do packet-out to the ofport (VM port). Mission accomplished,
very simple! Some main code procedure will be:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;new extension initialized with a subnet cache list&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;start a periodic loop to send RA to each port from those subnets&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;handle_port&lt;/span&gt;&lt;/code&gt; method each VM port’s subnet will be added to the cache&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;delete_port&lt;/span&gt;&lt;/code&gt; remove the VM port from subnet’s port cache&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get subnet information by the resource cache RPC&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;looping of sending RA to each port&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Openvswitch agent will pull ports, subnets and networks information by
“resource cache” related RPC.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;For some cases, neutron router will interact with the upstream physical
router. This extension will not handle such configurations and
deployment architecture.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The attribute &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ipv6_ra_mode&lt;/span&gt;&lt;/code&gt; of subnet is None, then Neutron will not
generate RA to VMs. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ipv6_ra_mode&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;None&lt;/span&gt;&lt;/code&gt; will be used to indicate if
there are external (physical) routers.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;LIU Yulong &amp;lt;&lt;a class="reference external" href="mailto:i%40liuyulong.me"&gt;i&lt;span&gt;@&lt;/span&gt;liuyulong&lt;span&gt;.&lt;/span&gt;me&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Adding ovs-agent extension to do the RA work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make L3-agent radvd configurable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Test cases to verify the RA can work for ports.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://ryu.readthedocs.io/en/latest/library_packet_ref/packet_icmpv6.html#ryu.lib.packet.icmpv6.nd_router_advert"&gt;https://ryu.readthedocs.io/en/latest/library_packet_ref/packet_icmpv6.html#ryu.lib.packet.icmpv6.nd_router_advert&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/admin/config-ipv6.html"&gt;https://docs.openstack.org/neutron/latest/admin/config-ipv6.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 08 Mar 2022 00:00:00 </pubDate></item><item><title>Off-path SmartNIC DPU Port Binding with OVN</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/yoga/off-path-smartnic-dpu-port-binding-with-ovn.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/off-path-smartnic-dpu-port-binding-with-ovn"&gt;https://blueprints.launchpad.net/neutron/+spec/off-path-smartnic-dpu-port-binding-with-ovn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Off-path SmartNIC DPUs introduce an architecture change where network
agents responsible for NIC switch configuration and representor
interface plugging run on a separate SoC with its own CPU, memory and
that runs a separate OS kernel. The side-effect of that is that
hypervisor hostnames no longer match SmartNIC DPU hostnames which are
seen by ovs-vswitchd and OVN &lt;a class="footnote-reference brackets" href="#id26" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; agents while the existing port binding
code relies on that. The goal of this specification is to introduce
changes necessary to extend the existing hardware offload code to cope
with the hostname mismatch and related design challenges while reusing
the rest of the code. To do that, PCI(e) add-in card tracking is
introduced for cards with unique serial numbers so that it can be used
to determine the correct hostname of a SmartNIC DPU which is responsible
for a particular VF. Additionally, more information is suggested to be
passed in the “binding:profile” during a port update to facilitate
representor port plugging.&lt;/p&gt;
&lt;p&gt;Nova spec: &lt;a class="reference external" href="https://review.opendev.org/c/openstack/nova-specs/+/787458"&gt;https://review.opendev.org/c/openstack/nova-specs/+/787458&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;section id="terminology"&gt;
&lt;h3&gt;Terminology&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Data Processing Unit (DPU) - an embedded system that includes a CPU, a NIC
and possibly other components on its board which integrates with the main
board using some I/O interconnect (e.g. PCIe);&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Off-path SmartNIC DPU architecture &lt;a class="footnote-reference brackets" href="#id24" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id25" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; - an architecture where NIC
cores are responsible for programming a NIC Switch and are bypassed when
rules programmed into the NIC Switch are enough to make a decision on where
to deliver packets. Normally, NIC cores only participate in packet forwarding
for the “slow path” only and the “fast path” is handled in hardware like an
ASIC;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On-path SmartNIC DPU architecture &lt;a class="footnote-reference brackets" href="#id24" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id25" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; - an architecture where NIC cores
participate in processing of every packet going through the NIC as a whole.
In other words, NIC cores are always on the “fast path” of all packets;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NIC Switch (or eSwitch) - a programmable embedded switch present in various
types of NICs (SR-IOV-capable NICs, off-path SmartNICs). Typically relies
on ASICs for packet processing;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;switchdev &lt;a class="footnote-reference brackets" href="#id27" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; - in-kernel driver model for switch devices which offload the
forwarding (data) plane from the kernel.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Representor ports &lt;a class="footnote-reference brackets" href="#id28" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; - a concept introduced in the switchdev model which
models netdevs representing switch ports. This applies to NIC switch ports
(which can be physical uplink ports, PFs or VFs);&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;devlink &lt;a class="footnote-reference brackets" href="#id29" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; - a kernel API to expose device information and resources not
directly related to any device class, such as chip-wide/switch-ASIC-wide
configuration;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PCI/PCIe Vital Product Data (VPD) - a standard capability exposed by PCI(e)
endpoints which, among other information, includes a unique serial number
(read-only, persistent, factory-generated) of a card shared by all functions
exposed by it. Present in PCI local bus 2.1+ and PCIe 4.0+ specifications.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="detailed-overview"&gt;
&lt;h3&gt;Detailed overview&lt;/h3&gt;
&lt;p&gt;The related Nova specification &lt;a class="footnote-reference brackets" href="#id30" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; is an integral part of the cross-project
effort and its problem description is assumed to be a part of this
specification.&lt;/p&gt;
&lt;p&gt;There are also relevant changes to OVS &lt;a class="footnote-reference brackets" href="#id31" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and OVN itself &lt;a class="footnote-reference brackets" href="#id32" id="id11" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;9&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id33" id="id12" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;10&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; that
are needed in order to facilitate the implementation of this specification
in Neutron. The result of upstream OVN discussions has been that a separate
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ovn-vif&lt;/span&gt;&lt;/code&gt; &lt;a class="footnote-reference brackets" href="#id34" id="id13" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;11&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; component is going to be introduced and the corresponding
change &lt;a class="footnote-reference brackets" href="#id33" id="id14" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;10&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; is in the late stages of the review process at the time of writing.
Support in other ML2 mechanism drivers is possible, but we would like to target
OVN first and leave other ML2 drivers out of scope for Yoga cycle.&lt;/p&gt;
&lt;p&gt;In the context of off-path SmartNIC DPUs, the main problems that need to be
addressed in this change are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;SmartNIC DPU hostname selection such that the correct host is selected for
representor port plugging. This corresponds to selecting the right chassis
(transport node) in OVN terms;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VF representor selection corresponding the VF and a PF it is associated with
selected at the hypervisor host side by Nova.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some practical challenges are as follows:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If PCIe is used to access the NIC at a SmartNIC DPU host, PCI addresses seen
by the hypervisor host and the SmartNIC DPU host differ as they have their
own root complexes and see isolated PCIe topologies (while communicating
with the same NIC). Therefore, PCI addresses seen from the SmartNIC DPU host
side have no meaning at the hypervisor host side;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A NIC Switch is not exposed to PFs at the hypervisor host side. Meanwhile,
PF representor numbers are tied to a particular NIC Switch (to a controller
number) at the SmartNIC DPU host side. There may be multiple controllers per
SmartNIC DPU host in a general case so simply passing PF logical numbers from
the host side is not enough to identify a PF representor at the transport
node side;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VF logical numbering seen via devlink port attributes depends on a device
driver implementation at the hypervisor host and does not always match what
is seen at the SmartNIC DPU host via the NIC Switch. It is possible to
retrieve VF logical numbers tied to PFs at the hypervisor side based on the
VF PCI address assignment process governed by the PCI SIG SR-IOV
specification;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;During port binding, the OVN mechanism driver needs to handle the vnic type
VNIC_REMOTE_MANAGED which it currently does not.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following diagram illustrates various components that play a role in the
context of this specification:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                       ┌────────────────────────────────────┐
                       │  Hypervisor                        │    LoM Ports
                       │  ┌───────────┐       ┌───────────┐ │   (on-board,
                       │  │ Instance  │       │  Nova     │ ├──┐ optional)
                       │  │ (QEMU)    │       │ Compute   │ │  ├─────────┐
                       │  │           │       │           │ ├──┘         │
                       │  └───────────┘       └───────────┘ │            │
                       │                                    │            │
                       └────────────────┬─┬───────┬─┬──┬────┘            │
                                        │ │       │ │  │                 │
                                        │ │       │ │  │ Control Traffic │
                           Instance VF  │ │       │ │  │ PF associated   │
                                        │ │       │ │  │ with an uplink  │
                                        │ │       │ │  │ port or a VF.   │
                                        │ │       │ │  │ (used to replace│
                                        │ │       │ │  │  LoM)           │
   ┌────────────────────────────────────┼─┼───────┼─┼──┼─┐               │
   │   SmartNIC DPU Board               │ │       │ │  │ │               │
   │   (transport node)                 │ │       │ │  │ │               │
   │  ┌──────────────┐ Control traffic  │ │       │ │  │ │               │
   │  │   App. CPU   │ via PFs or VFs  ┌┴─┴───────┴─┴┐ │ │               │
   │  ├──────────────┤  (DC Fabric)    │             │ │ │               │
   │  │ovn-controller├─────────────────┼─┐           │ │ │               │
   │  ├──────────────┤                 │ │           │ │ │               │
   │  │ovs-vswitchd  │     Port        │ │NIC Switch │ │ │               │
   │  ├──────────────┤   Representors  │ │  ASIC     │ │ │               │
   │  │    br-int    ├─────────────────┤ │           │ │ │               │
   │  │              ├─────────────────┤ │           │ │ │               │
   │  └──────────────┘                 │ │           │ │ │               │
   │                                   │ │           │ │ │               │
   │                                   └─┼───┬─┬─────┘ │ │               │
 ┌─┴──────┐Initial NIC Switch            │   │ │       │ │               │
─┤OOB Port│configuration is done via     │   │ │uplink │ │               │
 └─┬──────┘the OOB port to create        │   │ │       │ │               │
   │       ports for control traffic.    │   │ │       │ │               │
   └─────────────────────────────────────┼───┼─┼───────┼─┘               │
                                         │   │ │       │                 │
                                      ┌──┼───┴─┴───────┼────────┐        │
                                      │  │             │        │        │
                                      │  │   DC Fabric ├────────┼────────┘
                                      │  │             │        │
                                      └──┼─────────────┼────────┘
                                         │             │
                                         │         ┌───┴──────┐
                                         │         │          │
                                     ┌───▼──┐  ┌───▼───┐ ┌────▼────┐
                                     │OVN SB│  │Neutron│ │Placement│
                                     └──────┘  │Server │ │         │
                                               └───────┘ └─────────┘
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="identifying-a-smartnic-dpu-host-and-vf-representor"&gt;
&lt;h3&gt;Identifying a SmartNIC DPU Host and VF Representor&lt;/h3&gt;
&lt;p&gt;The related Nova specification &lt;a class="footnote-reference brackets" href="#id30" id="id15" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; introduces add-in-card serial
number collection via PCIe VPD and forwarding of that information in port
updates to Neutron, therefore, it becomes possible to match that against what
is seen at the SmartNIC DPU host side. Those serial numbers are unique,
read-only, and assigned at the manufacturing time (per the PCI and PCIe specs).
The board serial number can be stored in the OVN SB database as an external-id
for a particular OVN chassis:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;external_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ovn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cms&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'card-serial-number=UNIQUEBOARDSERIAL'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that there can be other means of accessing the NIC from the SmartNIC DPU
host side (e.g. platform devices or other I/O types) so querying the serial
number can be done either by extracting PCIe VPD via sysfs or by using
devlink-info API and getting &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;board.serial_number&lt;/span&gt;&lt;/code&gt; (which does not depend
on a particular I/O interconnect type). However, this is a concern for OVN
itself since Neutron does not have any agents running at the SmartNIC DPU side
- it only needs to look up a chassis by a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;card-serial-number&lt;/span&gt;&lt;/code&gt;
regardless of how it got collected at the SmartNIC DPU host.&lt;/p&gt;
&lt;p&gt;The responsibility of placing it there can be given to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A deployer who will be responsible of configuring the ovn-controller agent
to be responsible for a particular transport node;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ovn-controller itself based on some default behavior of looking up a card
serial number based on the switchdev-capable devices available on the
SmartNIC DPU host.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Regardless of the chosen method of populating this value, Neutron will then
be able to lookup which OVN chassis should handle representor plugging and flow
programming for a particular port update that has a card serial included.&lt;/p&gt;
&lt;p&gt;VF logical numbers are relevant in the context of a particular PF. In turn,
PF logical numbers are tied to a particular controller. Since a NIC Switch is
not exposed to the hypervisor host, it cannot determine the controller logical
number as visible by the SmartNIC DPU host and while PF numbers could be
inferred indirectly from their PCI address function numbers, this information
is not enough to identify a PF representor at the SmartNIC DPU host side.
To address that, a PF MAC seen by the hypervisor host can be passed to the
SmartNIC DPU host. While port representors have a different MAC address from
the port they represent, it is possible to use generic in-kernel API to
retrieve a MAC address of a function via its representer (as of kernel
5.9 &lt;a class="footnote-reference brackets" href="#id35" id="id16" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;12&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, subject to the switchdev-aware device driver support, for example
&lt;a class="footnote-reference brackets" href="#id36" id="id17" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;13&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;). While Neutron will not be responsible for doing this lookup (OVN will),
it needs to accept and forward this information to OVN.&lt;/p&gt;
&lt;p&gt;As a result, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding:profile&lt;/span&gt;&lt;/code&gt; attribute for a port updated by Nova is
expected to contain the following information:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"pci_vendor_info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"pci_slot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"physical_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"card_serial_number"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"UNIQUEBOARDSERIAL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"pf_mac_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"de:ad:be:ef:ca:fe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"vf_num"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With this information both the right OVN chassis hostname and port
representor at the SmartNIC DPU host side can be identified.&lt;/p&gt;
&lt;p&gt;The OVN mechanism driver also needs to be changed (where relevant) to use the
hostname looked up based on a serial number instead of relying on the
hypervisor hostname passed in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding_host_id&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;After receiving a port update from Nova, Neutron needs to create relevant
Logical Switch Ports in the OVN database (the final approach to communicating
the necessary information to OVN is to be determined based on the outcome of
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ovn-vif&lt;/span&gt;&lt;/code&gt; discussions in upstream OVN):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Logical_Switch_Port&lt;/span&gt;
  &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;requested&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;chassis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fqdn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;smartnic&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dpu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;
  &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;plug&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;representor&lt;/span&gt;
  &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;plug&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mtu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1500&lt;/span&gt;
  &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;plug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;representor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;pf&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mac&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;de&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ad&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;be&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ca&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fe&lt;/span&gt;
  &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;plug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;representor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;vf&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vf-num&lt;/span&gt;&lt;/code&gt; is not specified, then a PF representor should be plugged instead
of a VF representor.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="port-binding-and-port-capabilities"&gt;
&lt;h3&gt;Port Binding and Port Capabilities&lt;/h3&gt;
&lt;p&gt;Currently, to support hardware offload, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;bind_port&lt;/span&gt;&lt;/code&gt; method of the OVN
mechanism driver is able to bind ports of type &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;direct&lt;/span&gt;&lt;/code&gt; if they also have
the “switchdev” capability supplied in their &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding:profile&lt;/span&gt;&lt;/code&gt; attribute:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{"capabilities": ["switchdev"]}'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This capability is discovered by Nova from PCI(e) endpoints via devlink -
when an NIC Switch is visible via a PF, the “switchdev” capability is added to
both PFs and VFs tracked in Nova. SmartNIC DPUs do not expose the NIC Switch to
the hypervisor host, therefore, this capability is not discovered. To address
that, the related Nova specification &lt;a class="footnote-reference brackets" href="#id30" id="id18" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; relies on a new port type for the
purposes of working with SmartNIC DPUs called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VNIC_REMOTE_MANAGED&lt;/span&gt;&lt;/code&gt;. The
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VNIC_SMARTNIC&lt;/span&gt;&lt;/code&gt; VNIC type already present in neutron-lib has been considered
but it was found later that the fact that scheduling happens after resource
request creation makes it to run into a conflict with the Ironic use-case).&lt;/p&gt;
&lt;p&gt;The OVN mechanism driver needs to be extended to also handle
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VNIC_REMOTE_MANAGED&lt;/span&gt;&lt;/code&gt; ports. It will allow the port binding code to pick the
right code-path and trigger the representor port plugging logic in OVN.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="primary-assignees"&gt;
&lt;h3&gt;Primary Assignees&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Dmitrii Shcherbakov (lp: ~dmitriis, oftc || libera: dmitriis)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Frode Nordahl (lp: ~fnordahl, oftc || libera: fnordahl)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;OVS &lt;a class="footnote-reference brackets" href="#id31" id="id19" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and OVN &lt;a class="footnote-reference brackets" href="#id32" id="id20" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;9&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id33" id="id21" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;10&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id34" id="id22" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;11&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A related Nova specification &lt;a class="footnote-reference brackets" href="#id30" id="id23" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; depends on this spec;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id24" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id4"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://netdevconf.info/0x14/pub/slides/39/Netdev%200x14%20--%20Taking%20Control%20of%20your%20SmartNIC%20v1.pdf"&gt;https://netdevconf.info/0x14/pub/slides/39/Netdev%200x14%20–%20Taking%20Control%20of%20your%20SmartNIC%20v1.pdf&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id25" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id3"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id5"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://homes.cs.washington.edu/~arvind/papers/ipipe.pdf"&gt;https://homes.cs.washington.edu/~arvind/papers/ipipe.pdf&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id26" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://man7.org/linux/man-pages/man7/ovn-architecture.7.html"&gt;https://man7.org/linux/man-pages/man7/ovn-architecture.7.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id27" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.kernel.org/doc/Documentation/networking/switchdev.txt"&gt;https://www.kernel.org/doc/Documentation/networking/switchdev.txt&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id28" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://lwn.net/Articles/692942/"&gt;https://lwn.net/Articles/692942/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id29" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.kernel.org/doc/html/latest/networking/devlink/index.html"&gt;https://www.kernel.org/doc/html/latest/networking/devlink/index.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id30" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id9"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id15"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id18"&gt;3&lt;/a&gt;,&lt;a role="doc-backlink" href="#id23"&gt;4&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/nova-specs/+/787458"&gt;https://review.opendev.org/c/openstack/nova-specs/+/787458&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id31" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id10"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id19"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openvswitch/ovs/commit/bfee9f6c011518c7690d3ce3b290a2b7189a377d"&gt;https://github.com/openvswitch/ovs/commit/bfee9f6c011518c7690d3ce3b290a2b7189a377d&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id32" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;9&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id11"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id20"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://patchwork.ozlabs.org/project/ovn/list/?series=267834&amp;amp;state=3&amp;amp;archive=both"&gt;https://patchwork.ozlabs.org/project/ovn/list/?series=267834&amp;amp;state=3&amp;amp;archive=both&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id33" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;10&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id12"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id14"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id21"&gt;3&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://patchwork.ozlabs.org/project/ovn/list/?series=269965&amp;amp;state=*&amp;amp;archive=both"&gt;https://patchwork.ozlabs.org/project/ovn/list/?series=269965&amp;amp;state=*&amp;amp;archive=both&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id34" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;11&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id13"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id22"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/fnordahl/ovn-vif"&gt;https://github.com/fnordahl/ovn-vif&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id35" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id16"&gt;12&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2a916ecc405686c1d86f632281bc06aa75ebae4e"&gt;https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2a916ecc405686c1d86f632281bc06aa75ebae4e&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id36" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id17"&gt;13&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f099fde16db3d2594a54ba8c94ce9fa3557aa3e1"&gt;https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f099fde16db3d2594a54ba8c94ce9fa3557aa3e1&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Thu, 17 Feb 2022 00:00:00 </pubDate></item><item><title>Allowed Address Pair: support matching ANY MAC address</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/yoga/allowed-address-pair-match-any-mac-address.html</link><description>

&lt;p&gt;Include the URL of your launchpad RFE:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1946251"&gt;https://bugs.launchpad.net/neutron/+bug/1946251&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Allowed address pairs API allows to match against a subset of IP addresses, or
even all of them, by virtue of netmasks being part of ‘ip_address’ field
format. For example, using ‘0.0.0.0/0’ means allowing any IP address used with
the corresponding MAC address. This proposal suggests extending the API so that
a user can allow any MAC address used with the corresponding IP address.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;An end user would like to configure their topology so that a port enforces
security group rules but allows any MAC addresses. To achieve this, the user:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;creates a security group with appropriate rules;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;creates a port and assigns it to the security group;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;adds allowed address pair for ANY MAC address and some IP address(es).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Right now, the only way to disable MAC address enforcement is to set
port_security_enabled attribute to false. But this attribute also disables
security group rule enforcement. In this scenario, only anti-spoofing
enforcement should be disabled.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposal is to extend ‘allowed_address_pairs’ attribute for ports so that
its ‘mac_address’ field accepts a special value “ANY” that would disable MAC
anti-spoofing mechanism. IP address enforcement may still continue, based on
the corresponding ‘ip_address’ field value of the pair.&lt;/p&gt;
&lt;p&gt;Having multiple address pairs with “ANY” ‘mac_address’ field value is
supported.  Having a list of pairs where some but not all ‘mac_address’ field
values are “ANY” is supported.&lt;/p&gt;
&lt;p&gt;A new Networking API extension will be introduced to indicate support for the
new special value. This support is backend specific, which means that ML2 may
need to offload decision to enable the extension to underlying drivers.&lt;/p&gt;
&lt;p&gt;Database model for allowed address pairs will not need adjustment to accept the
new special value because it already accepts all strings.&lt;/p&gt;
&lt;p&gt;Client library may need to be adjusted to support the new special value “ANY”
for the ‘mac_address’ field in the API validator module.&lt;/p&gt;
&lt;p&gt;For agent-based setups, there are two cases to handle where the firewall driver
chosen implements anti-spoofing / allowed_address_pair handling itself, and
where this task is left to the agent. The firewall driver indicates the former
by setting provides_arp_spoofing_protection attribute to True. In this
scenario, the driver will have to implement handling of the new “ANY” value set
for a MAC-IP pair. A new firewall driver flag (support_any_mac_anti_spoofing)
will be added to indicate support for the new feature, defaults to False. If
the flag is not set, the agent will filter out ANY address pairs before passing
them to the firewall driver. It will also log a warning about the issue. Each
driver that handles anti-spoofing itself will need to opt in receiving “ANY”
address pairs by setting the support_any_mac_anti_spoofing flag to True.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Instead of using a new special value “ANY”, we could introduce a masking scheme
for ‘mac_address’ field. For example, “de:ad:/32” would indicate “any MAC
address that starts with de:ad: prefix”. But it’s debatable whether using any
mask but /0 is generally useful, since MAC addresses are opaque values with no
inherent ordering or grouping (that said, traditionally vendors reuse the same
prefixes for their devices).&lt;/p&gt;
&lt;p&gt;Instead of reusing the existing allowed address pairs API attribute, we could
introduce a new port level attribute that would disable MAC address
anti-spoofing without disabling security group rules. Since SG API still allows
to match against particular IP addresses, this approach would be functionally
identical to this. That said, I think it’s generally better to avoid
introducing new attributes to base resources, and it’s better to keep
anti-spoofing related functionality under the same attribute.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Fri, 29 Oct 2021 00:00:00 </pubDate></item><item><title>Add Possibility for Cascade Deletion of Neutron Networks</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/zed/network-cascade-deletion.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1870319"&gt;https://bugs.launchpad.net/neutron/+bug/1870319&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When creating a network, a user needs to create other resources such
as subnets and ports depending on their needs. They would need to make
numerous API calls to the Neutron server to achieve this, and that’s okay.
Deleting the network doesn’t need to be that much of a hassle, though.
This spec explores a way to extend the delete API command to include
an argument to cascade delete all corresponding ports and subports
upon the deletion of a network.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently, deleting a network with many ports requires many API calls
to the Neutron server as the user needs to list all ports and delete
them before requesting the deletion of the network itself. Even more
requests are required when the network is plugged to a router(s) or has
trunk ports as those also need to be removed before network can be deleted.
A simple &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;openstack&lt;/span&gt; &lt;span class="pre"&gt;network&lt;/span&gt; &lt;span class="pre"&gt;delete&lt;/span&gt; &lt;span class="pre"&gt;&amp;lt;network&lt;/span&gt; &lt;span class="pre"&gt;name&lt;/span&gt; &lt;span class="pre"&gt;or&lt;/span&gt; &lt;span class="pre"&gt;ID&amp;gt;&lt;/span&gt;&lt;/code&gt; as prescribed
in the OpenStackClient (OSC) to delete a given network does not work if
there is one or more ports still in use on the network.
In other cases, e.g. when Kuryr &lt;a class="footnote-reference brackets" href="#id7" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; is used, it puts a lot of load on
Neutron’s client-side. This is what Kuryr currently needs to do to delete
“namespace”:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Get the ACTIVE ports in the subnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get the trunks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For each ACTIVE port, obtain what trunk it is attached to
and call Neutron to detach it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove the ports (one by one; there is no bulk deletion).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get the DOWN ports in the given subnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove the ports (one by one; there is no bulk deletion).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detach the subnet from the router.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove the network (which will also remove the subnet).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The goal of this spec is to add a new API to allow for the cascade
deletion of a given network and all the resources that belong to that
network, similarly to Octavia’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;loadbalancer&lt;/span&gt; &lt;span class="pre"&gt;delete&lt;/span&gt; &lt;span class="pre"&gt;--cascade&lt;/span&gt;&lt;/code&gt; option &lt;a class="footnote-reference brackets" href="#id8" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.
When the proposed network cascade deletion API call is sent to the
Neutron server, it is expected to find and clean:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;All router interfaces that belong to the subnets in that network,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All trunk ports whose parent ports are in that network. It will also
need to find and delete all the subports in these trunks,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove all ports in that network, this includes especially ports owned by
nova compute, attached to VMs; ports owned by &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DEVICE_OWNER_DHCP&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DEVICE_OWNER_DISTRIBUTED&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DEVICE_OWNER_AGENT_GW&lt;/span&gt;&lt;/code&gt; can be
omitted as they will have been already automatically removed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After all this cleaning is done, the network will be finally deleted.&lt;/p&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;The new option will be added to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DELETE&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/networks/{network_id}&lt;/span&gt;&lt;/code&gt;
API &lt;a class="footnote-reference brackets" href="#id9" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The new option will be called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cascade&lt;/span&gt;&lt;/code&gt;, and will be a boolean value.&lt;/p&gt;
&lt;p&gt;If this new option is set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt;, Neutron will remove all the
resources that need to be cleaned to successfully remove the given network.&lt;/p&gt;
&lt;p&gt;The main concern regarding the proposed API is the return code in case
the deletion of some resources fails and thus the request is only
partially completed. There are a few possible options in such a case:&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Return &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;HTTP&lt;/span&gt; &lt;span class="pre"&gt;207&lt;/span&gt; &lt;span class="pre"&gt;Multi-status&lt;/span&gt;&lt;/code&gt; &lt;a class="footnote-reference brackets" href="#id10" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and in the response body,
return a list of actions on various resources and their statuses,
for example:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"40ac1143-1488-42df-bf85-b0fde7598c97"&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Forbidden"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"trunk"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cb4acbfa-190a-4ad2-9227-ea8595b59b19"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;403&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Network in use."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"a7ebad6d-fd63-4024-b7db-8c30f5f9dea3"&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;409&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In this case, Neutron can always stop on first failure, so the response
body will always contain only one or two resources which failed during
the request: the network and one of the other resources that had to be
cleaned in cascade but, for some reason, failed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stop processing the cascade request on first failure and always
return &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;HTTP&lt;/span&gt; &lt;span class="pre"&gt;409&lt;/span&gt; &lt;span class="pre"&gt;Conflict&lt;/span&gt;&lt;/code&gt; with detailed information about what
went wrong, e.g. “Port &amp;lt;port_id&amp;gt; could not be deleted. Reason: &amp;lt;message&amp;gt;”.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make this Neutron API asynchronous. In this case, the return code would
only tell if the cascade delete request was accepted and will be
processed by the server, or not. Later, the user would be able to
periodically check if the network is already deleted or not yet.
This is how Octavia implemented the cascade deletion of the
loadbalancer &lt;a class="footnote-reference brackets" href="#id8" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. But it would break the documented Neutron
API behaviour &lt;a class="footnote-reference brackets" href="#id10" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The proposal of this spec is to implement third solution from the ones mentioned
above and make this Neutron API asynchronous.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;Network’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;status&lt;/span&gt;&lt;/code&gt; field will have new possible value &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DELETING&lt;/span&gt;&lt;/code&gt; which will
indicate that network is in the middle of the asynchronous deletion.&lt;/p&gt;
&lt;p&gt;To avoid execution of several DB transactions at once, e.g. when one worker will
proceed with asynchronous cascade deletion of the network and all its resources
and other one would try to update one of the ports/subnets it will be needed to
add check of the network’s status for all CREATE/UPDATE/DELETE operations for
ports and subnets as well as for attach/detach subnets from the routers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Finding and removing all the resources to be cascade deleted will be slow,
so the cascade deletion of a network with many resources may take
a long time.
To minimize that time, we can think of a couple of optimizations like:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implementing bulk port deletion,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Removing a port from a trunk automatically if it is the trunk’s subport.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignees:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Sharon Koech &amp;lt;&lt;a class="reference external" href="mailto:skoech%40protonmail.ch"&gt;skoech&lt;span&gt;@&lt;/span&gt;protonmail&lt;span&gt;.&lt;/span&gt;ch&lt;/a&gt;&amp;gt; (IRC: skoech)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;REST API update.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ML2 plugin update.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI update.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests and CI related changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit Tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;The new API option must be documented in the Neutron api-ref document.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/kuryr/latest/"&gt;https://docs.openstack.org/kuryr/latest/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id5"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/api-ref/load-balancer/v2/?expanded=remove-a-load-balancer-detail#remove-a-load-balancer"&gt;https://docs.openstack.org/api-ref/load-balancer/v2/?expanded=remove-a-load-balancer-detail#remove-a-load-balancer&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id9" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/api-ref/network/v2/index.html?expanded=delete-network-detail#networks"&gt;https://docs.openstack.org/api-ref/network/v2/index.html?expanded=delete-network-detail#networks&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id4"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id6"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/api-ref/network/v2/index.html#synchronous-versus-asynchronous-plug-in-behavior"&gt;https://docs.openstack.org/api-ref/network/v2/index.html#synchronous-versus-asynchronous-plug-in-behavior&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Fri, 24 Sep 2021 00:00:00 </pubDate></item><item><title>QoS minimum guaranteed packet rate</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/yoga/qos-minimum-guaranteed-packet-rate.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1922237"&gt;https://bugs.launchpad.net/neutron/+bug/1922237&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Similarly to how bandwidth can be a limiting factor of a network interface,
packet processing capacity tend to be a limiting factor of the soft switching
solutions like OVS. In the same time certain applications are dependent on not
just guaranteed bandwidth but also on guaranteed packet rate to function
properly. OpenStack already supports bandwidth guarantees via the
&lt;a class="reference external" href="https://docs.openstack.org/api-ref/network/v2/?expanded=#qos-minimum-bandwidth-rules"&gt;minimum bandwidth QoS policy rules&lt;/a&gt;. This specification is aiming for adding
support for a similar minimum packet rate QoS policy rule.&lt;/p&gt;
&lt;p&gt;To add support for the new QoS rule type both Neutron and Nova needs to be
extended. This specification only focuses on the Neutron impact. For the high
level view and for the Nova specific impact please read the
&lt;a class="reference external" href="https://review.opendev.org/c/openstack/nova-specs/+/785014"&gt;Nova specification&lt;/a&gt;.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently there are several parameters, quantitative and qualitative,
that define a VM and are used to select the correct host
and network backend devices to run it. The packet processing capacity of the
soft switching solution (like OVS) could also be such a parameter that affects
the placement of new workload.&lt;/p&gt;
&lt;p&gt;This spec focuses on managing the packet processing capacity of the soft switch
(like OVS) running on the hypervisor host serving the VM. Managing packet
processing capacity in other parts of the networking backend (like in
Top-Of-Rack switches) are out of scope.&lt;/p&gt;
&lt;p&gt;Guaranteeing packet processing capacity generally involves enforcement of
constraints on two levels.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;placement: Avoiding over-subscription when placing (scheduling) VMs and their
ports.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;data plane: Enforcing the guarantee on the soft switch&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This spec addresses placement enforcement only. Data plane enforcement
can be developed later. When the &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1912460"&gt;packet rate limit policy rule&lt;/a&gt; feature is
implemented then a basic data plane enforcement can be applied by adding both
minimum and maximum packet rate QoS rules to the same QoS policy where maximum
limit is set to be equal to the minimum guarantee.&lt;/p&gt;
&lt;section id="use-cases"&gt;
&lt;h3&gt;Use cases&lt;/h3&gt;
&lt;p&gt;I as an administrator want to define the maximum packet rate, in kilo packet
per second (kpps), my OVS soft switch capable of handle per compute node, so
that I can avoid overload on OVS.&lt;/p&gt;
&lt;p&gt;I as an end user want to define the minimum packet rate, in kilo packet per
second (kpps) a Neutron port needs to provide to my VM, so that my
application using the port can work as expected.&lt;/p&gt;
&lt;p&gt;I as an administrator want to get a VM with such ports placed on a
compute node that can still provide the requested minimum packet rate for the
Neutron port so that the application will get what it requested.&lt;/p&gt;
&lt;p&gt;I as an administrator want that the VM lifecycle operations are
rejected in case the requested minimum packet rate guarantee of the Neutron
ports of the server cannot be fulfilled on any otherwise eligible compute
nodes, so that the OVS overload is avoided and application guarantees are kept.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;For the high level solution including the impact and interactions between
Nova, Neutron and Placement see the &lt;a class="reference external" href="https://review.opendev.org/c/openstack/nova-specs/+/785014"&gt;Nova specification&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This feature is similar to the already supported
&lt;a class="reference external" href="https://docs.openstack.org/api-ref/network/v2/?expanded=#qos-minimum-bandwidth-rules"&gt;minimum bandwidth QoS policy rules&lt;/a&gt;. So this spec describes the impact in
relation to the already introduced concepts and implementation while also
pointing out key differences.&lt;/p&gt;
&lt;p&gt;The solution needs to differentiate between two deployment scenarios.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The packet processing functionality is implemented on the compute host CPUs
and therefore packets processed from both ingress and egress directions are
handled by the same set of CPU cores. This is the case in the
non-hardware-offloaded OVS deployments. In this scenario OVS represents a
single packet processing resource pool. Which can be represented with a
single new resource class, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NET_PACKET_RATE_KILOPACKET_PER_SEC&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The packet processing functionality is implemented in a specialized hardware
where the incoming and outgoing packets are handled by independent
hardware resources. This is the case for hardware-offloaded OVS. In this
scenario a single OVS has two independent resource pools one for the
incoming packets and one for the outgoing packets. Therefore these needs to
be represented with two new resource classes
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NET_PACKET_RATE_EGR_KILOPACKET_PER_SEC&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NET_PACKET_RATE_IGR_KILOPACKET_PER_SEC&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="ovs-packet-processing-capacity"&gt;
&lt;h3&gt;OVS packet processing capacity&lt;/h3&gt;
&lt;p&gt;Neutron OVS agent needs to provide a configuration options for the
administrator to define the maximum packet processing capability of the OVS
per compute node. This means the following new configuration options are added
to OVS agent configuration:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ovs&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# Comma-separated list of &amp;lt;hypervisor&amp;gt;:&amp;lt;packet_rate&amp;gt; tuples, defining the&lt;/span&gt;
&lt;span class="c1"&gt;# minimum packet rate the OVS backend can guarantee in kilo (1000) packet&lt;/span&gt;
&lt;span class="c1"&gt;# per second. The hypervisor name is used to locate the parent of the&lt;/span&gt;
&lt;span class="c1"&gt;# resource provider tree. Only needs to be set in the rare case when the&lt;/span&gt;
&lt;span class="c1"&gt;# hypervisor name is different from the DEFAULT.host config option value as&lt;/span&gt;
&lt;span class="c1"&gt;# known by the nova-compute managing that hypervisor or if multiple&lt;/span&gt;
&lt;span class="c1"&gt;# hypervisors are served by the same OVS backend.&lt;/span&gt;
&lt;span class="c1"&gt;# The default is :0 which means no packet processing capacity is guaranteed&lt;/span&gt;
&lt;span class="c1"&gt;# on the hypervisor named according to DEFAULT.host.&lt;/span&gt;
&lt;span class="c1"&gt;# resource_provider_packet_processing_without_direction = :0&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Similar to the resource_provider_packet_processing_without_direction but&lt;/span&gt;
&lt;span class="c1"&gt;# used in case the OVS backend has hardware offload capabilities. In this a&lt;/span&gt;
&lt;span class="c1"&gt;# case the format is&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;lt;hypervisor&amp;gt;:&amp;lt;egress_packet_rate&amp;gt;:&amp;lt;ingress_packet_rate&amp;gt; which allows&lt;/span&gt;
&lt;span class="c1"&gt;# defining packet processing capacity per traffic direction. The direction&lt;/span&gt;
&lt;span class="c1"&gt;# is meant from the VM perspective. Note that the&lt;/span&gt;
&lt;span class="c1"&gt;# resource_provider_packet_processing_without_direction and the&lt;/span&gt;
&lt;span class="c1"&gt;# resource_provider_packet_processing_with_direction&lt;/span&gt;
&lt;span class="c1"&gt;# are mutually exclusive options.&lt;/span&gt;
&lt;span class="c1"&gt;# resource_provider_packet_processing_with_direction = :0:0&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Key:value pairs to specify defaults used while reporting packet rate&lt;/span&gt;
&lt;span class="c1"&gt;# inventories. Possible keys with their types: allocation_ratio:float,&lt;/span&gt;
&lt;span class="c1"&gt;# max_unit:int, min_unit:int, reserved:int, step_size:int&lt;/span&gt;
&lt;span class="c1"&gt;# resource_provider_packet_processing_inventory_defaults = {&lt;/span&gt;
&lt;span class="c1"&gt;#   'allocation_ratio': 1.0, 'min_unit': 1, 'step_size': 1, 'reserved': 0}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Note that while bandwidth inventory is defined per OVS bridge in the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[ovs]resource_provider_bandwidths&lt;/span&gt;&lt;/code&gt; configuration option, the packet
processing capacity is applied globally to the whole OVS instance.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Note that to support both OVS deployment scenarios there are two mutually
exclusive configuration options. One to handle the normal OVS deployments
with directionless resource inventories and one to handle hardware-offloaded
OVS deployments with direction aware resource inventories.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;configurations&lt;/span&gt;&lt;/code&gt; field of the OVS agent heartbeat RPC message is extended
to report the packet processing capacity configuration to the Neutron server.
If the hypervisor name is omitted from the configuration it is resolved to the
value of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[DEFAULT]host&lt;/span&gt;&lt;/code&gt; in the RPC message.&lt;/p&gt;
&lt;p&gt;The Neutron server reports the packet processing capacity as the new
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NET_PACKET_RATE_KILOPACKET_PER_SEC&lt;/span&gt;&lt;/code&gt; or
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NET_PACKET_RATE_[E|I]GR_KILOPACKET_PER_SEC&lt;/span&gt;&lt;/code&gt; resource inventory on the OVS
agent resource provider (RP) to Placement in a similarly way how the bandwidth
resource is reported today. Now that the OVS agent RP has resource inventory
the Neutron server also needs to report the same &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CUSTOM_VNIC_TYPE_&lt;/span&gt;&lt;/code&gt; traits
on the OVS agent RP as reported on the bridge RPs. These are the vnic types
this agent configured to support. Note that &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CUSTOM_PHYSNET_&lt;/span&gt;&lt;/code&gt; traits are
not needed for the packet rate scheduling as this resource is not split
between the available physnets.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Regarding the alternative of reporting the resources on the OVS bridge
level instead, please see the &lt;a class="reference external" href="https://review.opendev.org/c/openstack/nova-specs/+/785014"&gt;Nova specification&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="minimum-packet-rate-qos-policy-rule"&gt;
&lt;h3&gt;Minimum packet rate QoS policy rule&lt;/h3&gt;
&lt;p&gt;A new Neutron API extension is needed to extend the QoS API with the new
minimum_packet_rate rule type. This rule has a similar structure and semantic
as the minimum_bandwidth rule:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;qos_apidef&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SUB_RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'minimum_packet_rate_rules'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'parent'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;qos_apidef&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_PARENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'parameters'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;qos_apidef&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_QOS_RULE_COMMON_FIELDS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'min_kpps'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;converters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_sort_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s1"&gt;'type:range'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DB_INTEGER_MAX_VALUE&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EGRESS_DIRECTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ANY_DIRECTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INGRESS_DIRECTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EGRESS_DIRECTION&lt;/span&gt;
                    &lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The direction, ingress or egress of the rule is considered from the Nova
server’s perspective. So an 1 kpps ingress guarantee means the system ensures
that at least 1000 packets can enter the VM via the given port per second.&lt;/p&gt;
&lt;p&gt;To support the two different OVS deployment scenarios we need to allow that the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;direction&lt;/span&gt;&lt;/code&gt; field of the new QoS policy rule to be set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;any&lt;/span&gt;&lt;/code&gt; to
indicate that this QoS rule is valid in the normal OVS case where the resource
accounting is directionless.&lt;/p&gt;
&lt;p&gt;Mixing direction aware and directionless minimum packet rate rules in the same
QoS policy will always result in a NoValidHost error during scheduling as no
single OVS instance can have both direction aware and directionless inventory
at the same time. Therefore such rule creation will be rejected by the Neutron
server with HTTP 400.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;For the alternative about having only direction aware QoS rule types see
the &lt;a class="reference external" href="https://review.opendev.org/c/openstack/nova-specs/+/785014"&gt;Nova specification&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The above definition allows the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;min_kpps&lt;/span&gt;&lt;/code&gt; value to be updated with a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt;&lt;/code&gt;
request. This request will be rejected with HTTP 501 if the rule is already
used in a bound port similarly to the minimum bandwidth rule behavior.&lt;/p&gt;
&lt;p&gt;Neutron provides the necessary information to the admin clients via
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; of the port to allow the client to keep the placement
resource allocation consistent and therefore implement the schedule time
guarantee. Nova will use this information to do so. However neither Neutron nor
Nova can enforce that another client, which can bound ports also properly
allocates resources for those ports. This is out of scope.&lt;/p&gt;
&lt;p&gt;This results in the following new API resources and operations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/qos/policies/{policy_id}/minimum_packet_rate_rules&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;List minimum packet rate rules for QoS policy&lt;/p&gt;
&lt;p&gt;Response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"minimum_packet_rate_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5f126d84-551a-4dcf-bb01-0e9c0df0c793"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"min_kpps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"egress"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/qos/policies/{policy_id}/minimum_packet_rate_rules&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Create minimum packet rate rule&lt;/p&gt;
&lt;p&gt;Request:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"minimum_packet_rate_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"min_kpps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"any"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"minimum_packet_rate_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5f126d84-551a-4dcf-bb01-0e9c0df0c793"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"min_kpps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"any"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/qos/policies/{policy_id}/minimum_packet_rate_rules/{rule_id}&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Show minimum packet rate rule details&lt;/p&gt;
&lt;p&gt;Response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"minimum_packet_rate_limit_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5f126d84-551a-4dcf-bb01-0e9c0df0c793"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"min_kpps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"egress"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/qos/policies/{policy_id}/minimum_packet_rate_rules/{rule_id}&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Update minimum packet rate rule&lt;/p&gt;
&lt;p&gt;Request:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"minimum_packet_rate_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"min_kpps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"any"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"minimum_packet_rate_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5f126d84-551a-4dcf-bb01-0e9c0df0c794"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"min_kpps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"any"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DELETE&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/qos/policies/{policy_id}/minimum_packet_rate_rules/{rule_id}&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Delete minimum packet rate rule&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This spec intentionally does not propose the addition of the old style
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/qos/policies/{policy_id}/minimum_packet_rate_rules/{rule_id}&lt;/span&gt;&lt;/code&gt; APIs
as Neutron team prefers the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/qos/alias_bandwidth_limit_rules/{rule_id}&lt;/span&gt;&lt;/code&gt; style APIs in the
future. The old style APIs only kept for backwards compatibility for
already existing QoS rules. However as this new API will not have an old
style counterpart the ‘alias’ prefix is removed from the resource name.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;To persist the new QoS rule type a new DB table
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qos_minimum_packet_rate_rules&lt;/span&gt;&lt;/code&gt; is needed:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s1"&gt;'qos_minimum_packet_rate_rules'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'qos_policy_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
              &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'min_kpps'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Enum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ANY_DIRECTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                   &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EGRESS_DIRECTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                   &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INGRESS_DIRECTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                   &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"directions"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
              &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;server_default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EGRESS_DIRECTION&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrimaryKeyConstraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKeyConstraint&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'qos_policy_id'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'qos_policies.id'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                            &lt;span class="n"&gt;ondelete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'CASCADE'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This also means a new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;QosMinimumPacketRateRule&lt;/span&gt;&lt;/code&gt; DB model and OVO are added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="request-packet-rate-resources"&gt;
&lt;h3&gt;Request packet rate resources&lt;/h3&gt;
&lt;p&gt;Today the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; field of the Neutron port is used to express the
resource needs of the port. The information in this field is calculated from
the QoS policy rules attached to the port. So far only the minimum bandwidth
rule is used as a source of the requested resources. However both the structure
and the actual logic calculating the value of this field needs to be changed
when the new minimum packet rate rule is added as an additional source of the
requested resources.&lt;/p&gt;
&lt;p&gt;Currently &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; is structured like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CUSTOM_PHYSNET_&lt;/span&gt; &lt;span class="n"&gt;traits&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CUSTOM_VNIC_TYPE&lt;/span&gt; &lt;span class="n"&gt;traits&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"resources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;NET_BW_&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;GR_KILOBIT_PER_SEC&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;requested&lt;/span&gt; &lt;span class="n"&gt;bandwidth&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;the&lt;/span&gt; &lt;span class="n"&gt;QoS&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The current structure only allows describing one group of resources and traits.
However as described above the packet processing resource inventory is reported
on the OVS agent RP while the bandwidth resources are reported on the OVS
bridge RP. This also means that requesting these resources needs to be
separated as one group of resources always allocated from a single RP in
placement.&lt;/p&gt;
&lt;p&gt;Therefore the following structure is proposed for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt;
field:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"request_groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;some&lt;/span&gt; &lt;span class="n"&gt;unique&lt;/span&gt; &lt;span class="n"&gt;identifier&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="s2"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CUSTOM_VNIC_TYPE&lt;/span&gt; &lt;span class="n"&gt;traits&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s2"&gt;"resources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;NET_PACKET_RATE_&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;GR_KILOPACKET_PER_SEC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="n"&gt;requested&lt;/span&gt; &lt;span class="n"&gt;via&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;QoS&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;some&lt;/span&gt; &lt;span class="n"&gt;unique&lt;/span&gt; &lt;span class="n"&gt;identifier&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="s2"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CUSTOM_PHYSNET_&lt;/span&gt; &lt;span class="n"&gt;traits&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CUSTOM_VNIC_TYPE&lt;/span&gt; &lt;span class="n"&gt;traits&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s2"&gt;"resources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;NET_BW_&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;GR_KILOBIT_PER_SEC&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;requested&lt;/span&gt; &lt;span class="n"&gt;bandwidth&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;the&lt;/span&gt; &lt;span class="n"&gt;QoS&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Each dict in the list represents one group of resources and traits that needs
to be fulfilled from a single resource provider. E.g. either from the bridge
RP in case of bandwidth, or the OVS agent RP in case of packet rate. This
solves the problem of the RP separation. However in the other hand a port
still needs to allocate resources from the same overall entity, e.g. from
OVS, by allocating packet processing capacity from the OVS agent RP and
bandwidth from one of the OVS bridge RPs. In other words it is invalid to
fulfill the packet processing request from OVS and the bandwidth request
from an SRIOV PF managed by the SRIOV agent. In the placement model the OVS
bridge RPs are the children of the OVS agent RP while the PF RPs are not. So
placement already aware of the structural connections between the resource
inventories. Still by default, when two groups of resources are requested
Placement only enforces that they are fulfilled from two RPs in the same RP
tree but it does not enforce any subtree relationship between those RPs. To
express that the two groups of resources should be fulfilled from two RPs in
the same subtree (in our case from the subtree rooted by the OVS agent RP)
placement needs extra information in the request. Placement supports a
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;same_subtree&lt;/span&gt;&lt;/code&gt; parameter that can express what we need. Neutron needs to add
a new top level key &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;same_subtree&lt;/span&gt;&lt;/code&gt; to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt;
dict. I.e.:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"request_groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"port-request-group-due-to-min-pps"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="c1"&gt;# ...&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"port-request-group-due-to-min-bw"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="c1"&gt;# ...&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"same_subtree"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"port-request-group-due-to-min-pps"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"port-request-group-due-to-min-bw"&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;id&lt;/span&gt;&lt;/code&gt; field is a string that is assumed to be unique for each group of
each port in a neutron deployment. To achieve this a new UUID will be generated
for each group by combining the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port_id&lt;/span&gt;&lt;/code&gt; and UUIDs of the QoS rules
contributing to the group via the UUID5 method. This way we get a unique and
deterministic id for the group so we don’t need to persist the group id in
Neutron.&lt;/p&gt;
&lt;p&gt;We discussed and rejected another two alternatives:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Ignore the same subtree problem for now. &lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/admin/config-qos-min-bw.html#neutron-server-config"&gt;The QoS configuration&lt;/a&gt; already
requires the admin to create a setup where the different mechanism drivers
support disjunct set of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vnic_type&lt;/span&gt;&lt;/code&gt; s via the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vnic_type_prohibit_list&lt;/span&gt;&lt;/code&gt;
config option. A port always requests a specific &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vnic_type&lt;/span&gt;&lt;/code&gt; and the
supported &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vnic_type&lt;/span&gt;&lt;/code&gt; s are disjunct therefore the port’s resource request
always selects a specific networking backend via the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CUSTOM_VNIC_TYPE_&lt;/span&gt;&lt;/code&gt;
traits. Support for packet rate resource is only added to the OVS backend,
therefore if the scheduling of a port’s resource request, containing both
packet rate and bandwidth resource, succeeds then we know that the packet
rate resource is fulfilled by the OVS agent RP. Therefore the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vnic_type&lt;/span&gt;&lt;/code&gt;
matched the OVS backend. The bandwidth request also fulfilled from a backend
with the same &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vnic_type&lt;/span&gt;&lt;/code&gt; so it is also fulfilled from the OVS backend.
If we go with this direction then special care needs to be taken to document
the above assumption carefully so that future developers can check if any of
the statements become invalid due to new feature additions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Make an assumption in Nova that every request group from a single port
always needs to be fulfilled from the same subtree. Then the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;same_subtree&lt;/span&gt;&lt;/code&gt;
key is not needed in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; but Nova will implicitly assume
that it is there and generate the placement request accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The selected alternative is more future proof. When the IP allocation pool
handling are transformed to use the resource request, that resource will come
from a sharing resource provider and therefore Nova cannot implicitly assume
same_subtree for the whole resource_request.&lt;/p&gt;
&lt;p&gt;Note that the current neutron API does not define the exact structure of the
field, it is just a dict, so from Neutron perspective there is no need for a
new API extension to change the structure. However Nova needs to know which
format will be used by Neutron. We have alternatives:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A new Neutron API extension: It can signal the change of the API. Nova
already use to check the extension list to see if some feature is enabled in
Neutron or not.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new top level &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request_version&lt;/span&gt;&lt;/code&gt; field in the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; dict can signal the current and future versions. Nova
would need to check if the field exists in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; and
conditionally parse the rest of the dict.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Let Nova guess based on the structure. The new top level &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;request_groups&lt;/span&gt;&lt;/code&gt;
key can be used in Nova to detect the new format.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The API extension is the selected alternative as that feels like the standard
way in Neutron to signal API change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="port-binding"&gt;
&lt;h3&gt;Port binding&lt;/h3&gt;
&lt;p&gt;Today Nova sends the UUID of the resource provider the port’s
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; is fulfilled from in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;allocation&lt;/span&gt;&lt;/code&gt; key of the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding:profile&lt;/span&gt;&lt;/code&gt;. The port binding logic uses this information to bind the
port to the same physical device or OVS bridge the port’s resources are
allocated from. This is necessary as it is allowed to have multiple such
devices that are otherwise equivalent from Neutron perspective, i.e. they are
connected to the same physnet and supporting the same &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vnic_type&lt;/span&gt;&lt;/code&gt;. When the
port has two groups of resource requests (one for bandwidth and the other for
packet rate) the resource allocation is fulfilled from more than one RPs. To
support that we need to change the structure of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;allocation&lt;/span&gt;&lt;/code&gt; key. As
every group of resources in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; now has a uniq identifier
Nova can send a mapping of &amp;lt;group.id&amp;gt;: &amp;lt;RP.uuid&amp;gt; back in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;allocaton&lt;/span&gt;&lt;/code&gt;
key of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding:profile&lt;/span&gt;&lt;/code&gt; so that Neutron gets informed about which RP
provided which group of resources. This means the following structure in the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;allocation&lt;/span&gt;&lt;/code&gt; key:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uniq&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="n"&gt;requesting&lt;/span&gt; &lt;span class="n"&gt;min_pps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OVS&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="n"&gt;RP&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uniq&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="n"&gt;requesting&lt;/span&gt; &lt;span class="n"&gt;min_bw&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OVS&lt;/span&gt; &lt;span class="n"&gt;bridge&lt;/span&gt; &lt;span class="n"&gt;RP&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;SRIOV&lt;/span&gt; &lt;span class="n"&gt;PF&lt;/span&gt; &lt;span class="n"&gt;RP&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Only those group id keys are present in this dict that are present in the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; field as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;id&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Alternatively&lt;/em&gt; we could  ignore the problem for now. Only OVS supports packet
rate inventory for now and the packet rate inventory is global for the whole
OVS instance. A single &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding:host_id&lt;/span&gt;&lt;/code&gt; always maps to a single OVS
instance, so Neutron can always assume that the minimum packet rate resource
are allocated from the OVS agent resource provider that belongs to the
compute node the port is requested to bound to. So the UUID of the packet
rate resource provider is not needed of the port binding logic. Therefore the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;allocation&lt;/span&gt;&lt;/code&gt; key can be kept to only communicate the UUID of the bandwidth
resource provider if any.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="qos-policy-change-on-bound-port"&gt;
&lt;h3&gt;QoS policy change on bound port&lt;/h3&gt;
&lt;p&gt;Neutron supports changing the QoS policy on a bound port even if this means
that resource allocation change is needed due to changes in the resource
request indicated by the minimum_bandwidth QoS rule. This implementation needs
to be extended to handle changes not just in minimum_bandwidth but also in
minimum_packet_rate rule.&lt;/p&gt;
&lt;p&gt;The current support matrix is:&lt;/p&gt;
&lt;table class="docutils align-default" id="id1"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;Current scenarios&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Scenario&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Result&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Update the port.qos_policy_id from None to valid QoS policy with
minimum bandwidth rule&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Accepted but the resource allocation is not adjusted as that would
require a full scheduling. If the VM later scheduled to another host
(i.e. migrated, resize, evacuated) then that scheduling will consider
the new resource request.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Update the port.qos_policy_id from a QoS policy without minimum
bandwidth rule to a QoS policy with minimum bandwidth rule&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Accepted but the resource allocation is not adjusted. See above.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Update the port.qos_policy_id from a QoS policy with minimum bandwidth
rule to a QoS policy with minimum bandwidth rule but with different
min_kbps value or different direction.&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Supported. Accepted if the bandwidth allocation on the current resource
provider can be updated with the new QoS value and direction.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Update the port.qos_policy_id from a QoS policy with minimum bandwidth
rule to a QoS policy without minimum bandwidth rule.&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Supported. The bandwidth resource allocation for this port in placement
is deleted.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;After the minimum packet rate rule is added Neutron will have two QoS policy
rules that requires placement resources allocation. This adds more possible
cases to handle. The above scenarios still apply for minimum bandwidth and can
be applied similarly to QoS policy with a single minimum packet rate rule. The
more complex cases are described below:&lt;/p&gt;
&lt;table class="docutils align-default" id="id2"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;New scenarios&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Scenario&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Result&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;The old QoS policy has both minimum bandwidth and packet rate rules,
the new policy also has both rules but with different min_kbps
and / or min_kpps values.&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Supported. Accepted if the bandwidth allocation on the current resource
providers can be updated with the new QoS values.
Changing the direction of the minimum bandwidth rule or the direction
of the direction aware minimum packet rate rule is also supported.
However changing from a direction less minimum packet rate rule to a
direction aware packet rate rule, or vice versa, is not supported and
rejected.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;The old QoS policy has both minimum bandwidth and packet rate rules,
the new policy has less rules. Either just minimum bandwidth or
just minimum packet rate or none of them.&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Supported. The allocation related to the removed rule(s) are deleted in
placement.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;The new QoS policy adds either minimum bandwidth or packet rate rule or
both compared to the old policy.&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Accepted but the resource allocation is not adjusted as that would
require a full scheduling. If the VM later scheduled to another host
(i.e. migrated, resize, evacuated) then that scheduling will consider
the resource request of the new rule(s).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="upgrade"&gt;
&lt;h3&gt;Upgrade&lt;/h3&gt;
&lt;p&gt;A database schema upgrade is needed to add the new
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qos_minimum_packet_rate_rules&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;
&lt;p&gt;The changes in the Neutron server - OVS agent communication means that during
rolling upgrade upgraded OVS agents might send the new
packet processing capacity related keys in the hearthbeat while old agents
will not send it. So Neutron server needs to consider this new key as optional.&lt;/p&gt;
&lt;p&gt;The manipulation of the  new minimum_packet_rate QoS policy rule and changes in
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;allocation&lt;/span&gt;&lt;/code&gt; fields of the port requires a new
API extension. We need to support upgrade scenarios where the Neutron is
already upgraded to Yoga but Nova still on Xena version. However this does not
require any additional logic in Neutron as Nova already landed support this API
extension in Xena.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functional tests: agent-server interactions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest scenario tests: End-to-end feature test.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h3&gt;Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update the generic &lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/admin/config-qos.html"&gt;QoS admin guide&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new admin guide, similar to the one for &lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/admin/config-qos-min-bw.html"&gt;minimum bandwidth&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The &lt;a class="reference external" href="https://review.opendev.org/c/openstack/nova-specs/+/785014"&gt;Nova specification&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The already supported &lt;a class="reference external" href="https://docs.openstack.org/api-ref/network/v2/?expanded=#qos-minimum-bandwidth-rules"&gt;minimum bandwidth QoS policy rules&lt;/a&gt; serving as a
pattern for the new minimum packet rate QoS policy rule.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 15 Sep 2021 00:00:00 </pubDate></item><item><title>BFD as a Service for Neutron</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/xena/bfd_support.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1907089"&gt;https://bugs.launchpad.net/neutron/+bug/1907089&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add possibility to define BFD monitors in Neutron and associate it with routes.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;BFD (Bidirectional Forwarding Detection) can be used to detect link failures
between a Neutron router and an arbitrary destination, like an external
non-Neutron router.&lt;/p&gt;
&lt;p&gt;BFD can be used to provide quick, low-overhead link failure detection between
adjacent forwarding engines (&lt;a class="footnote-reference brackets" href="#id9" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;) to check for example if an extra route
(a nexthop-destination pair) is alive or not, and change routes accordingly.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This spec is not covering other use cases like tunnel monitoring and HA or
DVR router monitoring, or BGP or other routing protocol monitoring.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The goal of this spec is to add APIs to manage bfd_monitor instances, fetch
their status, associate a monitor to an extra route. The goal is to cover
the use case when Neutron managed bfd_monitor instances take the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ACTIVE&lt;/span&gt;&lt;/code&gt;
role, thus send BFD control packets, (see &lt;a class="footnote-reference brackets" href="#id10" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;This gives possibility to the operators to monitor the routes
(destination - nexthop pairs) added for a router.&lt;/p&gt;
&lt;section id="monitoring-scenarios"&gt;
&lt;h3&gt;Monitoring scenarios&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Two different nexthops for the same destination, like ecmp route legs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;dst1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;nexthop1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bfd_dst1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bfd1&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;dst1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;nexthop2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bfd_dst1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bfd2&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;____nexthop1&lt;/span&gt; &lt;span class="n"&gt;____&lt;/span&gt;
                 \ &lt;span class="n"&gt;____dst1&lt;/span&gt;
&lt;span class="n"&gt;____nexthop2____&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;monitoring 2 different destinations through the same nexthop, the case
when bfd3 and bfd4 dst_ip is the same:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;dst3&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;nexthop3&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bfd_dst3&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bfd3&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;dst4&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;nexthop3&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bfd_dst4&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bfd4&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                   &lt;span class="n"&gt;____dst3&lt;/span&gt;
&lt;span class="n"&gt;_____nexthop3_____&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
                  \&lt;span class="n"&gt;____dst4&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;section id="new-bfd-monitor-api"&gt;
&lt;h4&gt;New bfd monitor API&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create bfd_monitor:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bfd_monitors&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"bfd_monitor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"bfd1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"asynchronous"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"min_rx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"min_tx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"multiplier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"dst_ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.13"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"auth_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"auth_keys"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"secret_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"secret_2"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List bfd_monitors:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bfd_monitors&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show bfd_monitor:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bfd_monitors&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;monitor_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"bfd_monitor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"bfd1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{project_id}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"asynchronous"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"min_rx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"min_tx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"multiplier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"dst_ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.13"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"src_ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"169.254.112.144"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"auth_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"auth_keys"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"secret_1"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update a bfd_monitor:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bfd_monitors&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;monitor_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"bfd_monitor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"bfd_monitor1"&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"min_rx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"min_tx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"multiplier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete bfd_monitor:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bfd_monitors&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;monitor_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Only an unassociated bfd_monitor can be deleted.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;API fields and descriptions for bfd_monitor:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;id of bfd_monitor&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable name for the
bfd_monitor (255 characters limit).
Does not have to be unique.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable description for the
bfd_monitor (255 characters limit).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of the bfd_monitor.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;mode&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Can be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;asynchronous&lt;/span&gt;&lt;/code&gt; (default
common echo mode of BFD) or
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;demand&lt;/span&gt;&lt;/code&gt; (some other mechanism is
used to detect link state) and can
accept future modes like
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;one-arm-echo&lt;/span&gt;&lt;/code&gt; see &lt;a class="footnote-reference brackets" href="#id12" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; .&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;dst_ip&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The destination IP address to be
monitored. In case of singlehop bfd
this is the nexthop ip of the route,
for the general case (like multihop
bfd) this is an arbitrary IP (IPv4 or
Ipv6) that can serve as BFD neighbor.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;src_ip&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;IP address used as source for
transmitted BFD packets. An optional
field, if not specified, the IP set
on the interface, like on qg-xyz.
This can be set on the remote end to
be configured.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;min_rx&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The shortest interval, in millisecs,
at which this BFD session offers to
receive BFD control messages. At
least 1. Defaults is 1000.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;min_tx&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The shortest interval, in millisecs,
at which this BFD session is
willing to transmit BFD control
messages. At least 1. Default is 100.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;multiplier&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The BFD detection multiplier, An
endpoint signals  a connectivity
fault if the given number of
consecutive BFD control messages fail
to arrive. Default is 3.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;status&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Shows if the BFD monitor was
succesfully created in the backend,
but nothing about the session status,
for that the session_status API
endpoint can be used.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;auth_type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The Authentication Type, which can be
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;password&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;MD5&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;MeticulousMD5&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SHA1&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;MeticulousSHA1&lt;/span&gt;&lt;/code&gt;, if empty no
authentication is used.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;auth_key&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Dict&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A dictionary of authentication key
chain in which key is an integer of
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Auth&lt;/span&gt; &lt;span class="pre"&gt;Key&lt;/span&gt; &lt;span class="pre"&gt;ID&lt;/span&gt;&lt;/code&gt; and value is a string
of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Password&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Auth&lt;/span&gt; &lt;span class="pre"&gt;Key&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;For using authentication with BFD, please check &lt;a class="footnote-reference brackets" href="#id13" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;API extension proposal for bfd_monitors:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;ALIAS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'bfd-monitor'&lt;/span&gt;
&lt;span class="n"&gt;IS_SHIM_EXTENSION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;span class="n"&gt;IS_STANDARD_ATTR_EXTENSION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;span class="n"&gt;NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'BFD monitors for Neutron'&lt;/span&gt;
&lt;span class="n"&gt;DESCRIPTION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Provides support for BFD monitors"&lt;/span&gt;
&lt;span class="n"&gt;UPDATED_TIMESTAMP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2021-02-12T11:00:00-00:00"&lt;/span&gt;
&lt;span class="n"&gt;BFD_MONITOR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'bfd_monitor'&lt;/span&gt;
&lt;span class="n"&gt;BFD_MONITORS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'bfd_monitors'&lt;/span&gt;
&lt;span class="n"&gt;BFD_SESSION_STATUS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'bfd_session_status'&lt;/span&gt;

&lt;span class="n"&gt;BFD_MODE_ASYNC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'asynchronous'&lt;/span&gt;
&lt;span class="n"&gt;BFD_MODE_DEMAND&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'demand'&lt;/span&gt;
&lt;span class="n"&gt;BFD_MODE_ONE_ARM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'one_arm_echo'&lt;/span&gt;

&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;BFD_MONITORS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'enforce_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;db_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NAME_FIELD_SIZE&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                 &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_sort_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;db_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DESCRIPTION_FIELD_SIZE&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
        &lt;span class="s1"&gt;'project_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                           &lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;db_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PROJECT_ID_FIELD_SIZE&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                       &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'enforce_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'mode'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;db_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;STATUS_FIELD_SIZE&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                 &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BFD_MODE_ASYNC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'is_sort_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'dst_ip'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:ip_address'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                   &lt;span class="s1"&gt;'is_sort_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'enforce_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'src_ip'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:ip_address_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="s1"&gt;'is_sort_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'enforce_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'min_rx'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:non_negative'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                   &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;converters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'enforce_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'min_tx'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:non_negative'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                   &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;converters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'enforce_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'multiplier'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:non_negative'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                       &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;converters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'enforce_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_sort_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'auth_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                   &lt;span class="n"&gt;db_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NAME_FIELD_SIZE&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ATTR_NOT_SPECIFIED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'auth_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:dict_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                     &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ATTR_NOT_SPECIFIED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;SUB_RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;ACTION_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;BFD_MONITOR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'bfd_session_status'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'bfd_monitor_associations'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;ACTION_STATUS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;REQUIRED_EXTENSIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;l3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ALIAS&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;OPTIONAL_EXTENSIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Show bfd session status (For details see rfc5880, State Variables section):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bfd_monitors&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;monitor_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;session_status&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"bfd_session_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"remotes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"extra_route"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"router"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s2"&gt;"extra_route"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.3.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"nexthop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.1"&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s2"&gt;"src_ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"169.254.112.144"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"SessionState"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Up"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"RemoteSessionState"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Up"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"LocalDiagnostic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"RemoteDiagnostic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"LocalDiscriminator"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"RemoteDiscriminator"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"Forwarding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"extra_route"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show bfd_monitor associations:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bfd_monitors&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;monitor_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bfd_monitor_associations&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="s2"&gt;"bfd_monitor_associations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s2"&gt;"remotes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
             &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"extra_route"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"router"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="s2"&gt;"extra_route"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                 &lt;span class="s2"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.3.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s2"&gt;"nexthop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.1"&lt;/span&gt;
             &lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="s2"&gt;"src_ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"169.254.112.144"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="p"&gt;},&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"extra_route"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="o"&gt;...&lt;/span&gt;
         &lt;span class="p"&gt;}]&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The current proposal is only for “type”: “extra_route”, so the
extra_route’s details (nexthop, destination as of now) will appear.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;One bfd_monitor instance can be associated to several extra_routes.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;src_ip&lt;/span&gt;&lt;/code&gt; is the IP address used as source for transmitted BFD packets.
A read only field that practically shows the IP set on the interface,
like on qg-xyz. This can be set on the remote end.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Short description of the status fields:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;SessionState&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The state of the BFD session, it can be
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;admin_down&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;down&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;init&lt;/span&gt;&lt;/code&gt;,  or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;up&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;RemoteSessionState&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The state of the remote endpoint’s BFD session, it
can be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;admin_down&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;down&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;init&lt;/span&gt;&lt;/code&gt;,  or
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;up&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;LocalDiagnostic&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A diagnostic code specifying the local system’s
reason for the last change in session state. The
error messages are defined  in section 4.1 of the
RFC 5880 (see &lt;a class="footnote-reference brackets" href="#id11" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;RemoteDiagnostic&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A diagnostic code specifying the remote system’s
reason for  the last  change in session state. The
error messages are defined  in section 4.1 of the
RFC 5880 (see &lt;a class="footnote-reference brackets" href="#id11" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;LocalDiscriminator&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The local discriminator for this BFD session, used
to uniquely identify it.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;RemoteDiscriminator&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The remote discriminator for this BFD session. This
is the discriminator chosen by the remote system.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Forwarding&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Reports whether the BFD session believes this
Interface  may  be used  to forward traffic. It can
be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;true&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;false&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The above fields are optional, so based on the backend not all will be
filled, and in worst case a cumulative &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Forwarding&lt;/span&gt;&lt;/code&gt; result will only
present.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="changes-to-router-extra-routes-api"&gt;
&lt;h4&gt;Changes to Router extra routes API&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Changes to add or remove extra routes to router or Update router API:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;routers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"router"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"routes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"179.24.1.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"nexthop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"172.24.3.99"&lt;/span&gt;
                &lt;span class="s2"&gt;"bfd_monitor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;bfd_monitor_uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;routers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;add_extraroutes&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"router"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"routes"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"destination"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.3.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"nexthop"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.13"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"bfd_monitor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;bfd_monitor_uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"destination"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.4.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"nexthop"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.14"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;routers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;remove_extraroutes&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"router"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"routes"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"destination"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.3.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"nexthop"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.13"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"bfd_monitor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;bfd_monitor_uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The API will allow to remove bfd_monitor association from a route without
deleting and recreating the whole nexthop-destination tuple.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Get routes status:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;routers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;routes_status&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"router"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"routes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"destination"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.3.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"nexthop"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.13"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"UP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"bfd_monitor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;bfd_monitor_uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;API extension proposal for allowing bfd_monitor association to extra_routes:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;ALIAS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'bfd-for-extraroutes'&lt;/span&gt;
&lt;span class="n"&gt;IS_SHIM_EXTENSION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;span class="n"&gt;IS_STANDARD_ATTR_EXTENSION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;span class="n"&gt;NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'BFD monitors for extraroutes'&lt;/span&gt;
&lt;span class="n"&gt;DESCRIPTION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Provides the possibility to associate a bfd_monitor to'&lt;/span&gt;
               &lt;span class="s1"&gt;'extra_routes'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;UPDATED_TIMESTAMP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2021-01-29T00:00:00+00:00'&lt;/span&gt;
&lt;span class="n"&gt;RESOURCE_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;l3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ROUTER&lt;/span&gt;
&lt;span class="n"&gt;COLLECTION_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;l3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ROUTERS&lt;/span&gt;
&lt;span class="n"&gt;ROUTES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'routes'&lt;/span&gt;
&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;COLLECTION_NAME&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ROUTES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:hostroutes'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'destination'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'nexthop'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                             &lt;span class="s1"&gt;'bfd_monitor_id'&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
            &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;converters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_none_to_empty_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ATTR_NOT_SPECIFIED&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;SUB_RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;span class="n"&gt;ACTION_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;REQUIRED_EXTENSIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;l3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ALIAS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;extraroute&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ALIAS&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;OPTIONAL_EXTENSIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;ACTION_STATUS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;a class="footnote-reference brackets" href="#id14" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; proposes the change of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;hostroutes&lt;/span&gt;&lt;/code&gt; validator to accept a list
of possible fields to validate, like: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;destination&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;nexthop&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;bfd_monitor_id&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;BFD itself and fetching bfd_monitor session status information can be quite
resource intensive operation (the information must be fetched from the
backend), so new API endpoint is proposed to fetch the status of monitoring
to not overload or affect ordinary router API operations.&lt;/p&gt;
&lt;p&gt;The routes_status API endpoint gives feedback to the user if the monitored
link is up.&lt;/p&gt;
&lt;p&gt;If the bfd_monitor’s session_status is DOWN (BFD detects the given link dead)
the given route should be removed in the backend (on the command line: ip r
delete….), and set back if the monitor is UP again.&lt;/p&gt;
&lt;p&gt;The bfd_monitor instance in the backend is created when the bfd_monitor is
associated with any routes, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;status&lt;/span&gt;&lt;/code&gt; of the bfd_monitor is set to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ACTIVE&lt;/span&gt;&lt;/code&gt; from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DOWN&lt;/span&gt;&lt;/code&gt;. The bfd_monitor’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;status&lt;/span&gt;&lt;/code&gt; set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DOWN&lt;/span&gt;&lt;/code&gt; when
the extra route updated and bfd_monitor value is set to empty, so the
bfd_monitor is deleted in the backend.&lt;/p&gt;
&lt;p&gt;As a bfd_monitor can be associated to many routes, if it is associated to
at least one route and the creation in the backend is successful the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;status&lt;/span&gt;&lt;/code&gt; field of the bfd_monitor is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ACTIVE&lt;/span&gt;&lt;/code&gt;, and it will change to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DOWN&lt;/span&gt;&lt;/code&gt; when the last route association is deleted (the bfd_monitor is
deleted from the last extra_route).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="backend"&gt;
&lt;h4&gt;Backend&lt;/h4&gt;
&lt;p&gt;OVS can handle BFD on an interface and check the status of it.
The problem with it is that ovs can have 1 BFD session per port, and
to manage it ovsdb is the simplest way, but as LIU Yulong stated in &lt;a class="footnote-reference brackets" href="#id15" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;
touching ovsdb from l3-agent can be weird.&lt;/p&gt;
&lt;p&gt;A working solution with OVS is to create a BFD bridge, like br-bfd, and
add veth ports to it, and enable BFD on those interfaces.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt; &lt;span class="o"&gt;--------&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;--------&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;veth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;xy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;veth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;xy&lt;/span&gt;
 &lt;span class="o"&gt;--------&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bfd&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;--------&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Another possibility is to use os-ken, but during my experiments the BFD
implementation in os-ken is not mature enough, and it needs ovsdb connection
anyway, so I do not suggest os-ken to be used for BFD.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;New table is created for bfd_monitors, routers table is changed to make it
possible to associate a bfd_monitor to an extra route (a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;nexthop&lt;/span&gt;&lt;/code&gt; -
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;destination&lt;/span&gt;&lt;/code&gt; pair).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;BFD and fetching bfd_monitor status information can be quite resource intensive
operation as it can be fetched from the backend, it must be carefully
documented.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Lajos Katona &amp;lt;&lt;a class="reference external" href="mailto:katonalala%40gmail.com"&gt;katonalala&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt; (IRC: lajoskatona)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;REST API update.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB schema update.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L3 agent update to handle BFD:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;RPC change to send BFD data to l3 agent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RPC change to fetch BFD status information from l3 agent.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI update.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests and CI related changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit Test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functional test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API test&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Perhaps this is something that can be easily tested end-to-end with fullstack
tests. Need more investigation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;New API and changes to legacy APIs like routers must be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id9" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://tools.ietf.org/html/rfc5880"&gt;https://tools.ietf.org/html/rfc5880&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://tools.ietf.org/html/rfc5880#section-6.1"&gt;https://tools.ietf.org/html/rfc5880#section-6.1&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id11" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id5"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id6"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://tools.ietf.org/html/rfc5880#section-6.8.1"&gt;https://tools.ietf.org/html/rfc5880#section-6.8.1&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://tools.ietf.org/html/draft-wang-bfd-one-arm-use-case-00"&gt;https://tools.ietf.org/html/draft-wang-bfd-one-arm-use-case-00&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id13" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://tools.ietf.org/html/rfc5880#section-6.7"&gt;https://tools.ietf.org/html/rfc5880#section-6.7&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id14" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/neutron-lib/+/778859"&gt;https://review.opendev.org/c/openstack/neutron-lib/+/778859&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id15" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/neutron-specs/+/767337/7/specs/wallaby/bfd_support.rst#377"&gt;https://review.opendev.org/c/openstack/neutron-specs/+/767337/7/specs/wallaby/bfd_support.rst#377&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Mon, 02 Aug 2021 00:00:00 </pubDate></item><item><title>Distributed metadata datapath for Openvswitch Agent</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/yoga/distributed-metadata-data-path.html</link><description>

&lt;p&gt;RFE: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1933222"&gt;https://bugs.launchpad.net/neutron/+bug/1933222&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When instances are booting, they will try to retrieve metadata from
Nova by the path of Neutron virtual switches(bridges), virtual devices,
namespaces and metadata-agents. After that, metadata agent has no other
functionalities. In large-scale scenarios, a large number of deployed
metadata agents will cause a waste of resources for hosts and message queue.
Because metadata agents will start tons of external processes based on
the number of users’ resources, report state to Neutron server for keepalive.&lt;/p&gt;
&lt;p&gt;We are going to overcome this. This spec describes how to implement an
agent extension for Neutron openvswitch agent to make the metadata
datapath distributed.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;How many metadata-agent should run for a large scale cloud deployment?
There is no exact answer to this question. Cloud operators may setup
metadata agent to all hosts, something like DHCP agent.&lt;/p&gt;
&lt;p&gt;Config drive &lt;a class="footnote-reference brackets" href="#id3" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; can be an alternative for clouds to supply metadata for VMs.
But there are some limitations and security problem for config drive. For
instance, if you set config drive to use local disk, the live migration may
not be available. Config drive uses extra storage device and mounting it
inside VMs. Can not change userdata online for users specific scripts.
The security issue is that because the mounting FS can be access by all users,
if the metadata includes root password or key, the password and the key
can be accessed by none root users.&lt;/p&gt;
&lt;p&gt;If you are running Neutron agents, there is no alternative to replace
metadata agent for cloud deployments.&lt;/p&gt;
&lt;p&gt;As we can see, the metadata datapath is very long via many devices, namespaces
and agents. One metadata path goes down, such as agent down or external process
dead, will not only influence the host, but also all related hosts that will
boot new VMs on.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Adds an agent extension for Neutron openvswitch agent to make the metadata
datapath distributed.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This extension is only for openvswitch agent, other mechanism drivers
will not be considered, because this new extension will rely on the
openflow protocol and principle.&lt;/p&gt;
&lt;/div&gt;
&lt;section id="solution-proposed"&gt;
&lt;h3&gt;Solution Proposed&lt;/h3&gt;
&lt;section id="metadata-special-purpose-ip-and-mac"&gt;
&lt;h4&gt;Metadata Special purpose IP and MAC&lt;/h4&gt;
&lt;p&gt;Each VM in one host will generate a Meta IP + MAC pair which is unique among VM
on a host and which will be used to identify the metadata requestor
vm/port. The agent extension will do the generation work when handle port
in the first time, and store the Meta IP + MAC to ovsdb. When ovs-agent is
restarting, handle_port funtion will try to read the ovsdb first to reload
the Meta IP + MAC, if not exist, re-generate.&lt;/p&gt;
&lt;p&gt;During the agent extension initialization, it will add a internal port named
“tap-meta” to the ovs-bridge br-meta. This tap device will have a Meta Gateway
MAC + IP.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="potential-configrations"&gt;
&lt;h4&gt;Potential Configrations&lt;/h4&gt;
&lt;p&gt;Config options for Neutron openvswitch agent with this extension:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;METADATA&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;provider_cidr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;100.100.0.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;
&lt;span class="n"&gt;provider_vlan_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;998&lt;/span&gt;
&lt;span class="n"&gt;provider_base_mac&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"fa:16:ee:00:00:00"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;provider_cidr&lt;/span&gt;&lt;/code&gt; will be used as the IP range to generate the VM’s metadata IP.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;provider_vlan_id&lt;/span&gt;&lt;/code&gt; will be a fixed vlan for data from local tap-meta dev.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;provider_base_mac&lt;/span&gt;&lt;/code&gt; will be the MAC prefix to generate the VM’s META MAC.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can reuse the existing config option from metadata agent:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;METADATA_PROXY_HANDLER_OPTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StrOpt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'auth_ca_cert'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Certificate Authority public key (CA cert) "&lt;/span&gt;
                      &lt;span class="s2"&gt;"file for ssl"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HostAddressOpt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'nova_metadata_host'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'127.0.0.1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"IP address or DNS name of Nova metadata "&lt;/span&gt;
                              &lt;span class="s2"&gt;"server."&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PortOpt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'nova_metadata_port'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8775&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"TCP Port used by Nova metadata server."&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StrOpt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'metadata_proxy_shared_secret'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'When proxying metadata requests, Neutron signs the '&lt;/span&gt;
                      &lt;span class="s1"&gt;'Instance-ID header with a shared secret to prevent '&lt;/span&gt;
                      &lt;span class="s1"&gt;'spoofing. You may select any string for a secret, '&lt;/span&gt;
                      &lt;span class="s1"&gt;'but it must match here and in the configuration used '&lt;/span&gt;
                      &lt;span class="s1"&gt;'by the Nova Metadata Server. NOTE: Nova uses the same '&lt;/span&gt;
                      &lt;span class="s1"&gt;'config key, but in [neutron] section.'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
               &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StrOpt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'nova_metadata_protocol'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'http'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'http'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'https'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
               &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Protocol to access nova metadata, http or https"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BoolOpt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'nova_metadata_insecure'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Allow to perform insecure SSL (https) requests to "&lt;/span&gt;
                       &lt;span class="s2"&gt;"nova metadata"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StrOpt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'nova_client_cert'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Client certificate for nova metadata api server."&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StrOpt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'nova_client_priv_key'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Private key of client certificate."&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Basic backend config with http for haproxy will be:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;backend&lt;/span&gt; &lt;span class="n"&gt;backend_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_x&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;metasrv&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;nova_metadata_host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;nova_metadata_port&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In haproxy side if ssl verify is enabled, the backend will be:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;backend&lt;/span&gt; &lt;span class="n"&gt;backend_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_x&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;metasrv&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;nova_metadata_host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;nova_metadata_port&lt;/span&gt; &lt;span class="n"&gt;ssl&lt;/span&gt; &lt;span class="n"&gt;verify&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="n"&gt;ca&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;auth_ca_cert&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Or ssl with client certificate:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;backend&lt;/span&gt; &lt;span class="n"&gt;backend_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_x&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;metasrv&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;nova_metadata_host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;nova_metadata_port&lt;/span&gt; &lt;span class="n"&gt;ssl&lt;/span&gt; &lt;span class="n"&gt;verify&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="n"&gt;ca&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nova_client_cert&lt;/span&gt; &lt;span class="n"&gt;crt&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nova_client_priv_key&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;If the cloud has its own client certificate, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;crt&lt;/span&gt;&lt;/code&gt; parameter
can point to your client certificate file. But this is supported
since haproxy version &amp;gt;= 2.4.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="metadata-data-pipelines"&gt;
&lt;h4&gt;Metadata data pipelines&lt;/h4&gt;
&lt;section id="sample-resource-datas"&gt;
&lt;h5&gt;Sample Resource Datas&lt;/h5&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;VM1 - network1 local_vlan_id=1, fixed_ip 192.168.1.10, port mac fa:16:3e:4a:fd:c1, Meta_IP 100.100.0.10, Meta_MAC fa:16:ee:00:00:11&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VM2 - network2 local_vlan_id=2, fixed_ip 192.168.2.10, port mac fa:16:3e:4a:fd:c2, Meta_IP 100.100.0.11, Meta_MAC fa:16:ee:00:00:22&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VM3 - network1 local_vlan_id=1, fixed_ip 192.168.1.20, port mac fa:16:3e:4a:fd:c3, Meta_IP 100.100.0.12, Meta_MAC fa:16:ee:00:00:33&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VM4 - network3 local_vlan_id=3, fixed_ip 192.168.3.10, port mac fa:16:3e:4a:fd:c4, Meta_IP 100.100.0.13, Meta_MAC fa:16:ee:00:00:44&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;META Gateway IP 100.100.0.1, META Gateway MAC: fa:16:ee:00:00:01&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="tcp-egress"&gt;
&lt;h5&gt;TCP Egress&lt;/h5&gt;
&lt;p&gt;HTTP request packets from VM direct to br-meta, and change IP headers to tap-meta,
add HTTP headers in host haproxy then go to nova-metadata API. Datapath:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+----+&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt; &lt;span class="o"&gt;+-----------------------------------+&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt; &lt;span class="o"&gt;+---------------------------------------------+&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt; &lt;span class="o"&gt;+------------------------+&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt; &lt;span class="o"&gt;+-----------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;+-----&amp;gt;&lt;/span&gt;             &lt;span class="n"&gt;Br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;                &lt;span class="o"&gt;+-----&amp;gt;&lt;/span&gt;                   &lt;span class="n"&gt;Br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;meta&lt;/span&gt;                   &lt;span class="o"&gt;+-----&amp;gt;&lt;/span&gt;        &lt;span class="n"&gt;tap&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Meta&lt;/span&gt;        &lt;span class="o"&gt;+-----&amp;gt;&lt;/span&gt;        &lt;span class="n"&gt;Haproxy&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;From&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;169.254.169.254&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;Source&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;VM&lt;/span&gt; &lt;span class="n"&gt;MAC&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="o"&gt;--&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Meta&lt;/span&gt; &lt;span class="n"&gt;MAC&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Meta&lt;/span&gt; &lt;span class="n"&gt;Gateway&lt;/span&gt; &lt;span class="n"&gt;MAC&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;Match&lt;/span&gt; &lt;span class="n"&gt;Meta&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt; &lt;span class="n"&gt;vlan&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Dest&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAC&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="o"&gt;--&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Meta&lt;/span&gt; &lt;span class="n"&gt;Gateway&lt;/span&gt; &lt;span class="n"&gt;MAC&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="n"&gt;Listened&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;Add&lt;/span&gt; &lt;span class="n"&gt;Http&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;Br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;meta&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;tap&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Meta&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;Haproxy&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;Nova&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Metadata&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;API&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----+&lt;/span&gt;     &lt;span class="o"&gt;+-----------------------------------+&lt;/span&gt;     &lt;span class="o"&gt;+---------------------------------------------+&lt;/span&gt;     &lt;span class="o"&gt;+------------------------+&lt;/span&gt;     &lt;span class="o"&gt;+-----------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Flows (some keywords are pseudo code) on br-int:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;of_vm1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;169.254.169.254&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;mod_local_vlan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"To_br_meta"&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;of_vm2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;169.254.169.254&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;mod_local_vlan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"To_br_meta"&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;of_vm3&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;169.254.169.254&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;mod_local_vlan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"To_br_meta"&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;of_vm4&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;169.254.169.254&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;mod_local_vlan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"To_br_meta"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When your VM trying to access 169.254.169.254:80, what should the dest
MAC + IP be? The dest IP is clear, it is 169.254.169.254. The complicated
case is the dest MAC. We have three scenarios:&lt;/p&gt;
&lt;p&gt;a. if your VM has only one default route which point to gateway, so the request
dest MAC should be gateway MAC.&lt;/p&gt;
&lt;p&gt;b. if your VM has a route which directly point to 169.254.169.254 (for instance,
to 169.254.169.254 via 192.168.1.2 &amp;lt;the DHCP port IP&amp;gt;, normally, this is set
by original DHCP-agent and metadata mechanism), so some ARP responder(s) will
be added for such DHCP port IPs, in case of upgrading. A fake mac will be
responded for these DHCP port IPs.&lt;/p&gt;
&lt;p&gt;c. if your VM has a link route which is telling guest OS 169.254.169.254 is
directly reachable. So an ARP responder for 169.254.169.254 will be added.
So the dest MAC will be a fake one as well.&lt;/p&gt;
&lt;p&gt;Flows on br-meta:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;patch_br_int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;169.254.169.254&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;resubmit&lt;/span&gt;&lt;span class="p"&gt;(,&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dl_vlan&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;local_vlan_1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;192.168.1.10&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;strip_vlan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_dl_src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_nw_src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;100.100.0.10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resubmit&lt;/span&gt;&lt;span class="p"&gt;(,&lt;/span&gt;&lt;span class="mi"&gt;87&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dl_vlan&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;local_vlan_2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;c2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;192.168.2.10&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;strip_vlan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_dl_src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_nw_src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;100.100.0.11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resubmit&lt;/span&gt;&lt;span class="p"&gt;(,&lt;/span&gt;&lt;span class="mi"&gt;87&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dl_vlan&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;local_vlan_1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;c3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;192.168.1.20&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;strip_vlan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_dl_src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_nw_src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;100.100.0.12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resubmit&lt;/span&gt;&lt;span class="p"&gt;(,&lt;/span&gt;&lt;span class="mi"&gt;87&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dl_vlan&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;local_vlan_3&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;c4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;192.168.3.10&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;strip_vlan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_dl_src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_nw_src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;100.100.0.13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resubmit&lt;/span&gt;&lt;span class="p"&gt;(,&lt;/span&gt;&lt;span class="mi"&gt;87&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;87&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tcp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;169.254.169.254&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;tp_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mod_nw_dst&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;100.100.0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mod_dl_dst&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"tap-meta"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="tcp-ingress"&gt;
&lt;h5&gt;TCP Ingress&lt;/h5&gt;
&lt;p&gt;HTTP packets come from tap-meta to br-meta directly, then go to br-int and
finnaly direct to VM. Datapath:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+----+&lt;/span&gt;     &lt;span class="o"&gt;+---------------------+&lt;/span&gt;     &lt;span class="o"&gt;+---------------------------------------+&lt;/span&gt;     &lt;span class="o"&gt;+---------------+&lt;/span&gt;     &lt;span class="o"&gt;+------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="n"&gt;Br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="n"&gt;Br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;meta&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;tap&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Meta&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="n"&gt;Haproxy&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;From&lt;/span&gt; &lt;span class="n"&gt;patch_br_meta&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;Source&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="o"&gt;---&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;169.254.169.254&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Http&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;mac_dst&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Dest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Meta&lt;/span&gt; &lt;span class="n"&gt;MAC&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="o"&gt;---&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt; &lt;span class="n"&gt;MAC&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="n"&gt;To&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;To&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;-----+&lt;/span&gt;   &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;-----+&lt;/span&gt;               &lt;span class="n"&gt;to&lt;/span&gt;  &lt;span class="n"&gt;Br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;              &lt;span class="o"&gt;&amp;lt;-----+&lt;/span&gt; &lt;span class="n"&gt;Meta&lt;/span&gt; &lt;span class="n"&gt;MAC&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-----+&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Meta&lt;/span&gt; &lt;span class="n"&gt;MAC&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----+&lt;/span&gt;     &lt;span class="o"&gt;+---------------------+&lt;/span&gt;     &lt;span class="o"&gt;+---------------------------------------+&lt;/span&gt;     &lt;span class="o"&gt;+---------------+&lt;/span&gt;     &lt;span class="o"&gt;+------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Flows on br-meta:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"tap-meta"&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;push_vlan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;goto_table&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;91&lt;/span&gt;

&lt;span class="n"&gt;Table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;91&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dl_vlan&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;998&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;100.100.0.10&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mod_vlan_vid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_dl_dst&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_nw_dst&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;192.168.1.10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_nw_src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;169.254.169.254&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"to-br-int"&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dl_vlan&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;998&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;100.100.0.11&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mod_vlan_vid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_dl_dst&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;c2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_nw_dst&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;192.168.2.10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_nw_src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;169.254.169.254&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"to-br-int"&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dl_vlan&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;998&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;100.100.0.12&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mod_vlan_vid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_dl_dst&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;c3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_nw_dst&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;192.168.1.20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_nw_src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;169.254.169.254&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"to-br-int"&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dl_vlan&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;998&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;100.100.0.13&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mod_vlan_vid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_dl_dst&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;c4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_nw_dst&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;192.168.3.10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mod_nw_src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;169.254.169.254&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"to-br-int"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Flows on br-int:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;patch_br_meta&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_vlan&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_dst&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;vm1_mac_fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;169.254.169.254&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;strip_vlan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;of_vm1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;patch_br_meta&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_vlan&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_dst&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;vm2_mac_fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;c2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;169.254.169.254&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;strip_vlan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;of_vm2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;patch_br_meta&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_vlan&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_dst&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;vm3_mac_fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;c3&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;169.254.169.254&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;strip_vlan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;of_vm3&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;patch_br_meta&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_vlan&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_dst&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;vm4_mac_fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;c4&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;169.254.169.254&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;strip_vlan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;of_vm4&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="arp-for-metadata-ips"&gt;
&lt;h5&gt;ARP for Metadata IPs&lt;/h5&gt;
&lt;p&gt;Tap-meta device will be resident on host kernel IP stack, before the first
response of TCP, the host (protocol stack) needs to know the META_IP’s MAC
address. So ARP reqeust is broadcast. ARP will be sent from tap-meta device
to br-meta responder. The ARP responder datapath:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+---------------------------+&lt;/span&gt;      &lt;span class="o"&gt;+---------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="n"&gt;Br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;meta&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;tap&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Meta&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ARP&lt;/span&gt; &lt;span class="n"&gt;Responder&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Meta&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;Learn&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="n"&gt;to&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ARP&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Meta&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="s1"&gt;'s MAC |&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="n"&gt;INPORT&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;------+&lt;/span&gt;     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ARP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+---------------------------+&lt;/span&gt;      &lt;span class="o"&gt;+---------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The flows on br-meta will be:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Ingress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;Table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;arp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"tap-meta"&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;resubmit&lt;/span&gt;&lt;span class="p"&gt;(,&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;arp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;arp_tpa&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;100.100.0.10&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ARP&lt;/span&gt; &lt;span class="n"&gt;Responder&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;Meta_MAC&lt;/span&gt; &lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;IN_PORT&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;arp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;arp_tpa&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;100.100.0.11&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ARP&lt;/span&gt; &lt;span class="n"&gt;Responder&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;Meta_MAC&lt;/span&gt; &lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;IN_PORT&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;arp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;arp_tpa&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;100.100.0.12&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ARP&lt;/span&gt; &lt;span class="n"&gt;Responder&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;Meta_MAC&lt;/span&gt; &lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;IN_PORT&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;arp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;arp_tpa&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;100.100.0.13&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ARP&lt;/span&gt; &lt;span class="n"&gt;Responder&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;Meta_MAC&lt;/span&gt; &lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;IN_PORT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="host-haproxy-configurations"&gt;
&lt;h4&gt;Host haproxy configurations&lt;/h4&gt;
&lt;p&gt;The host haproxy is one only process which is used for all VMs. The host
haproxy will add HTTP headers to the metadata request which is needed for
metadata API. The headers have a fixed algorithm which is easy to
assemble. For each VM’s request, haproxy will add an independent backend
and a match rule of checking the source IP (aka Meta_IP). While the request
from one VM’s (Meta_IP) it will be send to the matched backend, which add
HTTP headers and then send to real nova-metadata-api.&lt;/p&gt;
&lt;p&gt;Configurations:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;global&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;         &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="n"&gt;local0&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;log_level&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;        &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;group&lt;/span&gt;       &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;maxconn&lt;/span&gt;     &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;maxconn&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;daemon&lt;/span&gt;

&lt;span class="n"&gt;frontend&lt;/span&gt; &lt;span class="n"&gt;public&lt;/span&gt;
    &lt;span class="n"&gt;bind&lt;/span&gt;            &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;clear&lt;/span&gt;
    &lt;span class="n"&gt;mode&lt;/span&gt;            &lt;span class="n"&gt;http&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;             &lt;span class="k"&gt;global&lt;/span&gt;
    &lt;span class="n"&gt;option&lt;/span&gt;          &lt;span class="n"&gt;httplog&lt;/span&gt;
    &lt;span class="n"&gt;option&lt;/span&gt;          &lt;span class="n"&gt;dontlognull&lt;/span&gt;
    &lt;span class="n"&gt;maxconn&lt;/span&gt;         &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;maxconn&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;  &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;

    &lt;span class="n"&gt;acl&lt;/span&gt; &lt;span class="n"&gt;instance_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_1&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_1&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;acl&lt;/span&gt; &lt;span class="n"&gt;instance_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_2&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_2&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;acl&lt;/span&gt; &lt;span class="n"&gt;instance_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_3&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_3&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;acl&lt;/span&gt; &lt;span class="n"&gt;instance_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_4&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_4&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;

    &lt;span class="n"&gt;use_backend&lt;/span&gt; &lt;span class="n"&gt;backend_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_1&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;instance_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_1&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;use_backend&lt;/span&gt; &lt;span class="n"&gt;backend_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_2&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;instance_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_2&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;use_backend&lt;/span&gt; &lt;span class="n"&gt;backend_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_3&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;instance_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_3&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;use_backend&lt;/span&gt; &lt;span class="n"&gt;backend_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_4&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;instance_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_4&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;

&lt;span class="n"&gt;backend&lt;/span&gt; &lt;span class="n"&gt;backend_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_1&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;balance&lt;/span&gt;         &lt;span class="n"&gt;roundrobin&lt;/span&gt;
    &lt;span class="n"&gt;retries&lt;/span&gt;         &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="n"&gt;redispatch&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;    &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="n"&gt;connect&lt;/span&gt;         &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;          &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;

    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Instance&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Tenant&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Instance&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Signature&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;signature&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;

    &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;metasrv&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="n"&gt;backend&lt;/span&gt; &lt;span class="n"&gt;backend_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_2&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;balance&lt;/span&gt;         &lt;span class="n"&gt;roundrobin&lt;/span&gt;
    &lt;span class="n"&gt;retries&lt;/span&gt;         &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="n"&gt;redispatch&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;    &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="n"&gt;connect&lt;/span&gt;         &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;          &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;

    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Instance&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Tenant&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Instance&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Signature&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;signature&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;

    &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;metasrv&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="n"&gt;backend&lt;/span&gt; &lt;span class="n"&gt;backend_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_3&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="n"&gt;backend&lt;/span&gt; &lt;span class="n"&gt;backend_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;instance_4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;metadata_ip_4&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="ipv6-metadata"&gt;
&lt;h4&gt;IPv6 metadata&lt;/h4&gt;
&lt;p&gt;The metadata for IPv6 &lt;a class="footnote-reference brackets" href="#id4" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; only network has similar address &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;fe80::a9fe:a9fe&lt;/span&gt;&lt;/code&gt;,
so all these works can be mirrored for IPv6. For IPv6 the generator
will use the range &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;fe80:ffff:a9fe:a9fe::/64&lt;/span&gt;&lt;/code&gt; to allocate Meta_IPv6 address.
The Meta_gateway_IPv6 address will be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;fe80:ffff:a9fe:a9fe::1&lt;/span&gt;&lt;/code&gt;, Gateway MAC is
still the same one &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;fa:16:ee:00:00:01&lt;/span&gt;&lt;/code&gt;. NA responder
for Meta_IPv6 address &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;fe80:ffff:a9fe:a9fe::abcd&lt;/span&gt;&lt;/code&gt; and Meta_MAC
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;fa:16:ee:00:00:11&lt;/span&gt;&lt;/code&gt; will be:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;icmp6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;icmp_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;135&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;icmp_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nd_sll&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;set_field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;136&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;icmpv6_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;set_field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;icmpv6_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;set_field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;icmpv6_options_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;goto_table&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;

&lt;span class="n"&gt;Table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;
&lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;icmp6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;icmp_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;136&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;icmp_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nd_target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fe80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ffff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;a9fe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;a9fe&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;abcd&lt;/span&gt;
&lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_ETH_SRC&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_ETH_DST&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="n"&gt;set_field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;eth_src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;NXM_NX_IPV6_SRC&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NXM_NX_IPV6_DST&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="n"&gt;set_field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fe80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ffff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;a9fe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;a9fe&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;abcd&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;ipv6_src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;set_field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;nd&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tll&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;set_field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mh"&gt;0xE000&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;OFPXMT_OFB_ICMPV6_ND_RESERVED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;IN_PORT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;LIU Yulong &amp;lt;&lt;a class="reference external" href="mailto:i%40liuyulong.me"&gt;i&lt;span&gt;@&lt;/span&gt;liuyulong&lt;span&gt;.&lt;/span&gt;me&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Adding flows action for ovs bridges&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adding host haproxy manager for ovs-agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adding host metadata IP and Mac generator with ovsdb settings&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adding ovs-agent extension to set up flows for VM ports&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Test cases to verify the metadata can be set properly, this can be done by
using existing jobs with new new metadata driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/nova/latest/user/metadata.html"&gt;https://docs.openstack.org/nova/latest/user/metadata.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1460177"&gt;https://bugs.launchpad.net/neutron/+bug/1460177&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Thu, 29 Jul 2021 00:00:00 </pubDate></item><item><title>OVS auxiliary bridge to reduce live migration networking disruption in OVN</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/xena/ovn-auxiliary-port-bridge-live-migration.html</link><description>

&lt;p&gt;Launchpad bug: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1933517"&gt;https://bugs.launchpad.net/neutron/+bug/1933517&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The goal of this spec is to propose a change in the VM - backend (OVN)
connectivity to improve the live migration process.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The live migration is a very sensitive process that implies to configure
a destination host to execute a virtual machine that is already running.
When the destination hypervisor is prepared, the source virtual machine
is paused and immediately unpaused in the destination host.&lt;/p&gt;
&lt;p&gt;Since &lt;a class="footnote-reference brackets" href="#id16" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and &lt;a class="footnote-reference brackets" href="#id17" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, Nova is capable of plugging the port and create the
interface in the destination host during the pre-live migration. But the TAP
device is created by libvirt when the VM is unpaused. This is when the port
interface is assigned with an OpenFlow port ID.&lt;/p&gt;
&lt;p&gt;When the port is created, the network backend detects the new port attached
and informs to the OVN Northbound and this event is received by Neutron. The
network backend is commanded to configure the needed rules for this new port.&lt;/p&gt;
&lt;p&gt;The problem with this sequence of actions is that when the virtual
machine is unpaused, the network backend is not ready to continue any
network communication until the OVN controller (in the compute node) has set
all needed OpenFlow rules and chassis configuration, using the OpenFlow port
ID (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;interface.ofport&lt;/span&gt;&lt;/code&gt;) assigned when the TAP interface is created.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The spec scope is limited to the OVN backend. This spec does not consider the
case of HW offloaded ports, that have other plug process. This spec is only
considering &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os_vif.objects.vif.VIFOpenVSwitch&lt;/span&gt;&lt;/code&gt; VIF types within the related
network backend.&lt;/p&gt;
&lt;p&gt;This spec proposes to create an intermediate OVS bridge between the integration
bridge and the virtual machine tap interface. This OVS bridge will be connected
to the integration bridge with a patch port. The TAP interface will be plugged
into the intermediate bridge when the virtual machine is created or unpaused
(that happens during the live migration). This architecture is very similar to
OVS hybrid plugging, but with an OVS bridge in between.&lt;/p&gt;
&lt;p&gt;The advantage of this approach is that the integration bridge port, in this
case the patch port, that is created during the pre-live migration process, has
a valid OpenFlow port ID (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;interface.ofport&lt;/span&gt;&lt;/code&gt;), needed to provide the correct
OpenFlow rules in the integration bridge.&lt;/p&gt;
&lt;p&gt;After the port is plugged, Nova commands to libvirt to copy the guest memory
to the destination host. If “live_migration_permit_post_copy” is used &lt;a class="footnote-reference brackets" href="#id18" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;,
the virtual machine on the destination host will be activated before all its
memory has been copied. However there is a period of time where the port
is bound to the destination host and the virtual machine is still running on
the source host. During this period of time, the virtual machine won’t be
able to communicate, same as without this feature.&lt;/p&gt;
&lt;p&gt;When the virtual machine is unpaused in the destination host, the OVN
backend is ready to immediately continue transmitting packets from the guess.&lt;/p&gt;
&lt;section id="implementation"&gt;
&lt;h3&gt;Implementation&lt;/h3&gt;
&lt;p&gt;The VIF plug and unplug process is executed by Nova, using the different
backend implementations provided by &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-vif&lt;/span&gt;&lt;/code&gt; library. The bridge creation
and deletion will be done during the plug and unplug processes &lt;a class="footnote-reference brackets" href="#id19" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, as in OVS
hybrid plug strategy.&lt;/p&gt;
&lt;p&gt;The proposed architecture and naming is the following one, implemented in
&lt;a class="footnote-reference brackets" href="#id20" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;      ┌────────┐
      │tap-xxx │           TAP interface port
┌─────┴────────┴─────┐
│      pbr-xxx       │     Port bridge
└─────┬────────┬─────┘
      │pbp-xxx │           Port bridge patch port (port bridge side)
      └────┬───┘
      ┌────┴───┐
      │ipb-xxx │           Port bridge patch port (integration bridge side)
┌─────┴────────┴─────┐
│    integration     │
│      bridge        │
└────────────────────┘
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For each new VM TAP interface, an OVS bridge is created along with the patch
port to connect this bridge with the integration bridge. This port bridge will
have a default OpenFlow rule, allowing all traffic from the TAP interface port
to the patch port:&lt;/p&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="go"&gt;cookie=0x0, duration=84162.020s, table=0, n_packets=444223, n_bytes=832399534, priority=0 actions=NORMAL&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;OVN links the OVS ports (Open vSwitch DB) with the Logical Switch Ports (OVN
NB database) using the Neutron DB port ID. The OVN NB Logical Switch Port,
created by Neutron, will have this port ID in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;lsp.name&lt;/span&gt;&lt;/code&gt; field. The OVS
port &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ipb-xxx&lt;/span&gt;&lt;/code&gt; (the integration bridge side patch port) is created with
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;interface.external_ids={iface-id:&lt;/span&gt; &lt;span class="pre"&gt;port_id}&lt;/span&gt;&lt;/code&gt;. The ovn-controller will detect
this new port and assign to OVN SB Port Binding the corresponding chassis.
The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;interface.external_ids&lt;/span&gt;&lt;/code&gt; information is added by &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-vif&lt;/span&gt;&lt;/code&gt; during the
port plug process &lt;a class="footnote-reference brackets" href="#id20" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, called by Nova.&lt;/p&gt;
&lt;p&gt;Note: OVS and OVN ports are represented in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-vif&lt;/span&gt;&lt;/code&gt; with the same VIF type,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;objects.vif.VIFOpenVSwitch&lt;/span&gt;&lt;/code&gt;. The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-vif&lt;/span&gt;&lt;/code&gt; implementation could be used
both for OVS and OVN backends. However, the scope of this spec is limited to
OVN backend only.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="nova-neutron-events"&gt;
&lt;h3&gt;Nova - Neutron events&lt;/h3&gt;
&lt;p&gt;Nova and Neutron have a mechanism to communicate the state of the VIFs &lt;a class="footnote-reference brackets" href="#id21" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.
This is a unidirectional API that allows Neutron to inform Nova when a VIF has
been plugged or unplugged. Nova expects from Neutron a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network-vif-plugged&lt;/span&gt;&lt;/code&gt;
event when the port has been bound or plugged. Depending on the backend, Nova
will expect a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network-vif-plugged&lt;/span&gt;&lt;/code&gt; when the port has been bound or when
the port has been plugged &lt;a class="footnote-reference brackets" href="#id22" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. For example, in OVS with hybrid plug, Nova
expects the event when the port has been plugged to the OVS. In OVN, Nova is
expecting this event when the port has been bound during the live migration
process &lt;a class="footnote-reference brackets" href="#id23" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once Nova creates the intermediate bridge &lt;a class="footnote-reference brackets" href="#id16" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id17" id="id11" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, Neutron can send the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network-vif-plugged&lt;/span&gt;&lt;/code&gt; event when the port is plugged and the network backend
is configured.&lt;/p&gt;
&lt;p&gt;This spec proposes to use the existing OVN event infrastructure to capture the
patch port creation event, using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;LogicalSwitchPortCreateUpEvent&lt;/span&gt;&lt;/code&gt;, and in
the handler method push the event to Nova. Along with this change, Neutron will
inform Nova about the backend used in the port adding a field in
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port.vif_details&lt;/span&gt;&lt;/code&gt; called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;backend&lt;/span&gt;&lt;/code&gt;. The value will be “ovn”. This
port update will be done in &lt;a class="footnote-reference brackets" href="#id24" id="id12" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;9&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, in the mech driver port binding method.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="neutron-configuration"&gt;
&lt;h3&gt;Neutron configuration&lt;/h3&gt;
&lt;p&gt;As explained in the previous section, this spec proposes to change the event
emission from Neutron. That will depend on if &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-vif&lt;/span&gt;&lt;/code&gt; is configured to
create this intermediate bridge between the integration bridge and the TAP
device.&lt;/p&gt;
&lt;p&gt;Because Neutron cannot read the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-vif&lt;/span&gt;&lt;/code&gt; configuration, this spec proposes
to add the same config flag in the ML2 OVN plugin section: “per_port_bridge”.&lt;/p&gt;
&lt;p&gt;If enabled, Neutron will send the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network-vif-plugged&lt;/span&gt;&lt;/code&gt; when the port is
plugged, not when the port binding is updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="qos"&gt;
&lt;h3&gt;QoS&lt;/h3&gt;
&lt;p&gt;With this feature, the Logical Switch Port is now the patch port between the
port bridge and the TAP device, not the TAP device port. In OVS, QoS rules
can only be applied to external ports. However, in OVN the QoS rules are
applied using the “match” field in the QoS register &lt;a class="footnote-reference brackets" href="#id25" id="id13" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;10&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. This is a string
in the same expression language used in the Logical_Flow table. The traffic
shaping applied to the TAP device is the same when using the patch port
reference because the traffic flow is the same in both ports.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance"&gt;
&lt;h3&gt;Performance&lt;/h3&gt;
&lt;p&gt;The intermediate bridge will have one single rule, with action NORMAL. That
means all traffic coming from the TAP port will be sent to the patch port and
vice versa.&lt;/p&gt;
&lt;p&gt;The datapath will collapse this bridge resulting in an identical flow as
without the bridge. In other words, the new intermediate bridge won’t have any
effect on packet processing performance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ovn-dpdk"&gt;
&lt;h3&gt;OVN DPDK&lt;/h3&gt;
&lt;p&gt;Same as with other bridges (physical bridges, tunnel bridges, external
bridges), each port bridge will be connected to the integration bridge with a
patch port. That keeps one single datapath (“netdev” in DPDK case), as
commented in the previous section.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="upgrade-impact"&gt;
&lt;h3&gt;Upgrade Impact&lt;/h3&gt;
&lt;p&gt;This feature could be enabled in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os-vif&lt;/span&gt;&lt;/code&gt; using the configuration variable
“per_port_bridge” &lt;a class="footnote-reference brackets" href="#id26" id="id14" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;11&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. If this option is enabled, any OVN port will be
plugged and unplugged using the implementation described in this spec.
Currently this implementation does not handle mixing both plugging methods
(connecting the TAP port directly to the integration bridge or creating the
port bridge as described in this spec). If this option is enabled, the compute
node should not host any virtual machine. At this point, as described in the
proposed change, any virtual machine created or migrated to this host, will
be plugged using the intermediate port bridge. In case of migration, that will
solve or mitigate the connectivity problems when the virtual machine is
unpaused in the destination host.&lt;/p&gt;
&lt;p&gt;This spec does not cover any scenario mixing TAP ports using both plug
strategies on the same host (same as with OVS hybrid plugging strategy).&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Live migration tempest tests are covered in the Nova CI. In order to test this
feature, a set of tests from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tempest.api.compute.admin.test_live_migration&lt;/span&gt;&lt;/code&gt;
should be executed on &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron-ovn-tempest-slow&lt;/span&gt;&lt;/code&gt; CI job.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Document the new architecture and the configuration flag to change the event
emission from Neutron.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="id15"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Sean K Mooney (&lt;a class="reference external" href="mailto:smooney%40redhat.com"&gt;smooney&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;, IRC: sean-k-mooney)
Rodolfo Alonso Hernandez (&lt;a class="reference external" href="mailto:ralonsoh%40redhat.com"&gt;ralonsoh&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;, IRC: ralonsoh)&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id16" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id10"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/nova/+/602432"&gt;https://review.opendev.org/c/openstack/nova/+/602432&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id17" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id11"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/nova/+/797428"&gt;https://review.opendev.org/c/openstack/nova/+/797428&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id18" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/nova/pike/admin/live-migration-usage.html"&gt;https://docs.openstack.org/nova/pike/admin/live-migration-usage.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id19" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/os-vif/blob/e93736711920afe64a850f564dddefbd704975cd/vif_plug_ovs/ovs.py"&gt;https://github.com/openstack/os-vif/blob/e93736711920afe64a850f564dddefbd704975cd/vif_plug_ovs/ovs.py&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id20" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id5"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id6"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/os-vif/+/798055"&gt;https://review.opendev.org/c/openstack/os-vif/+/798055&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id21" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Nova/ExternalEventAPI"&gt;https://wiki.openstack.org/wiki/Nova/ExternalEventAPI&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id22" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/nova/blob/e7a7fd51d12d045ff134d55a4a1749c1feee0386/nova/network/model.py#L464-L481"&gt;https://github.com/openstack/nova/blob/e7a7fd51d12d045ff134d55a4a1749c1feee0386/nova/network/model.py#L464-L481&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id23" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/13e96bf6bd740a09283d9e2849fc2b6adbbf29e3/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py#L796-L815"&gt;https://github.com/openstack/neutron/blob/13e96bf6bd740a09283d9e2849fc2b6adbbf29e3/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py#L796-L815&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id24" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id12"&gt;9&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/2acb96c37468120ba79de7d8de48ffb942e78a2b/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py#L840-L960"&gt;https://github.com/openstack/neutron/blob/2acb96c37468120ba79de7d8de48ffb942e78a2b/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py#L840-L960&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id25" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id13"&gt;10&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.ovn.org/support/dist-docs/ovn-nb.5.html"&gt;https://www.ovn.org/support/dist-docs/ovn-nb.5.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id26" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id14"&gt;11&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/os-vif/blob/b837c1a74f37191692a820711e431a75516a4abf/vif_plug_ovs/ovs.py#L100"&gt;https://github.com/openstack/os-vif/blob/b837c1a74f37191692a820711e431a75516a4abf/vif_plug_ovs/ovs.py#L100&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Fri, 02 Jul 2021 00:00:00 </pubDate></item><item><title>Neutron VLAN networks with QinQ support</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/yoga/qinq_networks.html</link><description>

&lt;p&gt;Launchpad Bug:
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1915151"&gt;https://bugs.launchpad.net/neutron/+bug/1915151&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron supports networks with vlan transparency but in case where it is used
with VLAN networks, there is no way to use it as QinQ which is different
ethertype (e.g. 0x8a88) than regular vlan ethertype (0x8100).&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Networks with enabled vlan transparency can be of any type available in Neutron
(vxlan, vlan, flat, etc.). In most cases it is fine when packets sent from the
node and have ethertype 0x8100 (802.1q).
But in such case as we have 2 vlans already (S-Tag and C-Tag) there are some
use cases where it should be sent as QinQ which is slightly different standard
and have different ethertype (0x8a88) &lt;a class="footnote-reference brackets" href="#id3" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Add new API extension to extend &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network&lt;/span&gt;&lt;/code&gt; resource in Neutron with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qinq&lt;/span&gt;&lt;/code&gt;
attribute. This new attribute would be valid only for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vlan&lt;/span&gt;&lt;/code&gt; networks and in
case of that networks would work similary to what current &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VLAN&lt;/span&gt; &lt;span class="pre"&gt;transparency&lt;/span&gt;&lt;/code&gt;
extension &lt;a class="footnote-reference brackets" href="#id4" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. The difference between vlan transparency and new qinq extensions
would be in the ethertype configured for packets in such network send from the
node.
In case of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qinq=True&lt;/span&gt;&lt;/code&gt; S-Tag and C-Tag will work in same way like it is now
for the networks with enabled vlan transparency. C-Tag is configured directly in
the instance by user and S-Tag is configured and controlled by Neutron. The
difference will be that ethertype of the packets sent from the node will be
0x8a88.
Attributes &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vlan_transparent&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qinq&lt;/span&gt;&lt;/code&gt; will be mutually exclusive. Only
one of them can be set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt; for the network.&lt;/p&gt;
&lt;section id="server-side-changes"&gt;
&lt;h3&gt;Server side changes&lt;/h3&gt;
&lt;p&gt;A new API extension of Neutron will be added with new attribute for the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network&lt;/span&gt;&lt;/code&gt; resource. This new attribute will be called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qinq&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;COLLECTION_NAME&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"qinq"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;converters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ATTR_NOT_SPECIFIED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Attribute &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qinq&lt;/span&gt;&lt;/code&gt; will have effect only for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vlan&lt;/span&gt;&lt;/code&gt; networks.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Attributes &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vlan_transparent&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qinq&lt;/span&gt;&lt;/code&gt; would be mutually
exclusive. Only one of them can be set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="agent-side-changes"&gt;
&lt;h3&gt;Agent side changes&lt;/h3&gt;
&lt;p&gt;Currently &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;linuxbridge&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ovn&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SR-IOV&lt;/span&gt;&lt;/code&gt; backends supports VLAN
transparency and QinQ will be supported by the same backends.
In case of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;linuxbridge&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ovn&lt;/span&gt;&lt;/code&gt; backends correct ethertype will need to
be set on the nodes so correct ethertype will be set for the packets.
In case of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SR-IOV&lt;/span&gt;&lt;/code&gt; backend support for that feature will depend on the
hardware and its driver and that will need to be tested separately.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="db-impact"&gt;
&lt;h3&gt;DB Impact&lt;/h3&gt;
&lt;p&gt;Extend the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;networks&lt;/span&gt;&lt;/code&gt; table with boolean column &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qinq&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="client-impact"&gt;
&lt;h3&gt;Client Impact&lt;/h3&gt;
&lt;p&gt;Relevant changes in osc and openstacksdk to add support for new network’s
attribute. To enable it for network, it should be something like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;qinq&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and to disable it:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;no&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;qinq&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fullstack test.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests in neutron-tempest-plugin.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Slawek Kaplonski &amp;lt;&lt;a class="reference external" href="mailto:skaplons%40redhat.com"&gt;skaplons&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://en.wikipedia.org/wiki/IEEE_802.1ad"&gt;https://en.wikipedia.org/wiki/IEEE_802.1ad&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/api-ref/network/v2/#vlan-transparency-extension"&gt;https://docs.openstack.org/api-ref/network/v2/#vlan-transparency-extension&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 29 Jun 2021 00:00:00 </pubDate></item><item><title>Node-Local virtual IP address (Local IP)</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/xena/node-local-ip.html</link><description>

&lt;p&gt;RFE: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1930200"&gt;https://bugs.launchpad.net/neutron/+bug/1930200&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes a new type of shared virtual IP address that can be used to
access distributed and/or multi-node services and applications running in the
cloud. The feature is primarily focused on high efficiency and performance of
the networking data plane for very large scale clouds and/or clouds with high
network throughput demands.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;In a topology where several workloads access a shared resource over network
obvious bottlenecks are the network and the shared resource itself
(or a loadbalancer):&lt;/p&gt;
&lt;img alt="../../_images/node-local-ip-problem.png" src="../../_images/node-local-ip-problem.png"/&gt;
&lt;p&gt;Proposed feature suggests to solve this bottleneck issue by deploying local
replicas/caches of the shared service and re-translating local workloads`
requests to these replicas transparently. Transparency is achieved by
assigning same IP address to local replicas as on main shared resource.&lt;/p&gt;
&lt;img alt="../../_images/node-local-ip-solution.png" src="../../_images/node-local-ip-solution.png"/&gt;
&lt;p&gt;Primary use-cases for this feature are listed in the RFE description. While
the proposed virtual IP may be used on its own for simple use cases, it is
mainly intended to serve as a basic building block and should be used in
conjunction with other services to provide full-fledged service discovery,
load balancing, proxying and other advanced features.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Add a new Node Local IP (or just Local IP) resource - a virtual IP that can be
shared across multiple ports/VMs (similar to anycast IP) and is guaranteed
to only be reachable within the same physical server/node boundaries.
The mechanism is similar to Floating IP, with the difference that Local IP
could be assigned to several fixed IPs (on different nodes) simultaneously and
that all address translation happens early/locally on the node’s integration
bridge.&lt;/p&gt;
&lt;p&gt;The scope of this feature is limited to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;API and CLI to provide fine grained control over allocation and assignment
of the Local IP addresses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Networking data plane mechanism to efficiently redirect traffic to a port
within the same physical node (if present) or to optionally forward it to a
fallback destination&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Local IP will only be accessible within the same L2 segment&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Local IP object will be composed of the following objects &amp;amp; attributes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Underlying Neutron port representing Local IP&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Collection of associated Neutron ports that will serve as packets’
destination when the packet source port is located on the same physical node&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IP mode for local ports:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;‘translate’ (default) - Local IP will behave as DNAT for redirected packets&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘passthrough’ - packets will be redirected without modification to IP
headers; destination VM’s guest OS will be responsible for configuring
Local IP’s IP address on a corresponding port interface. This is similar
to current allowed address pair mechanism with the benefit of fine grained
control over IP allocation and assignment&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fallback policy:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;‘forward’ (default) - to redirect packets to an underlying Neutron port IP
address if no Local IP assigned port is available on the physical node&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘drop’ - packets will be dropped if no Local IP assigned port is available
on the physical node - out of scope for now&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘reject’ - similar to iptables’ ‘reject’ policy to help clients fail fast
if no Local IP assigned port is available on the physical node -
out of scope for now&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;section id="new-local-ip-api-resource"&gt;
&lt;h4&gt;New Local IP API resource&lt;/h4&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the
Local IP object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable name for the Local IP
(255 characters limit). Does not have
to be unique.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable description for the
Local IP (255 characters limit).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of the Local IP.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;local_ip&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Local IP CIDR (virtual) that will be
reachable within the same physical
server/node. Required when provided
local_port_id’s Port has several fixed
IPs&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;local_port_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Underlying (backup) Neutron port ID
used by Local IP object to get actual
IP address for local translation.
If port has several fixed IPs -
local_ip should be provided as well.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;network_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ID of network from which to allocate
Local IPs underlying Neutron port.
Required when no local_port_id
was provided upon creation.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;ip_mode&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;One of ‘translate’ (for DNAT) or
‘passthrough’ (no NAT) modes described
above. Default: ‘translate’&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="new-local-ip-association-api-resource"&gt;
&lt;h4&gt;New Local IP Association API resource&lt;/h4&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;local_ip_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Local IP id&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;fixed_port_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ID of associated Neutron fixed port&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;fixed_ip&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Exact port’s fixed IP address that is
associated with Local IP&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;host&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;List&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Host where associated port is bound&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Basically new API will be similar to existing Floating IP API with some
differences:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Local IP could be associated with multiple fixed ports at the same time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Local IP may be created by providing an existing Neutron port which will
be used to obtain the IP address and may serve as a fallback destination&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creating Local IP without explicitly specified port will trigger creation
of an underlying Neutron port to handle IPAM, network boundaries and
permission checks. In this case network ID should be specified upon
creation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deletion of the Local IP underlying fallback port will be prohibited by
the Neutron server as long as a Local IP associated with such port exists&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manual underlying Neutron port updates will be ignored by parent Local IP
(similar to current Floating IP behavior)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deleting Local IP should be prohibited if Local IP has associated local
ports; ‘force’ option may be provided to trigger local port disassociation
on deletion; deleting Local IP should also delete the underlying Neutron
port representing Local IP if this port was created specifically for
Local IP and did not exist before&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IPAM and IP validation will be handled automatically by underlying Port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Local IP will behave similar to Port and Floating IP API in terms of
user/admin access rights&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Local IP may have quotas similar to Floating IP API (out of scope for now)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;The following are the backend database tables for the REST API proposed above.&lt;/p&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;strong&gt;Local IPs&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id (PK)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the
Local IP object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable name for the Local IP
(255 characters limit). Does not have
to be unique.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of the Local IP. Only admin
users can specify a project identifier
other than their own.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;local_ip&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Local IP CIDR (virtual) that will be
reachable within the same physical
server/node.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;local_port_id (FK)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Underlying (backup) Neutron port ID
used by Local IP object to get actual
IP address for local NATting&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;ip_mode&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;One of ‘translate’ (for DNAT) or
‘passthrough’ (no NAT) modes described
above. Default: ‘translate’&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;strong&gt;Local IP associations&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;local_ip_id (PK)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID of a Local IP&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;fixed_port_id (PK)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID of a port which will serve Local
IP requests on this port’s host&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;fixed_ip&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Exact port’s fixed IP address that is
associated with Local IP&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="client-impact"&gt;
&lt;h3&gt;Client impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New CLI and OpenStack client commands to create, update, delete, list and
show Local IPs and to associate/disassociate fixed IP ports&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="ovs-ml2-drivers-impact"&gt;
&lt;h3&gt;OVS, ML2 Drivers impact&lt;/h3&gt;
&lt;p&gt;RPC interface between server and OVS agent will be updated to include info
about Local IPs associated with agent’s ports. Server will update port_details
with this info.&lt;/p&gt;
&lt;p&gt;OVS agent will perform following flow updates based on Local IPs info:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;update ARP spoofing flow for associated port
(like done for allowed address pairs)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;identify network/local vlan of associated port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;for each port from this network - redirect packets from table 0 or
24(ARP_SPOOF)/25(MAC_SPOOF) to a new table - 50 (LOCAL_EGRESS)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Below flow examples are for the case when fixed port (id=56fbc1e7-2c..,
MAC=fa:16:3e:9a:1a:de, IP=10.0.0.51) is associated with Local IP 10.0.0.10&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_packets&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_bytes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"tap56fbc1e7-2c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;dl_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;resubmit&lt;/span&gt;&lt;span class="p"&gt;(,&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;table 50(LOCAL_EGRESS) serves for memorizing local vlans to later
distinguish Local IP traffic from different nets and redirect packets further
to table 51(LOCAL_IP_HANDLE)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_packets&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_bytes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"tap56fbc1e7-2c"&lt;/span&gt;
&lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mh"&gt;0x4&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NXM_NX_REG6&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="n"&gt;resubmit&lt;/span&gt;&lt;span class="p"&gt;(,&lt;/span&gt;&lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;table 51(LOCAL_IP_HANDLE) has actual flows for Local IP handling&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;ARP responder flow to handle Local IP ARP requests from same subnet ports
(fixed port and local IP associated with it are from the same IP subnet)&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_packets&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_bytes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;arp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg6&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0x4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;arp_tpa&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;10.0.0.10&lt;/span&gt;
&lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mh"&gt;0x2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_ARP_OP&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;NXM_NX_ARP_SHA&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NXM_NX_ARP_THA&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_ARP_SPA&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_ARP_TPA&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mh"&gt;0xfa163e9a1ade&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NXM_NX_ARP_SHA&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mh"&gt;0x1010102&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_ARP_SPA&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_ETH_SRC&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_ETH_DST&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="n"&gt;mod_dl_src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;de&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;IN_PORT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NAT flows to do actual Local IP address translation&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_packets&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_bytes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg6&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0x4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;nw_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;10.0.0.10&lt;/span&gt;
&lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;10.0.0.51&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_packets&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_bytes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="n"&gt;trk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg6&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0x4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;dl_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;de&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;10.0.0.51&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;After translation packets are resubmitted further to TRANSIENT_TABLE (60)&lt;/p&gt;
&lt;p&gt;Alternatively static NAT could be used to avoid kernel conntrack:
learn back flows with 7 tuple (src_mac, dest_mac, src_ip, dest_ip,
protocol, src_protocol_port, dest_protocol_port)&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;tcp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_vlan&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;de&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;dl_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;10.0.0.100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;10.0.0.10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;tp_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0x8000&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mh"&gt;0x8000&lt;/span&gt;
&lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;learn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;idle_timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;hard_timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;eth_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0x800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_proto&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_ETH_SRC&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_ETH_DST&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="n"&gt;NXM_OF_ETH_DST&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_ETH_SRC&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_IP_SRC&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_IP_DST&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="n"&gt;NXM_OF_IP_DST&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_IP_SRC&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_TCP_DST&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_TCP_SRC&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="n"&gt;NXM_OF_TCP_SRC&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_TCP_DST&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_VLAN_TCI&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0..11&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;NXM_NX_REG0&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0..11&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_VLAN_TCI&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0..11&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;NXM_OF_IN_PORT&lt;/span&gt;&lt;span class="p"&gt;[]),&lt;/span&gt;&lt;span class="n"&gt;set_field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;10.0.0.10&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;ip_dst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;goto_table&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This is usable in case of OVS offloading (e.g. SmartNICs).
This will be made configurable on the ovs agent side.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Not matched (not related to Local IP) packets are transmitted further&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_packets&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_bytes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;resubmit&lt;/span&gt;&lt;span class="p"&gt;(,&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Packet processing example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;VM1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mf"&gt;10.0.0.100&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tries&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;access&lt;/span&gt; &lt;span class="n"&gt;Local&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.10&lt;/span&gt;
&lt;span class="n"&gt;Local&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;assigned&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;MAC_2&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;10.0.0.51&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;ARP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;VM1&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ARP&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.10&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mf"&gt;10.0.0.10&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="n"&gt;MAC_2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;Egress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;VM1_MAC_1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.100&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MAC_2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.10&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt; &lt;span class="n"&gt;NAT&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;VM1_MAC_1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.100&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MAC_2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.51&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;Ingress&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;back&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MAC_2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.51&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;VM1_MAC_1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.100&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt; &lt;span class="n"&gt;NAT&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MAC_2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.10&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;VM1_MAC_1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.100&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="scheduling"&gt;
&lt;h3&gt;Scheduling&lt;/h3&gt;
&lt;p&gt;Local IP will have no effect on VM scheduling/placement. Local IP operates
under assumption that at any given time any physical node in the cloud should
have no more than one active port/VM associated with a given Local IP.
Users are responsible to utilize OpenStack placement/scheduling features (e.g.
anti-affinity rules) to avoid assigning multiple ports from the same physical
node the the same Local IP.&lt;/p&gt;
&lt;p&gt;However there might be valid cases when multiple Local IP’s local ports may be
colocated on the same physycal node (e.g. as a result of temporary live
migration during other node’s maintenance). Local IP should provide a
deterministic way of handling such situations (e.g. in case of multiple local
ports, only the oldest port shall be used).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="initial-release-limitations"&gt;
&lt;h3&gt;Initial release limitations&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Only IPv4 will be supported. IPv6 support will be considered in future
releases&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Only ‘openvswitch’ ML2 mechanism driver will support the feature&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Only tunnel (VxLAN, GRE) networks will be supported. ‘vlan’ will be
considered if require minimum overhead&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No deterministic handling of packets if a node contains multiple local ports
from same L2 segment associated with the same Local IP&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;no ‘reject’ and ‘drop’ fallback policies; only ‘forward’ will be supported&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Thu, 24 Jun 2021 00:00:00 </pubDate></item><item><title>Manage default route(s) explicitly</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/xena/explicit-default-routes.html</link><description>

&lt;p&gt;RFE: &lt;a class="reference external" href="https://launchpad.net/bugs/1921126"&gt;https://launchpad.net/bugs/1921126&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes to allow explicit management of the default route(s)
of a Neutron router.  This is mostly useful for a user to install
multiple default routes for Equal Cost Multipath (ECMP) and treat all
these routes uniformly.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Today the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extraroute&lt;/span&gt;&lt;/code&gt; API allows explicit addition of default route(s),
where by default route we mean a route with destination=0.0.0.0/0
and an arbitrary (connected) nexthop.  But the router already has an
implicit default route derived from its external gateway settings (with
its nexthop being the gateway port’s first subnet’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gateway_ip&lt;/span&gt;&lt;/code&gt;).
To the best of my knowledge the interaction of the default routes out of
these two sources is problematic.  For example our api-ref has warnings
about it &lt;a class="footnote-reference brackets" href="#id4" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. Other times people not familiar with these warnings consider
this behavior outright buggy &lt;a class="footnote-reference brackets" href="#id5" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We also already have a spec merged for ECMP &lt;a class="footnote-reference brackets" href="#id6" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. ECMP makes as much
sense for the default route as for any other route.  But today if you
want to manage multiple default route entries in order to have ECMP over
the default route, then you have to manage a mishmash of the implicit
default route and some other default routes via the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extraroute&lt;/span&gt;&lt;/code&gt; API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This spec proposes to separate the implicit management of a router’s
default route from the explicit.  A router either has the one traditional
implicit default route or all of its default route(s) are explicitly
managed via the extraroute API.  But never a mixture of these two.&lt;/p&gt;
&lt;p&gt;We propose to have a new API extension: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default-route-management&lt;/span&gt;&lt;/code&gt;.
Which introduces a new router attribute: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;explicit_default_routes&lt;/span&gt;&lt;/code&gt;.
Which is a boolean and defaults to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;False&lt;/span&gt;&lt;/code&gt;.
It can be set at router create and update.&lt;/p&gt;
&lt;p&gt;When &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;explicit_default_routes&lt;/span&gt;&lt;/code&gt; is set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;False&lt;/span&gt;&lt;/code&gt; (implicit mode) the
default route of a router is derived from its external gateway as before.
This default route is not visible through the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extraroute&lt;/span&gt;&lt;/code&gt; API (again
as before).  For the sake of backward compatibility we should not reject
default routes on the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extraroute&lt;/span&gt;&lt;/code&gt; API.  However we could document
that in implicit mode managing default routes over the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extraroute&lt;/span&gt;&lt;/code&gt;
API is not recommended.&lt;/p&gt;
&lt;p&gt;Updating a router’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;explicit_default_routes&lt;/span&gt;&lt;/code&gt; (in both directions)
is rejected except when a router’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routes&lt;/span&gt;&lt;/code&gt; attribute contains:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;either no default routes,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;or exactly one default route with the same nexthop as in implicit mode.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;explicit_default_routes&lt;/span&gt;&lt;/code&gt; is set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt; (explicit mode)
the Neutron router is not going to have any default routes installed
implicitly. However a router can be updated from implicit to explicit
mode without traffic loss if the one extra route allowed above (that is:
exactly one default route with the same nexthop as in implicit mode) is
present before switching to explicit mode. In this case the default route
is preserved through the update.&lt;/p&gt;
&lt;p&gt;In explicit mode default routes can be managed via the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extraroute&lt;/span&gt;&lt;/code&gt; API.
And they can be managed properly - for example all of the default routes
set are visible via the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;extraroute&lt;/span&gt;&lt;/code&gt; API.&lt;/p&gt;
&lt;section id="db-impact"&gt;
&lt;h3&gt;DB Impact&lt;/h3&gt;
&lt;p&gt;Extend the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routers&lt;/span&gt;&lt;/code&gt; table with boolean column
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;explicit_default_routes&lt;/span&gt;&lt;/code&gt; defaulting to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;False&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;New API extension: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;default-route-management&lt;/span&gt;&lt;/code&gt; introducing new router
attribute: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;explicit_default_routes&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="client-impact"&gt;
&lt;h3&gt;Client Impact&lt;/h3&gt;
&lt;p&gt;Relevant changes in osc and openstacksdk.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests in neutron-tempest-plugin.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Bence Romsics &amp;lt;&lt;a class="reference external" href="mailto:bence.romsics%40gmail.com"&gt;bence&lt;span&gt;.&lt;/span&gt;romsics&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/api-ref/network/v2/#extra-routes-extension"&gt;https://docs.openstack.org/api-ref/network/v2/#extra-routes-extension&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1901992"&gt;https://bugs.launchpad.net/neutron/+bug/1901992&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/wallaby/l3-router-support-ecmp.html"&gt;https://specs.openstack.org/openstack/neutron-specs/specs/wallaby/l3-router-support-ecmp.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 16 Mar 2021 00:00:00 </pubDate></item><item><title>QoS Rule Type Packet per Second</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/xena/qos_pps_rule.html</link><description>

&lt;p&gt;RFE: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1912460"&gt;https://bugs.launchpad.net/neutron/+bug/1912460&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron supports bandwidth rate limit for ports and L3 IPs. But packet
rate limit (packet per second) is not available, although it is a common
measurement.&lt;/p&gt;
&lt;p&gt;So, this spec describes adding a new QoS rule type packet per second (pps).&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Packet per second is a very general network performance metric.
Like bandwidth, it is usually used to evaluate the packet forwarding
performance of a device.&lt;/p&gt;
&lt;p&gt;For cloud providers, to limit the packet per second (pps)
of VM NIC is popular and sometimes essential. Transit large set of
packets for VM in physical compute hosts will consume the
CPU and physical NIC I/O performance. For small packets, even if the
bandwidth is low, the pps can still be higher. Without the limitation,
it can be an attack point inside the cloud while some VMs are becoming
hacked.&lt;/p&gt;
&lt;p&gt;For L2 drivers like ovs and ovn, it may get extremly high usage of
CPU when user send small packet (typically 64B small) from
the VM to the others, even if the device has lower QoS bandwidth limitation.
Then your host services and other users’ VMs will be under a higher
failure point.&lt;/p&gt;
&lt;p&gt;For network quality assurance, the resource consumption of the system
is determined according to the user’s VM specifications. With the pps
limitation, the VM will not consume more CPU with smaller bandwidth.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Adding new API extension to QoS service plugin to allow CURD actions for
packet rate limit (packet per second) rule.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;We will not elaborate the real limitation in L2/L3 backend,
this spec only shows how we add a new QoS rule type.&lt;/p&gt;
&lt;/div&gt;
&lt;section id="server-side-changes"&gt;
&lt;h3&gt;Server side changes&lt;/h3&gt;
&lt;p&gt;A new API extension of Neutron will be added with new resource
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PacketRateLimitRule&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;qos_apidef&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SUB_RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'packet_rate_limit_rules'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'parent'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;qos_apidef&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_PARENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'parameters'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;qos_apidef&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_QOS_RULE_COMMON_FIELDS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'max_kpps'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;converters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_sort_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s1"&gt;'type:range'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DB_INTEGER_MAX_VALUE&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'max_burst_kpps'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'is_sort_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;converters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s1"&gt;'type:range'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DB_INTEGER_MAX_VALUE&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_sort_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EGRESS_DIRECTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;VALID_DIRECTIONS&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The unit for the rate and burst is kilo (1000) packets per second,
so the value range will be 1 kpps to 2147 gpps.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="potential-agent-side-enhancements"&gt;
&lt;h3&gt;Potential agent side enhancements&lt;/h3&gt;
&lt;p&gt;Each of the following will be an independent and huge proposal, we will
not describe the detail here.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;apply pps rule to L3 IPs in agent side by iptables rule &lt;a class="footnote-reference brackets" href="#id5" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;apply pps rule to VM port by ovs meter &lt;a class="footnote-reference brackets" href="#id6" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id7" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id8" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;apply pps rule to router ports (gateway port, router interface) by iptables rule.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;apply pps rule to L3 IPs and ports to OVN related devices by ovs meter.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="user-use-cases"&gt;
&lt;h3&gt;User use cases&lt;/h3&gt;
&lt;p&gt;After the L2/L3 backends have the real abilities to limit the pps,
users can use the pps rule in the following scenarios:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;“pps” rule for floating IP, using the L3 agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“pps” rule for floating IP, using OVN L3 agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“pps” rule for gateway IP, using the L3 agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“pps” rule for gateway IP, using OVN L3 agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“pps” rule for ML2 OVS VM ports&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“pps” rule for ML2 OVN VM ports&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“pps” rule for router gateway or interface ports&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;Add table &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qos_packet_rate_limit_rules&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s1"&gt;'qos_packet_rate_limit_rules'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'qos_policy_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
              &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'max_kpps'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'max_burst_kpps'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Enum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EGRESS_DIRECTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                   &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INGRESS_DIRECTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                   &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"directions"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
              &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;server_default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EGRESS_DIRECTION&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrimaryKeyConstraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKeyConstraint&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'qos_policy_id'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'qos_policies.id'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                            &lt;span class="n"&gt;ondelete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'CASCADE'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Add DB model &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;QosPacketRateLimitRule&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;QosPacketRateLimitRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HasId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model_base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BASEV2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;__tablename__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'qos_packet_rate_limit_rules'&lt;/span&gt;
    &lt;span class="n"&gt;qos_policy_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                              &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'qos_policies.id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                            &lt;span class="n"&gt;ondelete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'CASCADE'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                              &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;max_kpps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;max_burst_kpps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;revises_on_change&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'qos_policy'&lt;/span&gt;&lt;span class="p"&gt;,)&lt;/span&gt;
    &lt;span class="n"&gt;qos_policy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;orm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QosPolicy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;load_on_pending&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Enum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EGRESS_DIRECTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                  &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INGRESS_DIRECTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                  &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"directions"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                          &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EGRESS_DIRECTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="n"&gt;server_default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EGRESS_DIRECTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;__table_args__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UniqueConstraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;qos_policy_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"qos_packet_rate_limit_rules0qos_policy_id0direction"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;model_base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BASEV2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__table_args__&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With OVO object:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nd"&gt;@base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NeutronObjectRegistry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;register&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;QosPacketRateLimitRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QosRule&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;db_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;qos_db_model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QosPacketRateLimitRule&lt;/span&gt;

    &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'max_kpps'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;obj_fields&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntegerField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;'max_burst_kpps'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;obj_fields&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntegerField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;common_types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FlowDirectionEnumField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EGRESS_DIRECTION&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;duplicates_compare_fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;rule_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RULE_TYPE_PACKET_RATE_LIMIT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;GET: List packet rate limit rules for QoS policy&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;/v2.0/qos/policies/{policy_id}/packet_rate_limit_rules&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"packet_rate_limit_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5f126d84-551a-4dcf-bb01-0e9c0df0c793"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"max_kpps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"max_burst_kpps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"egress"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;POST: Create packet rate limit rule&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;/v2.0/qos/policies/{policy_id}/packet_rate_limit_rules&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Request:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"packet_rate_limit_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"max_kpps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10000"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"packet_rate_limit_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5f126d84-551a-4dcf-bb01-0e9c0df0c793"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"max_kpps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"max_burst_kpps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"egress"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;GET: Show packet rate limit rule details&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;/v2.0/qos/policies/{policy_id}/packet_rate_limit_rules/{rule_id}&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"packet_rate_limit_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5f126d84-551a-4dcf-bb01-0e9c0df0c793"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"max_kpps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"max_burst_kpps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"egress"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;PUT:  Update packet rate limit rule&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;/v2.0/qos/policies/{policy_id}/packet_rate_limit_rules/{rule_id}&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Request:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"packet_rate_limit_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"max_kpps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"packet_rate_limit_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5f126d84-551a-4dcf-bb01-0e9c0df0c794"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"max_kpps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10000"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;DELETE: Delete packet rate limit rule&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;/v2.0/qos/policies/{policy_id}/packet_rate_limit_rules/{rule_id}&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And, neutron will allow attaching new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PacketRateLimitRule&lt;/span&gt;&lt;/code&gt; to QoS policy.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="the-neutron-basic-workflow"&gt;
&lt;h3&gt;The Neutron basic workflow&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;User creates QoS policy&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creates packet rate limit rules with multiple directions to this QoS policy&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attaching this QoS policy to a port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(No available) related L2 driver apply PPS limitation driver rule to the port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attaching this QoS policy to a L3 IP (floating IP or gateway IP).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(No available) related L3 driver apply PPS limitation driver rule to the IP&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;LIU Yulong &amp;lt;&lt;a class="reference external" href="mailto:i%40liuyulong.me"&gt;i&lt;span&gt;@&lt;/span&gt;liuyulong&lt;span&gt;.&lt;/span&gt;me&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Adding API extension and DB models for neutron server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit test cases to verify the DB rules are created/updated/deleted.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://linux.die.net/man/8/iptables"&gt;https://linux.die.net/man/8/iptables&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://workshop.netfilter.org/2017/wiki/images/d/db/Nfws-ovs-metering.pdf"&gt;http://workshop.netfilter.org/2017/wiki/images/d/db/Nfws-ovs-metering.pdf&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.openvswitch.org//support/dist-docs/ovs-ofctl.8.txt"&gt;http://www.openvswitch.org//support/dist-docs/ovs-ofctl.8.txt&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openvswitch/ovs/blob/master/NEWS#L312"&gt;https://github.com/openvswitch/ovs/blob/master/NEWS#L312&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Thu, 11 Mar 2021 00:00:00 </pubDate></item><item><title>Allow multiple external gateways on a router</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/xena/multiple-external-gateways.html</link><description>

&lt;p&gt;RFE: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1905295"&gt;https://bugs.launchpad.net/neutron/+bug/1905295&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes to allow a Neutron router to have multiple external
gateways, so we can represent router designs where the router has
multiple legs towards the outside world for reasons of higher capacity
(typically load balanced between these legs) and higher availability
(tolerating the failure of a router uplink or a router gateway port).&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Below we describe one cloud design that required us to allow multiple
external gateways on a single router.  However the feature proposed in
this spec is in no way specific to this design, this spec only strives
to allow multiple external gateways for any design that needs it.&lt;/p&gt;
&lt;p&gt;The Neutron router could be an active-active HA router.  Compute hosts are
connected to the Neutron router via an MLAG, the two sides of the router
present a single IP to the computes.  There is a single logical router
one hop away from the Neutron router towards the external world (from
here on: datacenter gateway) which is also an active-active HA router.
The Neutron router and the datacenter gateway are interconnected by 2x2
point-to-point links (from each side to each side).  The Neutron router
in this setup has 4 links towards the external world.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+--+&lt;/span&gt;   &lt;span class="o"&gt;+--+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;R3&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;R4&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Datacenter&lt;/span&gt; &lt;span class="n"&gt;gateway&lt;/span&gt;
&lt;span class="o"&gt;+--+&lt;/span&gt;   &lt;span class="o"&gt;+--+&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt; \   &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;  \ &lt;span class="o"&gt;/&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;X&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="n"&gt;links&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;/&lt;/span&gt; \  &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;   \ &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--+&lt;/span&gt;   &lt;span class="o"&gt;+--+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;R1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;R2&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Neutron&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt;
&lt;span class="o"&gt;+--+&lt;/span&gt;   &lt;span class="o"&gt;+--+&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt; \   &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;  \ &lt;span class="o"&gt;/&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;X&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;MLAG&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;/&lt;/span&gt; \
 &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;+--+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;C1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;...&lt;/span&gt;  &lt;span class="n"&gt;Compute&lt;/span&gt; &lt;span class="n"&gt;hosts&lt;/span&gt;
&lt;span class="o"&gt;+--+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="overall-picture"&gt;
&lt;h3&gt;Overall Picture&lt;/h3&gt;
&lt;p&gt;The information in an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt; structure is used to
create a gateway port.  A gateway port is a router leg, where beyond
packet forwarding, we perform SNAT (if enabled) and DNAT (for floating
IPs and port forwardings) and which influences the default route of
that router.  Given multiple &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt; structures
we can straightforwardly create multiple gateway ports.  We can also
straightforwardly install the directly connected routes of the additional
external gateways.&lt;/p&gt;
&lt;p&gt;With only one external gateway - regarding packet forwarding - naturally
only the internal-internal and internal-external directions exist.
However with multiple external gateways the external-external direction
also becomes possible. We don’t have a use case for external-external
forwarding. However for the sake of simplicity of implementation this
spec proposes to support that, that is to allow packet forwading from
one external gateway to another.  If required, a follow-up spec may
propose finer control of external-external packet forwarding.&lt;/p&gt;
&lt;p&gt;However the default route of a router cannot be multiplied without
complex consequences (e.g. load balancing between multiple nexthops).
So for the sake of simplicity for each router we retain one external
gateway as special.  The special one is used to set the default route of
a router as before, while the other external gateways have no influence
on the default route.&lt;/p&gt;
&lt;p&gt;NATting and reservation of floating IPs can be performed for each external
gateway as usual, but please see the ‘Out of Scope’ section.&lt;/p&gt;
&lt;p&gt;The first implementation targets centralized routers on l3-agent.&lt;/p&gt;
&lt;p&gt;For the special, first gateway port we keep adding the same routes as before.&lt;/p&gt;
&lt;p&gt;The usual set of implicitly managed routes in a Neutron router are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;One directly connected route for each router interface’s each subnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One directly connected route for each gateway port’s each subnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One default route to the single gateway port’s subnet’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gateway_ip&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Keeping to this logic, when we add further gateway ports, we also add a
directly connected route for each additional gateway port’s each subnet.
Therefore the traffic destined to these subnets will be sent already
via the respective gateway ports.  Also traffic may reach the gateway
ports from outside.  However the majority of traffic will be sent via
the default route.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="out-of-scope"&gt;
&lt;h3&gt;Out of Scope&lt;/h3&gt;
&lt;p&gt;First of all, overall support for active-active HA routers by the l3-agent
is not targeted here.&lt;/p&gt;
&lt;p&gt;We intentionally only add a default route for the first, special gateway
port(‘s subnet’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gateway_ip&lt;/span&gt;&lt;/code&gt;). We do not add default routes for the
other gateway ports(’ subnet’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gateway_ip&lt;/span&gt;&lt;/code&gt;). Further management
of routes (to make the additional external gateways actually used)
is left to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Managing additional routes via the extraroutes API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Future improvements to neutron-dynamic-routing so a Neutron router
can also receive (not just advertise) additional routes. [1]&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since the extraroutes API is already available, we believe that some
use of the multiple external gateways can be realized as soon as this
feature is merged.&lt;/p&gt;
&lt;p&gt;The advertisement of any routes with the newly introduced additional
external gateways as nexthops (for tenant networks or floating IPs)
is also out of scope here.  We believe that advertising such routes via
routing protocols clearly makes sense, however:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This can be covered by a later spec in neutron-dynamic-routing and&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;basic use of the changes proposed here is possible without routing protocols.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="backwards-compatibility"&gt;
&lt;h3&gt;Backwards Compatibility&lt;/h3&gt;
&lt;p&gt;We propose to store and expose the external gateways a bit redundantly
to make backwards compatibility easier.  Where possible (API, DB, RPC)
keep the current scalar external gateway (or gateway port) attribute of
a router as is.  But also add a new router attribute for the plural:
external gateways or gateway ports which contain a list of (not just
the rest but) all such objects.  So the object in the scalar attribute
is present in this list too - preferably as the first element of the list.&lt;/p&gt;
&lt;p&gt;This is just a high level approach that aims to leave all code unchanged
where we only need to keep backwards compatible behavior.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="db-impact"&gt;
&lt;h3&gt;DB Impact&lt;/h3&gt;
&lt;p&gt;The current DB schema contains the router - external gateway relations
somewhat redundantly.&lt;/p&gt;
&lt;p&gt;First in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routerports&lt;/span&gt;&lt;/code&gt; table there is no constraint on the number
of ports with type &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network:router_gateway&lt;/span&gt;&lt;/code&gt; belonging to one router.
Today we only store at most one &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network:router_gateway&lt;/span&gt;&lt;/code&gt; port for each
router, but the DB schema allows more. [2]&lt;/p&gt;
&lt;p&gt;Second the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gw_port_id&lt;/span&gt;&lt;/code&gt; column of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routers&lt;/span&gt;&lt;/code&gt; table is a scalar.
Today it stores the same port uuid as we have in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routerports&lt;/span&gt;&lt;/code&gt;
table. [3]&lt;/p&gt;
&lt;p&gt;We propose:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;To keep the SQL schema as is, but start storing multiple
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network:router_gateway&lt;/span&gt;&lt;/code&gt; ports in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routerports&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To also keep &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routers.gw_port_id&lt;/span&gt;&lt;/code&gt; scalar and there store the one
special, backwards compatible external gateway (so this one is present
both in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routerports&lt;/span&gt;&lt;/code&gt; table and in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routers.gw_port_id&lt;/span&gt;&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To extend the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron.db.models.l3.Router&lt;/span&gt;&lt;/code&gt; class with new attribute
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gw_ports&lt;/span&gt;&lt;/code&gt; that map to all relevant &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network:router_gateway&lt;/span&gt;&lt;/code&gt; ports
stored in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;routerports&lt;/span&gt;&lt;/code&gt; table.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Introduce a new API extension called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;multiple-external-gateways&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This extension adds a new router attribute: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateways&lt;/span&gt;&lt;/code&gt;.
Which is a list of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt; structures, for example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"network_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"external_fixed_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;"ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"subnet_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="s2"&gt;"enable_snat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The first element in the list is special:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;It is always the same as the original &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is the one that sets the default route of the Neutron router.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The order of the the rest of the list is irrelevant and ignored.
Duplicates in the list (that is multiple external gateways with the same
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network_id&lt;/span&gt;&lt;/code&gt;) are not allowed.&lt;/p&gt;
&lt;p&gt;Updating &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt; also updates the first element of
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateways&lt;/span&gt;&lt;/code&gt; and it leaves the rest of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateways&lt;/span&gt;&lt;/code&gt;
unchanged.  Setting &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt; to an empty value also
resets &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateways&lt;/span&gt;&lt;/code&gt; to the empty list.&lt;/p&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateways&lt;/span&gt;&lt;/code&gt; attribute cannot be set in
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/routers&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/routers/{router_id}&lt;/span&gt;&lt;/code&gt; requests,
instead it can be managed via sub-methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/routers/{router_id}/add_external_gateways&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Accepts a list of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt; structures.  Adding an
external gateway to a network that already has one raises an error.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/routers/{router_id}/update_external_gateways&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Accepts a list of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt; structures.  The external
gateways to be updated are identified by the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network_ids&lt;/span&gt;&lt;/code&gt; found
in the PUT request.  The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_fixed_ips&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_snat&lt;/span&gt;&lt;/code&gt;
fields can be updated.  The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network_id&lt;/span&gt;&lt;/code&gt; field cannot be updated.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/routers/{router_id}/remove_external_gateways&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Accepts a list of potentially partial &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt;
structures.  Only the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network_id&lt;/span&gt;&lt;/code&gt; field from
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_gateway_info&lt;/span&gt;&lt;/code&gt; structure is used.  The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_fixed_ips&lt;/span&gt;&lt;/code&gt;
and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_snat&lt;/span&gt;&lt;/code&gt; keys can be present but their values are ignored.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The add/update/remove PUT sub-methods respond with the whole router
object just as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST/PUT/GET&lt;/span&gt; &lt;span class="pre"&gt;/v2.0/routers&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rpc-impact"&gt;
&lt;h3&gt;RPC Impact&lt;/h3&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sync_routers&lt;/span&gt;&lt;/code&gt; message already has a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gw_port&lt;/span&gt;&lt;/code&gt; field.  Extend the
message to also include a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gw_ports&lt;/span&gt;&lt;/code&gt; field containing all gateway ports.
Bump the rpc version of this message.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="upgrade-impact"&gt;
&lt;h3&gt;Upgrade Impact&lt;/h3&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sync_routers&lt;/span&gt;&lt;/code&gt; RPC message will have a new version.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="client-impact"&gt;
&lt;h3&gt;Client Impact&lt;/h3&gt;
&lt;p&gt;Relevant changes in osc and openstacksdk.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fullstack tests for l3-agent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests in neutron-tempest-plugin.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Bence Romsics &amp;lt;&lt;a class="reference external" href="mailto:bence.romsics%40gmail.com"&gt;bence&lt;span&gt;.&lt;/span&gt;romsics&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://review.opendev.org/c/openstack/neutron-specs/+/783791"&gt;https://review.opendev.org/c/openstack/neutron-specs/+/783791&lt;/a&gt;
[2] &lt;a class="reference external" href="https://opendev.org/openstack/neutron/src/commit/b7c4a11158786431c262cfcc2fc4bc46ab6bacd2/neutron/db/models/l3.py#L24"&gt;https://opendev.org/openstack/neutron/src/commit/b7c4a11158786431c262cfcc2fc4bc46ab6bacd2/neutron/db/models/l3.py#L24&lt;/a&gt;
[3] &lt;a class="reference external" href="https://opendev.org/openstack/neutron/src/commit/b7c4a11158786431c262cfcc2fc4bc46ab6bacd2/neutron/db/models/l3.py#L54"&gt;https://opendev.org/openstack/neutron/src/commit/b7c4a11158786431c262cfcc2fc4bc46ab6bacd2/neutron/db/models/l3.py#L54&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 09 Mar 2021 00:00:00 </pubDate></item><item><title>L3 router support ECMP</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/wallaby/l3-router-support-ecmp.html</link><description>

&lt;p&gt;Blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/support-for-ecmp"&gt;https://blueprints.launchpad.net/neutron/+spec/support-for-ecmp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Launchpad Bug:
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1880532"&gt;https://bugs.launchpad.net/neutron/+bug/1880532&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ECMP is a kind of routing technology which allows traffic to reach the
same destination via multiple different links. Neutron does not need to
calculate the equivalent route path, but leave that part of the work to
those applications using ECMP API. Neutron just receives those parameters
and configures routers. Since we have “ip route” command provided by the
iproute2 utility in Linux, Neutron can simply address ECMP by using pyroute2
and adding route entry into Neutron router namespace.&lt;/p&gt;
&lt;p&gt;This feature is currently designed to support Octavia’s multi-active scheme,
allowing LoadBalancer in Octavia to have multiple amphoras at the same time.
By configuring the ECMP route in the router, multiple amphoras can have a
virtual IP at the same time to serve a set of functions that require high
concurrency support.&lt;/p&gt;
&lt;div class="admonition note" id="p2"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Items marked with [&lt;a class="reference internal" href="#p2"&gt;P2&lt;/a&gt;] refer to lower priority features
to be designed / implemented only after initial release.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;[&lt;a class="reference internal" href="#p2"&gt;P2&lt;/a&gt;] Currently the equal cost route is a simple 5 tuple, that means if
we have one &amp;lt;nexthop&amp;gt; unreachable and remove it from ECMP routes, all
connections get redistributed. To avoid this, we intend to use a consistent
hashing instead of the original scheme. This scheme which can support
consistent hashing is based on hmark which was added in iptables-1.4.15 or
later. See the history file of the iptables on &lt;a class="footnote-reference brackets" href="#id5" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Then this spec describes how to implement ECMP in Neutron.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Octavia has proposed an active-active load balancing design on &lt;a class="footnote-reference brackets" href="#id6" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;section id="topology-description"&gt;
&lt;h3&gt;Topology Description&lt;/h3&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                                                     Tenant Backend
                        +----------------+              Network
                        |                |                 +
Internet+--------------&amp;gt;+    router/gw   +-----------------&amp;gt;
                        |                |    ECMP         |
                        +----------------+                 |
                                                           |
Management                                                 |
 Network                                                   |
    +                                                      |
    |                                                      |         +----------+
    |               +-----------------------+              |         |  Tenant  |
    |          +----+                  +---------+         &amp;lt;---------+Service(1)|
    |          |MGMT|  loadbalancer(1) | VIP|Back|         |         |          |
    &amp;lt;----------+ IP |                  |    | IP +---------&amp;gt;         +----------+
    |          +---------------------------------+         |
    |                                          |           |         +----------+
    |                                          |           |         |  Tenant  |
    |                                          |  ICMP     &amp;lt;---------+Service(2)|
    |                                          | DETECT    |         |          |
    |                                          |           |         +----------+
    |                                          |           |
    |               +-----------------------+  v           |         +----------+
    |          +----+                  +---------+         |         |  Tenant  |
    |          |MGMT|  loadbalancer(2) | VIP|Back|         &amp;lt;---------+service(3)|
    &amp;lt;----------+ IP |                  |    | IP +---------&amp;gt;         |          |
    |          +---------------------------------+         |         +----------+
    |                                          |           |
    |                                          |           |
    |         +-------------+                  |           |           ● ● ●
    |         |Octavia Lbaas|                  |           |
    &amp;lt;---------+ Controller  |   ● ● ●          |  ICMP     |
    |         +-------------+                  | DETECT    |         +----------+
    |                                          |           |         |  Tenant  |
    |                                          |           &amp;lt;---------+Service(M)|
    |                                          |           |         |          |
    |               +-----------------------+  v           |         +----------+
    |          +----+                  +---------+         |
    |          |MGMT|   loadbalancer(n)| VIP|Back|         |
    &amp;lt;----------+ IP |                  |    | IP +---------&amp;gt;
    |          +---------------------------------+         |
    +                                                      +
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This program proposed such a scheme:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Multiple load balancing servers in a vip-subnet, sharing one virtual IP
and one or more back end pools to response clients’ request, and each
loadbalancer has its own IP address.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clients send requests to VIP, then the router distributes every single
request to a load balancing server which has the correct VIP configured
on it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, the load balancing server distributes the request to a back end.
The loadbalancers and tenant service vm can be in the same subnet or
different networks.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In such a situation, Octavia needs the router to support ECMP for distributing
requests. So Octavia can send a request to Neutron for creating an ECMP route,
then Neutron L3 agent executes command in the Neutron router’s namespace to
create an ECMP entry in it, using VIP as the destination IP of the route’s
entry, and several load balancers’ IP as nexthop IP. So those requests having
VIP as their destinations can be distributed to each loadbalancer.&lt;/p&gt;
&lt;p&gt;The whole process implements two levels of load balancing, i.e. load balancing
between multiple loadbalancers and load balancing between the backend
real servers&lt;/p&gt;
&lt;p&gt;[&lt;a class="reference internal" href="#p2"&gt;P2&lt;/a&gt;] Based on current public cloud operator implementations in production
environments, tenants usually only see IPs in the same network, so
considering the same broadcast domain, the router needs to enable proxy
ARP on the corresponding interface.(Users need to disable the proxy ARP
capability of vms in nexthops by themselves)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="user-workflow"&gt;
&lt;h3&gt;User Workflow&lt;/h3&gt;
&lt;p&gt;Generally, users can use the ECMP function for their own purposes.
For putting an ECMP entry into the router namespace,
user can set routes with same destination by using command:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;route&lt;/span&gt; \
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt; &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;20.0.20.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;gateway&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;12.0.0.11&lt;/span&gt; \
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt; &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;20.0.20.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;gateway&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;12.0.0.12&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ecmp&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And withdraw the ECMP entry with:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;route&lt;/span&gt; \
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt; &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;20.0.20.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;gateway&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;12.0.0.11&lt;/span&gt; \
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt; &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;20.0.20.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;gateway&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;12.0.0.12&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ecmp&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For more information about router related OSC, please read &lt;a class="footnote-reference brackets" href="#id7" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;An integrated sequence diagram of the Octavia’s use case is here:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+------+&lt;/span&gt;      &lt;span class="o"&gt;+--------+&lt;/span&gt;     &lt;span class="o"&gt;+-------+&lt;/span&gt;   &lt;span class="o"&gt;+--------+&lt;/span&gt; &lt;span class="o"&gt;+-------+&lt;/span&gt; &lt;span class="o"&gt;+------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Octavia&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;LB&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;qrouter&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------+&lt;/span&gt;      &lt;span class="o"&gt;+---+----+&lt;/span&gt;     &lt;span class="o"&gt;+---+---+&lt;/span&gt;   &lt;span class="o"&gt;+---+----+&lt;/span&gt; &lt;span class="o"&gt;+---+---+&lt;/span&gt; &lt;span class="o"&gt;+------+-----+&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;LB&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;+-------------&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;ecmp&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;        &lt;span class="o"&gt;+--------------&amp;gt;&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;LB&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;boot&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;+--------------+----------&amp;gt;+&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="n"&gt;ecmp&lt;/span&gt; &lt;span class="n"&gt;route&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ecmp&lt;/span&gt; &lt;span class="n"&gt;done&lt;/span&gt;    &lt;span class="o"&gt;+-----------+---------&amp;gt;+&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;+&amp;lt;-------------|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;LB&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;boot&lt;/span&gt; &lt;span class="n"&gt;done&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;LB&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="o"&gt;+&amp;lt;-------------+-----------+&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;+&amp;lt;--------------+&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;sending&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;+----------------------------------------------------&amp;gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;pick&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;LB&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;+&amp;lt;---------|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;pick&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;+----------------------&amp;gt;+&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;+&amp;lt;----------------------+&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;response&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;+&amp;lt;-----------------------------------------+&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;v&lt;/span&gt;               &lt;span class="n"&gt;v&lt;/span&gt;              &lt;span class="o"&gt;+&lt;/span&gt;           &lt;span class="n"&gt;v&lt;/span&gt;          &lt;span class="n"&gt;v&lt;/span&gt;            &lt;span class="n"&gt;v&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Suppose a user has a set of services that require a multi-active
load-balancing scheme, so the user send a request to Octavia to create a
loadbalancer, specifying topology as multi-active. And post a vip-subnet
to Octavia to assign an IP or directly post a virtual port, which is
defined by Octavia, and then users need to submit parameters such as
pool, member, listener, etc., but the latter are irrelevant to Neutron,
you can find them in Octavia document.&lt;/p&gt;
&lt;p&gt;While Octavia is creating a loadbalancer, it will also send an &lt;cite&gt;update_router&lt;/cite&gt;
request or an &lt;cite&gt;add_extraroutes&lt;/cite&gt; request to Neutron, post severval &lt;cite&gt;routes&lt;/cite&gt;
entries with same &lt;cite&gt;destination&lt;/cite&gt; param, and load balancers’ IPs as
&lt;cite&gt;nexthop&lt;/cite&gt; param.&lt;/p&gt;
&lt;p&gt;Neutron receives the request from Octavia, determines whether to add an ECMP
route by calculating whether there are multiple routes with the same
destination address, making sure the router will distribute those packets
with vip as their destination.&lt;/p&gt;
&lt;p&gt;Those ECMP routes will be removed when user drops the multi-active
loadbalancer, and it could be modified when adding or removing a load balancing
node.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-flow"&gt;
&lt;h3&gt;Data flow&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[&lt;a class="reference internal" href="#p2"&gt;P2&lt;/a&gt;] (If on a same network, use ARP proxy) A client requests mac
address of the VIP and accesses the service based on this mac address.
the router will use gateway MAC address to respond.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The client’s datagram will be transmitted to the router first.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The router gateway checks ECMP routing entries then forwards the
client’s packets to the load balancers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Load balancer accepts connections from clients, receives traffic, then
distributes it to the back-end server pool.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The reply traffic from the back-end server pool go through load balancers
and then comes to the router (directly comes back to intranet clients if on
a same network), these packets are eventually forwarded back by the router.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="overview"&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
&lt;section id="in-server-side"&gt;
&lt;h4&gt;In Server Side&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;There are no changes that have to be made in server side.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="in-agent-side"&gt;
&lt;h4&gt;In Agent Side&lt;/h4&gt;
&lt;p&gt;Modify the logic of processing router_update event in L3 agent to
support adding ECMP routes in routers.
The &lt;cite&gt;routes_updated&lt;/cite&gt; function in RouterInfo will behave as below:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;When more than one route is found to have the same destination, L3
agent should execute a pyroute2 code, which looks like&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'replace'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'&amp;lt;destination_ip&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;multipath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;"gateway"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="s2"&gt;"&amp;lt;nexthop1&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;},{&lt;/span&gt;&lt;span class="s2"&gt;"gateway"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;nexthop2&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;}])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Then there will be an ip route entry in the namespace, which looks like&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;vip&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;proto&lt;/span&gt; &lt;span class="n"&gt;static&lt;/span&gt;
    &lt;span class="n"&gt;nexthop&lt;/span&gt; &lt;span class="n"&gt;via&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;nexthop_ip1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;xxxxxxxx&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;nn&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;nexthop&lt;/span&gt; &lt;span class="n"&gt;via&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;nexthop_ip2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;xxxxxxxx&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;nn&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Then router will randomly pick a &amp;lt;nexthop_ip&amp;gt; and fill its mac address into
the package’s dst_mac address when it wants to get to the &amp;lt;destination_ip&amp;gt;.&lt;/p&gt;
&lt;p&gt;[&lt;a class="reference internal" href="#p2"&gt;p2&lt;/a&gt;]For keeping connection while removing a load balancing node, use
iptables instead of simply a ip route entry.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Use &lt;cite&gt;HMARK&lt;/cite&gt; to mark flows in mangle table, the &lt;cite&gt;fwmark&lt;/cite&gt; values
determined by the source address.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Distribute flows to different tables by &lt;cite&gt;fwmark&lt;/cite&gt; values.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is a mapping between the &lt;cite&gt;fwmark&lt;/cite&gt; values and the table values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For each table, give it a default nexthop ip.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify the mapping between &lt;cite&gt;fwmark&lt;/cite&gt; values and table values
when a &lt;cite&gt;nexthop&lt;/cite&gt; is unreachable.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;[&lt;a class="reference internal" href="#p2"&gt;p2&lt;/a&gt;]In order to let traffic from the same network to pass through the
router, L3 agent will also let router to use Proxy ARP by setting command:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;sysctl&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ipv4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="o"&gt;.&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;NIC_1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;proxy_arp_pvlan&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;NIC_1&amp;gt; is the name of the router interface to which the destination
subnet is connected. For example, router &lt;cite&gt;R1&lt;/cite&gt; is connected to a
subnet &lt;cite&gt;sub-1&lt;/cite&gt; whose cidr is &lt;cite&gt;10.10.10.0/24&lt;/cite&gt;, so there will be a
virtual network interface device &lt;cite&gt;qr-abcdefgh&lt;/cite&gt; in the router related
namespace as the gateway for the subnet &lt;cite&gt;sub-1&lt;/cite&gt;, then add an
ECMP route with a destination like &lt;cite&gt;10.10.10.5/32&lt;/cite&gt; which is in the
scope of the subnet &lt;cite&gt;sub-1&lt;/cite&gt;, at this point, the above command
will be executed and &amp;lt;NIC_1&amp;gt; will be &lt;cite&gt;qr-abcdefgh&lt;/cite&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For making the ARP proxy optional, add an config option in L3Agent.ini:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ECMP&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;router_interface_arp_proxy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Following REST APIs wil be affected:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;routers&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;add_extraroutes&lt;/span&gt;

&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;routers&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;remove_extraroutes&lt;/span&gt;

&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;routers&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The above three APIs are the current methods used to add/remove custom
routes. See the usage of &lt;cite&gt;extraroutes&lt;/cite&gt; on &lt;a class="footnote-reference brackets" href="#id8" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. (The third API
&lt;cite&gt;PUT /v2.0/routers/&amp;lt;router_id&amp;gt;&lt;/cite&gt; is not recommended for adding routes)&lt;/p&gt;
&lt;p&gt;Before the ECMP routing Implementation, when L3 agent receive several route
entries with same destination and different nexthops, it will only keep one
entry of them, or replace the existing route with a new one. But now after
these changes, there will be an ECMP route in the router. So you can add an
ECMP route entry like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;routers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;add_extraroutes&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"router"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"routes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"192.168.1.6/32"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"nexthop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"192.168.1.88"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"192.168.1.6/32"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"nexthop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"192.168.1.99"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Then you can find the ECMP route in router related namespace:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;#ip route&lt;/span&gt;

&lt;span class="mf"&gt;192.168.1.6&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt; &lt;span class="n"&gt;proto&lt;/span&gt; &lt;span class="n"&gt;static&lt;/span&gt;
  &lt;span class="n"&gt;nexthop&lt;/span&gt; &lt;span class="n"&gt;via&lt;/span&gt; &lt;span class="mf"&gt;192.168.1.88&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;adb238b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="n"&gt;nexthop&lt;/span&gt; &lt;span class="n"&gt;via&lt;/span&gt; &lt;span class="mf"&gt;192.168.1.99&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;adb238b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To make this behavior change discoverable, a shim extension called
‘ecmp_routes’ will be added.
[&lt;a class="reference internal" href="#p2"&gt;p2&lt;/a&gt;]To make ARP proxy behavior discoverable, a shim extension called
‘ecmp_arp’ will be added, it will be removed dynamically when related option
&lt;cite&gt;router_interface_arp_proxy&lt;/cite&gt; in config file is &lt;cite&gt;False&lt;/cite&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;XiaoYu Zhu&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;L3 Agent Update&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Tempest tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New tests need to be written&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;User documentation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API reference&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Needs devref documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://netfilter.org/projects/iptables/files/changes-iptables-1.4.15.txt"&gt;http://netfilter.org/projects/iptables/files/changes-iptables-1.4.15.txt&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/723864"&gt;https://review.opendev.org/723864&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/python-openstackclient/latest/cli/command-objects/router.html"&gt;https://docs.openstack.org/python-openstackclient/latest/cli/command-objects/router.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/train/improve-extraroute-api.html"&gt;https://specs.openstack.org/openstack/neutron-specs/specs/train/improve-extraroute-api.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Thu, 21 Jan 2021 00:00:00 </pubDate></item><item><title>L3 router support NDP proxy</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/xena/l3-router-support-ndp-proxy.html</link><description>

&lt;p&gt;Launchpad Bug:
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1877301"&gt;https://bugs.launchpad.net/neutron/+bug/1877301&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The IPv6’s NDP (Neighbor Discovery Protocol) is similar to IPv4’s ARP (Address
Resolution Protocol) in functional, but the NDP works at L3. The NDP proxy &lt;a class="footnote-reference brackets" href="#id12" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;
is also similar to ARP proxy &lt;a class="footnote-reference brackets" href="#id13" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. But, the NDP proxy only works on IPv6, it can
proxy specific IPv6 address’s NA (Neighbor Advertisement) that to response the
NS (Neighbor Solicitation) which comes from the upstream router. The Linux
kernel already implement NDP proxy. With these functionalities, we can
implement some APIs so that users/tenants can advertise specific IPv6
addresses. It looks a little like IPv4’s floating IP, but this solution doesn’t
do any NAT action.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;As the IPv6 more and more popularize, we should provide a simple method to make
the IPv6 VMs more easily and flexibly connect to external network.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In some use cases, such as a web site which has some DB services, MQ services
and portal services etc, and they work on IPv6 VMs with same subnet. The
administrator of the web site just would like to publish portal services to
external. So the administrator needs some methods to just advertise a part of
address to external.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The current solution of publishing IPv6 address which the Neutron support,
such as BGP (Border Gateway Protocol) &lt;a class="footnote-reference brackets" href="#id14" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, PD (Prefix delegation) &lt;a class="footnote-reference brackets" href="#id15" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, is
more complex, they require do some complex configurations in upstream router.
This maybe not suit some company as their bare metal hosted in thrid-party
IDC, they don’t have the privilege of the upstream router. So we should
provide a solution with not depth cooperation of upstream router.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="overview"&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
&lt;section id="server-side"&gt;
&lt;h4&gt;Server Side&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement a service plugin named &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ndp_proxy&lt;/span&gt;&lt;/code&gt; to support the feature of this
spec description. Administrator can enable the feature by append the plugin
to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;service_plugin&lt;/span&gt;&lt;/code&gt; in Neutron configuration file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement an API extension, In the extension we should define a named
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ndp_proxy&lt;/span&gt;&lt;/code&gt; resource and its APIs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new parameter &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_ndp_proxy&lt;/span&gt;&lt;/code&gt; to router. If it is set to True, the
ndp proxy will be enabled in router namespace.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="agent-side"&gt;
&lt;h4&gt;Agent Side&lt;/h4&gt;
&lt;p&gt;Implement an extension of Neutron L3 agent to set relational rules for ndp
proxy. The extension behavior like below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If the router’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_ndp_proxy&lt;/span&gt;&lt;/code&gt; field is true, the router’s namespace
should have a default ip6tables rule to drop all packets input from the
router’s external gateway device. By this way, we can eliminate affection of
extra route and neighbor in upstream router. So, if a router’s
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_ndp_proxy&lt;/span&gt;&lt;/code&gt; set as True, the Prefix Delegation &lt;a class="footnote-reference brackets" href="#id15" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and BGP Dynamic
Routing &lt;a class="footnote-reference brackets" href="#id14" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; solution will have no effect, we should explain this in user
document.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;If a router’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_ndp_proxy&lt;/span&gt;&lt;/code&gt; set as false when the router
have ndp proxies, these ndp proxes will have no effect, the Prefix
Delegation &lt;a class="footnote-reference brackets" href="#id15" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and BGP Dynamic Routing &lt;a class="footnote-reference brackets" href="#id14" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; solution will recover.
In particular, the DVR router will ignore &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_ndp_proxy&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For each ndp proxy object, the extension should set a neighbor proxy entry
at the router’s external gateway device and set an ip6tables rule to permit
the relational packets through. By this, the router only permits those IPv6
addresses which enabled the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ndp_proxy&lt;/span&gt;&lt;/code&gt; to communication with external
network. This makes the ndp proxy’s behavior is more similar to IPv4’s
floating ip.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;The following new tables are added as part of the ndp proxy feature.&lt;/p&gt;
&lt;p&gt;For ndp proxy resource:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;ndp_proxies&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="n"&gt;CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt; &lt;span class="n"&gt;PRI&lt;/span&gt; &lt;span class="n"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;router_id&lt;/span&gt; &lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt; &lt;span class="n"&gt;FOREIGN&lt;/span&gt; &lt;span class="n"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;port_id&lt;/span&gt; &lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt; &lt;span class="n"&gt;FOREIGN&lt;/span&gt; &lt;span class="n"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ip_address&lt;/span&gt; &lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;project_id&lt;/span&gt; &lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;standard_attr_id&lt;/span&gt; &lt;span class="n"&gt;bigint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;router_id&lt;/span&gt;&lt;/code&gt; column will store the id of router which the ndp proxy belong
to. The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port_id&lt;/span&gt;&lt;/code&gt; column will store the id of Neutron internal port which the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ip_address&lt;/span&gt;&lt;/code&gt; locate in. The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ip_address&lt;/span&gt;&lt;/code&gt; column will store the IPv6 address
which we need to proxy.&lt;/p&gt;
&lt;p&gt;For router’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_ndp_proxy&lt;/span&gt;&lt;/code&gt; parameter:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;router_ndp_proxy_state&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;router_id&lt;/span&gt; &lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt; &lt;span class="n"&gt;FOREIGN&lt;/span&gt; &lt;span class="n"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;enable_ndp_proxy&lt;/span&gt; &lt;span class="n"&gt;BOOL&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="new-resource-extension"&gt;
&lt;h3&gt;New Resource Extension&lt;/h3&gt;
&lt;p&gt;New resource extension &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ndp_proxy&lt;/span&gt;&lt;/code&gt; will be added. It will define the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ndp_proxy&lt;/span&gt;&lt;/code&gt; entry’s CURD APIs.&lt;/p&gt;
&lt;p&gt;For this new feature, a new service plugin will be introduced, and the
following methods will be added:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;‘create_ndp_proxy()’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘delete_ndp_proxy()’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘update_ndp_proxy()’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘get_ndp_proxy()’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘get_ndp_proxies()’&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So the attributes map of new resource would be like:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'ndp_proxy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                 &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'is_sort_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'project_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                       &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'router_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'port_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'ip_address'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                           &lt;span class="s1"&gt;'type:ip_address_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                       &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ip_address&lt;/span&gt;&lt;/code&gt; parameter is optional, if not set it when user
send post request, the new service plugin will select a IPv6 address
from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port_id&lt;/span&gt;&lt;/code&gt; represented port.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;section id="extend-router-api"&gt;
&lt;h4&gt;Extend router API&lt;/h4&gt;
&lt;p&gt;The idea is to extend the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;router&lt;/span&gt;&lt;/code&gt; Rest API with a new extension
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;router_ndp_proxy&lt;/span&gt;&lt;/code&gt; with the below defined attribute.&lt;/p&gt;
&lt;table class="docutils align-default" id="id18"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;Router extension&lt;/span&gt;&lt;/caption&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Attribute Name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Default Value&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;enable_ndp_proxy&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Boolean&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;False&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Whether the router enable ndp proxy function.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;router&lt;/span&gt;&lt;/code&gt; extension definition would be expanded as :&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="s1"&gt;'routers'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s1"&gt;'enable_ndp_proxy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;converters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_boolean_if_not_none&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Default, only admin user can update &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_ndp_proxy&lt;/span&gt;&lt;/code&gt; parameter. And, a new
config option &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_ndp_proxy_by_default&lt;/span&gt;&lt;/code&gt; will be introduced. If it set as
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt;, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_ndp_proxy&lt;/span&gt;&lt;/code&gt; will be set as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt; default.&lt;/p&gt;
&lt;p&gt;For example, GET a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;router&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;GET /v2.0/routers/&amp;lt;router-uuid&amp;gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"router"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"admin_state_up"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"availability_zone_hints"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
        &lt;span class="s2"&gt;"availability_zones"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"nova"&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2018-03-19T19:17:04Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"distributed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"enable_ndp_proxy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"external_gateway_info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"enable_snat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"external_fixed_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"172.24.4.6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"subnet_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"b930d7f6-ceb7-40a0-8b81-a425dd994ccf"&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001:db8::9"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"subnet_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"0c56df5d-ace5-46c8-8f4c-45fa4e334d18"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s2"&gt;"network_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ae34051f-aa6c-4c75-abf5-50dc9ac99ef3"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"flavor_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"f7b14d9a-b0dc-4fbe-bb14-a0f4970a69e0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ha"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"f8a44de0-fc8e-45df-93c7-f79bf3b01c95"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"router1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"revision_number"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"routes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"179.24.1.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"nexthop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"172.24.3.99"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2018-03-19T19:17:22Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"0bd18306d801447bb457a46252d82d13"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"0bd18306d801447bb457a46252d82d13"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"service_type_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"tag1,tag2"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"conntrack_helpers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Set a router’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_ndp_proxy&lt;/span&gt;&lt;/code&gt; parameter to True:&lt;/p&gt;
&lt;p&gt;Post /v2.0/routers/&amp;lt;router-uuid&amp;gt;&lt;/p&gt;
&lt;p&gt;Request body:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"router"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"enable_ndp_proxy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For the new resource &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ndp_proxy&lt;/span&gt;&lt;/code&gt;, some new URLs will be introduced:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="list-ndp-proxies"&gt;
&lt;h4&gt;List NDP Proxies&lt;/h4&gt;
&lt;p&gt;GET /v2.0/ndp_proxies&lt;/p&gt;
&lt;p&gt;The response body:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"ndp_proxies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ad239fa5-ceb7-8b81-abf5-b930d7f6ceb7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ae34051f-aa6c-4c75-abf5-50dc9ac99ef3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"test01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"port_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"fa450s1f-aa6c-4c75-abf5-50dc9ac9df67"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001:217::19"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2020-05-21T11:33:21Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2020-06-18T08:31:48Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
         &lt;span class="p"&gt;},&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ad239fa5-ceb7-8b81-abf5-b930d7f6ceb7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"915a14a6-867b-4af7-83d1-70efceb146f9"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"test02"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"port_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"4323401f-aa6c-4c75-abf5-50dc9ac99ef3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001:218::12"&lt;/span&gt;
             &lt;span class="s2"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2020-05-21T11:33:21Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2020-06-18T08:31:48Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="show-ndp-proxy"&gt;
&lt;h4&gt;Show NDP Proxy&lt;/h4&gt;
&lt;p&gt;GET /v2.0/ndp_proxies/&amp;lt;ndp-proxy-id&amp;gt;&lt;/p&gt;
&lt;p&gt;The response body:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"ndp_proxy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ad239fa5-ceb7-8b81-abf5-b930d7f6ceb7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ae34051f-aa6c-4c75-abf5-50dc9ac99ef3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"test01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"port_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"b930d7f6-ceb7-40a0-8b81-a425dd994ccf"&lt;/span&gt;
         &lt;span class="s2"&gt;"ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001:217::19"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2020-05-21T11:33:21Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2020-06-18T08:31:48Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Some descriptions"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="create-ndp-proxy"&gt;
&lt;h4&gt;Create NDP Proxy&lt;/h4&gt;
&lt;p&gt;POST /v2.0/ndp_proxies&lt;/p&gt;
&lt;p&gt;The request body:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"ndp_proxy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"test01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"router_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5823deb7-8b81-ceb7-40a0-b930d7f6ceb7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"port_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"b930d7f6-ceb7-40a0-8b81-a425dd994ccf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001:217::19"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Some descriptions"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;There are some constraints here:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The router’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_ndp_proxy&lt;/span&gt;&lt;/code&gt; parameter must be set as True.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The subnet that the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ip_address&lt;/span&gt;&lt;/code&gt; allocated from must be added to the
router.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The network of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port_id&lt;/span&gt;&lt;/code&gt; represented port belong to must have same
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ipv6_address_scope&lt;/span&gt;&lt;/code&gt; &lt;a class="footnote-reference brackets" href="#id16" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; with the network of router’s external gateway.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The response body:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"ndp_proxy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ad239fv5-aa6c-4c75-abf5-50dc9ac99ef3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"test01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ad239fa5-ceb7-8b81-abf5-b930d7f6ceb7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"router_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5823deb7-8b81-ceb7-40a0-b930d7f6ceb7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"port_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"b930d7f6-ceb7-40a0-8b81-a425dd994ccf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001:217::19"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2020-05-21T11:33:21Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2020-06-18T08:31:48Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Some descriptions"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="update-ndp-proxy"&gt;
&lt;h4&gt;Update NDP Proxy&lt;/h4&gt;
&lt;p&gt;PUT /v2.0/ndp_proxies/&amp;lt;ndp-proxy-id&amp;gt;&lt;/p&gt;
&lt;p&gt;The request body:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"ndp_proxy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"test02"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"New descriptions"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The response body:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"ndp_proxy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ad239fv5-aa6c-4c75-abf5-50dc9ac99ef3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"test02"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ad239fa5-ceb7-8b81-abf5-b930d7f6ceb7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"router_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5823deb7-8b81-ceb7-40a0-b930d7f6ceb7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"port_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"b930d7f6-ceb7-40a0-8b81-a425dd994ccf"&lt;/span&gt;
         &lt;span class="s2"&gt;"ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001:217::56"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2020-05-21T11:33:21Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2020-06-18T08:31:48Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"New descriptions"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="delete-ndp-proxy"&gt;
&lt;h4&gt;Delete NDP proxy&lt;/h4&gt;
&lt;p&gt;DELETE /v2.0/ndp_proxies/&amp;lt;ndp-proxy-id&amp;gt;&lt;/p&gt;
&lt;p&gt;This operation does not accept a request body and does not return a response
body.&lt;/p&gt;
&lt;p&gt;Addtionally, if a router or port will be deleted, the ndp proxies which
relational with them will be delete cascade.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="effects-on-existing-router-apis"&gt;
&lt;h4&gt;Effects on Existing Router APIs&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Before remove the subnet from a router, neutron should check whether has any
ndp proxy related to the subnet (whether the ndp proxy’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ip_address&lt;/span&gt;&lt;/code&gt; was
allocated from the subnet). If has any ndp proxy related to the subnet, the
subnet can’t be removed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="l3-agent-impact"&gt;
&lt;h3&gt;L3 Agent Impact&lt;/h3&gt;
&lt;p&gt;Neutron needs to implement a new l3 agent extension to cooperate with the
server API to set relational rules (neigh proxy and ip6tables, distributed
router needs to set some extra route rules) in router’s namespace.&lt;/p&gt;
&lt;p&gt;We assume user has a below scenario, then respectively describe the
implementions of the feature about DVR router and Legacy router:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A subnet of which cidr is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;2001::1:0/112&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A VM belong to the subnet and it’s IPv6 address is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;2001::1:8&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A distributed/legacy router which set external gateway and connect to the
subnet.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="legacy-router-impact"&gt;
&lt;span id="id10"/&gt;&lt;h4&gt;Legacy router Impact&lt;/h4&gt;
&lt;p&gt;Assume the router’s external gateway device is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qg-733bd76b-62&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If the router’s parameter &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_ndp_proxy&lt;/span&gt;&lt;/code&gt; is true, the extension need to
set the kernel parameter &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;proxy_ndp&lt;/span&gt;&lt;/code&gt; as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;1&lt;/span&gt;&lt;/code&gt; in the router’s
qrouter-namespace, create a custom chain named &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron-l3-agent-NDP&lt;/span&gt;&lt;/code&gt; and
set a default iptables rule in it to drop all packets input from the router’s
external gateway device. The executed commands like below:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;sysctl&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ipv6&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;qg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;733&lt;/span&gt;&lt;span class="n"&gt;bd76b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;62.&lt;/span&gt;&lt;span class="n"&gt;proxy_ndp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;ip6tables&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt; &lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;NDP&lt;/span&gt;
&lt;span class="n"&gt;ip6tables&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;NDP&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;qg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;733&lt;/span&gt;&lt;span class="n"&gt;bd76b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;62&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="n"&gt;DROP&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;If the router have no external gateway, the parameter
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_ndp_proxy&lt;/span&gt;&lt;/code&gt; will be ignored.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When add the IPv6 subnet to the router (the router’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_ndp_proxy&lt;/span&gt;&lt;/code&gt;
already set as true), Before user advertise the subnet’s address with ndp
proxy, the subnet should drop all external traffic. So, the following cmd
should be executed:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;ip6tables&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt; &lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;FORWARD&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;qg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;733&lt;/span&gt;&lt;span class="n"&gt;bd76b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;62&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt; &lt;span class="mi"&gt;2001&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;112&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;NDP&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;By this, we can eliminate the effect of extra route and neighbor entries in
upstream router.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For each ndp proxies, the extension should add a neigh proxy entry to the
router external gateway device, and add ip6tables rule to permit the
relational packets pass. The executed commands like below:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="n"&gt;neigh&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt; &lt;span class="mi"&gt;2001&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;qg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;733&lt;/span&gt;&lt;span class="n"&gt;bd76b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;62&lt;/span&gt;
&lt;span class="n"&gt;ip6tables&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt; &lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;NDP&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;qg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;733&lt;/span&gt;&lt;span class="n"&gt;bd76b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;62&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt; &lt;span class="mi"&gt;2001&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="n"&gt;ACCEPT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When remove a ndp proxy, the extension should remove related neigh proxy
entry from the router external gateway device, and remove the related
ip6tables rule to re-forbid relational packets pass. The executed commands
like below:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="n"&gt;neigh&lt;/span&gt; &lt;span class="k"&gt;del&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt; &lt;span class="mi"&gt;2001&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;qg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;733&lt;/span&gt;&lt;span class="n"&gt;bd76b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;62&lt;/span&gt;
&lt;span class="n"&gt;ip6tables&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;D&lt;/span&gt; &lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;NDP&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;qg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;733&lt;/span&gt;&lt;span class="n"&gt;bd76b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;62&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt; &lt;span class="mi"&gt;2001&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When router’s parameter &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_ndp_proxy&lt;/span&gt;&lt;/code&gt; set to false, the extension
needs to set the kernel parameter &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;proxy_ndp&lt;/span&gt;&lt;/code&gt; as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;0&lt;/span&gt;&lt;/code&gt; in the router’s
qrouter-namespace namespace, delete the custom chain named
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron-l3-agent-NDP&lt;/span&gt;&lt;/code&gt;. The executed commands like below:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;sysctl&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ipv6&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;qg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;733&lt;/span&gt;&lt;span class="n"&gt;bd76b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;62.&lt;/span&gt;&lt;span class="n"&gt;proxy_ndp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;ip6tables&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;NDP&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="ha-router-impact"&gt;
&lt;h4&gt;HA router Impact&lt;/h4&gt;
&lt;p&gt;The implementation of the feature for HA router is same as Legacy router,
except failover. When HA router’s state has changed, the extension should
refresh the ndp proxy rules, because the ndp proxy rules may be lost after
multible failover.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;When HA router’s state has changed, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;keepalived&lt;/span&gt;&lt;/code&gt; will sends
unsolicited neighbor advertisement automatically. So, we don’t need
to write extra code to do this. During failover, the traffic will be
breaked, but it will recover soon if the failover accomplished.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="dvr-router-impact"&gt;
&lt;h4&gt;DVR Router Impact&lt;/h4&gt;
&lt;p&gt;For DVR &lt;a class="footnote-reference brackets" href="#id17" id="id11" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; router, it’s a little different from legacy and HA router. We need
to consider two scenes: If the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron-l3-agent&lt;/span&gt;&lt;/code&gt; in compute node set as
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dvr&lt;/span&gt;&lt;/code&gt; mode, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron-l3-agent&lt;/span&gt;&lt;/code&gt; will create a fip-namespace to process
north-south traffic, so we need to apply related rules in qrouter-namespace and
fip-namespace. If the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron-l3-agent&lt;/span&gt;&lt;/code&gt; in compute node set as
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dvr_no_external&lt;/span&gt;&lt;/code&gt; mode, the north-south traffic will be processed by
snat-namespace in network node, so we need to apply related rules in
qrouter-namespace and snat-namespace.&lt;/p&gt;
&lt;section id="for-dvr-mode"&gt;
&lt;h5&gt;For dvr mode&lt;/h5&gt;
&lt;p&gt;Assume the fip-namespace’s fg-dev port is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;fg-84920cf6-5e&lt;/span&gt;&lt;/code&gt;; the port connect
fip-namespace to qrouter-namespace is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;fpr-ea902fe0-9&lt;/span&gt;&lt;/code&gt; and it’s IPv6
address is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;fe80::8493:5bff:fe9b:8d93&lt;/span&gt;&lt;/code&gt;; the port connect qrouter-namespace
to fip-namespace is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rfp-ea902fe0-9&lt;/span&gt;&lt;/code&gt; and it’s IPv6 address is
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;fe80::a0a7:c5ff:fe2c:bade&lt;/span&gt;&lt;/code&gt;. The topology like below:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;      &lt;span class="o"&gt;+---------------+&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;upstream&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;+-------+-------+&lt;/span&gt;
              &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;compute&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+-------+--------+&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;fg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;84920&lt;/span&gt;&lt;span class="n"&gt;cf6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;fip&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;fpr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ea902fe0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+--------+-------+&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+--------+--------+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;rfp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ea902fe0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;qrouter&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+-----------------+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;We don’t need to set ip6tables rules for dvr router. Because just by
adding or removing the related route in fip-namespace (as description
below) can be the switch to enable/disable the IPv6 traffic.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Due to the current Neutron don’t support dvr with IPv6, the qrouter-namespace
has no default route about IPv6. We should add the default route firstly if
the router set external gateway, the default route’s next-hop shoule be the
fpr-dev device’s IPv6 address, The executed command like this (Executed in
qrouter-namespace):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="n"&gt;route&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="n"&gt;via&lt;/span&gt; &lt;span class="n"&gt;fe80&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;8493&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;bff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fe9b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;d93&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;rfp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ea902fe0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Because of the device which directly connects to upstream router is located
in fip-namespace, the proxy entry should be set in fip-namespace. So, the
below cmd should be executed in all fip-namespace:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;sysctl&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ipv6&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;84920&lt;/span&gt;&lt;span class="n"&gt;cf6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;proxy_ndp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For each ndp proxies the extension add a proxy entry to the fg-dev in
fip-namespace, the proxy entry just add to one namespace which hosted in the
node of the ndp proxy object’s port belong to, and add a route in the
namespace so that the packets of which destination is the ndp proxy’s
&lt;cite&gt;ip_address&lt;/cite&gt; can be forwarded to qrouter-namespace. This cmds like below
(Executed in fip-namespace):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="n"&gt;neigh&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt; &lt;span class="mi"&gt;2001&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;fg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;84920&lt;/span&gt;&lt;span class="n"&gt;cf6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;
&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="n"&gt;route&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="mi"&gt;2001&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="n"&gt;via&lt;/span&gt; &lt;span class="n"&gt;fe80&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;a0a7&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;c5ff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fe2c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;bade&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;fpr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ea902fe0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When remove a ndp proxy, the extension should remove related neigh proxy
entry from the fg-dev, and remove the related route, This cmds like below
(Executed in fip-namespace):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="n"&gt;neigh&lt;/span&gt; &lt;span class="k"&gt;del&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt; &lt;span class="mi"&gt;2001&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;fg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;84920&lt;/span&gt;&lt;span class="n"&gt;cf6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;
&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="n"&gt;route&lt;/span&gt; &lt;span class="k"&gt;del&lt;/span&gt; &lt;span class="mi"&gt;2001&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="n"&gt;via&lt;/span&gt; &lt;span class="n"&gt;fe80&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;a0a7&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;c5ff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fe2c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;bade&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;fpr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ea902fe0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Because setting of ip6tables rules is not required, so for the change of
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_ndp_proxy&lt;/span&gt;&lt;/code&gt;, the agent extension needn’t do any thing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If an instance was migrated and it’s port was related to a ndp proxy entry.
The extension should delete related rules in old host and create them in new
host. Additionally, the extension should send a NA (Neighbour Advertisement)
to fresh the upsteam router’s neighbor entry so that the external traffic can
forward to new host’s fip-namespace immediately.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="for-dvr-no-external-mode"&gt;
&lt;h5&gt;For dvr_no_external mode&lt;/h5&gt;
&lt;p&gt;Assume the snat-namespace’s qg-dev is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qg-87059c6c-a9&lt;/span&gt;&lt;/code&gt;, the sg-dev is
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sg-68bcdb7b-a2&lt;/span&gt;&lt;/code&gt;; the qrouter-namespace’s qr-dev is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qr-50457f9b-98&lt;/span&gt;&lt;/code&gt;. The
topology like below:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;    &lt;span class="o"&gt;+---------------+&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;upstream&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="o"&gt;+-------+-------+&lt;/span&gt;
            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+-------+------+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;qg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;87059&lt;/span&gt;&lt;span class="n"&gt;c6c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a9&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;snat&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;sg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;68&lt;/span&gt;&lt;span class="n"&gt;bcdb7b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a2&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+-------+------+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------+&lt;/span&gt;
            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;compute&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+--------+--------+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;50457&lt;/span&gt;&lt;span class="n"&gt;f9b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;98&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;qrouter&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+-----------------+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For this mode, in qrouter-namespace we just need to add a default route, so
that the north-south traffic can be redirected to snat-namespace (The current
neutron code already completed this demand). For snat-namespace we just treat
is as legacy router’s qrouter-namepsace, about it’s rules process we can refer
to &lt;a class="reference internal" href="#legacy-router-impact"&gt;&lt;span class="std std-ref"&gt;Legacy router Impact&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="ovn-backend-impact"&gt;
&lt;h3&gt;OVN backend impact&lt;/h3&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ndp_proxy&lt;/span&gt;&lt;/code&gt; for OVN L3 backend is not covered by this proposal. If it was
proved to be feasible, we should implement the feature base on OVN backend in
the future. But for now, we will just implement this base on Neutron L3 agent.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;yangjianfeng&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;API Implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB Implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reference implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;The functions that the spec proposed need the external hardware router’s
support (need to add a direct route entry at upstream router). This is
difficult for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tempest&lt;/span&gt;&lt;/code&gt; to do this. So, we can skip the scenario tests
firstly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Need to add functional tests&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Need to add API tests&lt;/p&gt;
&lt;/section&gt;
&lt;section id="fullstack-tests"&gt;
&lt;h3&gt;Fullstack Tests&lt;/h3&gt;
&lt;p&gt;Need to add Fullstack tests.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Needs user documentation&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Needs devref documentation&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-reference"&gt;
&lt;h3&gt;API reference&lt;/h3&gt;
&lt;p&gt;Needs API reference documentation&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://tools.ietf.org/html/rfc4389"&gt;https://tools.ietf.org/html/rfc4389&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id13" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://tools.ietf.org/html/rfc1027"&gt;https://tools.ietf.org/html/rfc1027&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id14" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id3"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id6"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id8"&gt;3&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron/train/admin/config-bgp-dynamic-routing.html#ipv6"&gt;https://docs.openstack.org/neutron/train/admin/config-bgp-dynamic-routing.html#ipv6&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id15" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id4"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id5"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id7"&gt;3&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/liberty/ipv6-prefix-delegation.html"&gt;https://specs.openstack.org/openstack/neutron-specs/specs/liberty/ipv6-prefix-delegation.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id16" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/admin/config-address-scopes.html"&gt;https://docs.openstack.org/neutron/latest/admin/config-address-scopes.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id17" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id11"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/admin/deploy-ovs-ha-dvr.html"&gt;https://docs.openstack.org/neutron/latest/admin/deploy-ovs-ha-dvr.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Wed, 20 Jan 2021 00:00:00 </pubDate></item><item><title>Distributed DHCP for Openvswitch Agent</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/wallaby/distributed_dhcp.html</link><description>

&lt;p&gt;RFE: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1900934"&gt;https://bugs.launchpad.net/neutron/+bug/1900934&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron DHCP agents and the scheduled network instances are relatively
simple in function. But the configuration is complex, and it depends
on external process (dnsmasq) and namespace. When the user’s demand is
merely unique, for example, they only need the DHCP response during the
virtual machine booting process, then the existing DHCP agent and its
configuration procedure for network and port make things complicated.&lt;/p&gt;
&lt;p&gt;This spec describes how to implement a DHCP extension for Neutron
openvswitch agent to achive a simple and efficient solution for virtual
machine DHCP function by leveraging the openflow with openvswitch.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Response the DHCP request is the main function for the scheduled network
instance of DHCP agent. Except this, it has other functions, like
isolated metadata and DNS lookup. But there are alternatives for these
extended functions, such as config drive for metadata and Designate
for DNS.&lt;/p&gt;
&lt;p&gt;Then, the use frequency of the DHCP agent and its scheduled instance are
relatively low. It will be used only during the VM booting if no DNS lookup.
If you use config drive, aslo the scheduled DHCP instance is not useful.&lt;/p&gt;
&lt;p&gt;And we have more problems for large scale clusters:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The scheduled network instances of DHCP port increase the consuming of
L2 agent’s capacity and performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The DHCP provisioning block sometimes causes virtual machine booting
failure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Full sync in unknown reason causes the message queue, neutron-server and
DB in high load.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DVR local router creation for the scheduled DHCP port is default behavior,
which increased resource load for L2 and L3 agents implicitly &lt;a class="footnote-reference brackets" href="#id5" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Down a DHCP node causes long time recovery due to it has tons of scheduled
network instance.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And it is hard to find the balance between &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;how&lt;/span&gt; &lt;span class="pre"&gt;many&lt;/span&gt; &lt;span class="pre"&gt;DHCP&lt;/span&gt; &lt;span class="pre"&gt;agents&lt;/span&gt; &lt;span class="pre"&gt;should&lt;/span&gt; &lt;span class="pre"&gt;the&lt;/span&gt;
&lt;span class="pre"&gt;deployment&lt;/span&gt; &lt;span class="pre"&gt;have&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;how&lt;/span&gt; &lt;span class="pre"&gt;many&lt;/span&gt; &lt;span class="pre"&gt;resources&lt;/span&gt; &lt;span class="pre"&gt;could&lt;/span&gt; &lt;span class="pre"&gt;one&lt;/span&gt; &lt;span class="pre"&gt;agent&lt;/span&gt; &lt;span class="pre"&gt;handle&lt;/span&gt;&lt;/code&gt;. Too few
DHCP agent will finally make each one agent has a huge mount of resources.
Too many DHCP agents will increase maintenance pressure for the operators,
and make the centralized components overloaded.&lt;/p&gt;
&lt;p&gt;There is a way to schedule one network to all DHCP agents on all compute
nodes. Firstly, this may work for tiny deployment with extremely few resources.
For large-scale deployment, it is basically impossible. Because there will be
tens of thousands of Networks in Neutron, this will directly lead to a surge of
resource pressure on each node, consume too many IP in user network,
the results basically are unable to operate, virtual machine startup failure
and unable to obtain IP and so on.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;A new extension of Neutron openvswitch agent will be added to achieve the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Distributed&lt;/span&gt; &lt;span class="pre"&gt;DHCP&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This extension is only for openvswitch agent, other mechanism drivers
will not be considered, because this new extension will rely on the
openflow protocol and principle. For OVN, it has supported similar
DHCP local response mechanism.&lt;/p&gt;
&lt;/div&gt;
&lt;section id="solution-proposed"&gt;
&lt;h3&gt;Solution Proposed&lt;/h3&gt;
&lt;p&gt;As we know Neutron openvswitch agent has the entire information of the ports
which are pluged to the ovs bridge (If the port information was not
synchronized by the ovs-agent, there is a simple cache pull mechanism which
will fill the information). Neutron has the all conditions to support
distributed DHCP natively:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;ovs-agent is based on the python SDN controller ryu/os-ken&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ovs-agent is fully distributed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ovs-agent has the entire resource information&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So we can assume the Neutron openvswitch agent is a local SDN controller which
will try to response the VM’s DHCP request. The basical data pipeline can be
described as this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                        &lt;span class="o"&gt;+---------+&lt;/span&gt;                &lt;span class="o"&gt;+---------------------+&lt;/span&gt;
&lt;span class="o"&gt;+-------+&lt;/span&gt; &lt;span class="n"&gt;DHCP&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+----------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;VM&lt;/span&gt;   &lt;span class="o"&gt;+---------------&amp;gt;&lt;/span&gt;  &lt;span class="n"&gt;Flows&lt;/span&gt;  &lt;span class="o"&gt;+----------------&amp;gt;&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ken&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;&amp;lt;---------------+&lt;/span&gt;         &lt;span class="o"&gt;&amp;lt;----------------+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-------+&lt;/span&gt; &lt;span class="n"&gt;DHCP&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;DHCP&lt;/span&gt; &lt;span class="n"&gt;Responder&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                        &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+----------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="n"&gt;OVS&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
                        &lt;span class="o"&gt;+---------+&lt;/span&gt;                &lt;span class="o"&gt;+---------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;After this we will have:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Higher level availability than DHCP agent with it’s schedlued &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dnsmasq&lt;/span&gt;&lt;/code&gt;,
DHCP requests are directly processed in the
computing nodes, it is completely distributed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No DHCP agent and its scheduling mechanism anymore&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No extra external process for DHCP anymore&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The (Neutron openvswith) agent downtime will no longer affect the
address acquisition and virtual machine startup in other nodes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Virtual machine startup will no longer be affected by port’s DHCP
configuration, which reduces the probability of VM spawning failure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DHCP request and reponse for VM will achieve a high success rate.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="dhcp-v4-v6-protocol-options"&gt;
&lt;h4&gt;DHCP(v4/v6) protocol options&lt;/h4&gt;
&lt;p&gt;We will not repeat the DHCPv4 &lt;a class="footnote-reference brackets" href="#id6" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and DHCPv6 &lt;a class="footnote-reference brackets" href="#id7" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; in details. But for
this spec, we will ensure the following features of the related protocol:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DHCPv4 all message types&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DHCPv4 host Configurations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DHCPv6 types Solicit, Advertise, Confirm, Renew, Rebind, Release and Reply&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DHCPv6 Options&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For Neutron, we have some Port attributes like dns_domain, dns_name and
extra_dhcp_opts, and Subnet dns_nameservers, host_routes and gateway_ip
and so on, all these options will be added to the final DHCP
response like dnsmasq do.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="server-side-changes"&gt;
&lt;h4&gt;Server side changes&lt;/h4&gt;
&lt;p&gt;Based on the new added config options, some DHCP related DB options,
APIs, notifications and RPCs will be changed to no operation or be skipped.
The config options only controls Neutron itself, the DHCP protocol will have
no effect on. The final goal is to support the full features of DHCP protocol
defined. The changes are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;disable DHCP scheduling mechanism and its failover forever&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;disable DHCP provisioning block&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;disable DHCP related RPCs and notificatons&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="openvswitch-agent-side-changes"&gt;
&lt;h4&gt;OpenvSwitch Agent side changes&lt;/h4&gt;
&lt;p&gt;For Neutron openvswitch agent, we will add a new agent extension which will
process the basical flow installation for each port’s further DHCP request.&lt;/p&gt;
&lt;p&gt;There will be two basic flows which will direct DHCPv4 and DHCPv6 to independent tables.
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;table&lt;/span&gt; &lt;span class="pre"&gt;77&lt;/span&gt;&lt;/code&gt; is for DHCPv4, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;table&lt;/span&gt; &lt;span class="pre"&gt;78&lt;/span&gt;&lt;/code&gt; is for DHCPv6. The flows are:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;udp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;nw_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;255.255.255.255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;tp_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;68&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;tp_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;resubmit&lt;/span&gt;&lt;span class="p"&gt;(,&lt;/span&gt;&lt;span class="mi"&gt;77&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;udp6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ipv6_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ff02&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;tp_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;546&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;tp_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;547&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;resubmit&lt;/span&gt;&lt;span class="p"&gt;(,&lt;/span&gt;&lt;span class="mi"&gt;78&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For table 77, each DHCP request will be checked to verify the source mac and in_port in order
to avoid the DHCP spoofing. If the DHCP request is matched, then submit it to the controller,
aka the Neutron openvswitch agent. Any unmatched packets will be dropped. One example for a
VM’s port is:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;77&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;udp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"tapcc4f2da4-c5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;58&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;tp_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;68&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;tp_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CONTROLLER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;77&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;drop&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For table 78, DHCPv6 match and drop flows structure are basically same to DHCPv4:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;78&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;udp6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"tapcc4f2da4-c5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;58&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;tp_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;546&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;tp_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;547&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CONTROLLER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;78&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;drop&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For the new extension of openvswitch agent, it will add a local
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;packet_in_handler&lt;/span&gt;&lt;/code&gt; which will do the following works:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Listen on the EventOFPPacketIn event&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify each packet to be DHCPv4 or DHCPv6&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;According to the openflow inport number to retrieve the port’s information&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assemble the DHCP(v4/v6) response and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;packet_out&lt;/span&gt;&lt;/code&gt; to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;in_port&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The response DHCP packet structure will be:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Source&lt;/span&gt; &lt;span class="n"&gt;Mac&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;gateway&lt;/span&gt; &lt;span class="n"&gt;Port&lt;/span&gt;&lt;span class="s1"&gt;'s MAC or A fake fixed MAC|&lt;/span&gt;
&lt;span class="o"&gt;+------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Destination&lt;/span&gt; &lt;span class="n"&gt;Mac&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;Neutron&lt;/span&gt; &lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="n"&gt;Mac&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Source&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="n"&gt;Gateway&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;Subnet&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Destination&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="n"&gt;Neutron&lt;/span&gt; &lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------------------------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Source&lt;/span&gt; &lt;span class="pre"&gt;Mac&lt;/span&gt; &lt;span class="pre"&gt;Address&lt;/span&gt;&lt;/code&gt; will be the internal subnet gateway port’s Mac address.
But actually this is not necessary for the DHCP protocol, we can use a fake
fixed mac address to avoid some DB/RPC query.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Destination&lt;/span&gt; &lt;span class="pre"&gt;Mac&lt;/span&gt; &lt;span class="pre"&gt;Address&lt;/span&gt;&lt;/code&gt; will be the port’s MAC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Source&lt;/span&gt; &lt;span class="pre"&gt;IP&lt;/span&gt; &lt;span class="pre"&gt;Address&lt;/span&gt;&lt;/code&gt; will be the internal subnet’s gateway IP.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Destination&lt;/span&gt; &lt;span class="pre"&gt;IP&lt;/span&gt; &lt;span class="pre"&gt;address&lt;/span&gt;&lt;/code&gt; will be the port’s first IP(v4/v6) address,
the secondary IPs will be ignored.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="potential-configurations"&gt;
&lt;h4&gt;Potential configurations&lt;/h4&gt;
&lt;p&gt;Config option &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;disable_traditional_dhcp&lt;/span&gt;&lt;/code&gt; for neutron server side will be
added which is aiming to control:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;to disable DHCP scheduling for networks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;to disable DHCP provisioning block&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;to disable DHCP RPC/notification&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;to disable all DHCP related API/attibutes network, subnet and port.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A new extension alias name &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dhcp&lt;/span&gt;&lt;/code&gt; will be added for neutron
openvswitch agent:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;extensions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dhcp&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Config section &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[dhcp]&lt;/span&gt;&lt;/code&gt; will be added for neutron openvswitch agent
and register some common options to determine DHCP protocol related
parameters, the final &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[dhcp]&lt;/span&gt;&lt;/code&gt; section for openvswitch agent will be:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;dhcp_opts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BoolOpt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'enable_dhcp_ipv6'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Whether enable DHCP for IPv6"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntOpt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'dhcp_renewal_time'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"DHCP renewal time T1 (in seconds). If set to 0, it "&lt;/span&gt;
                    &lt;span class="s2"&gt;"will default to half of the lease time."&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntOpt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'dhcp_rebinding_time'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"DHCP rebinding time T2 (in seconds). If set to 0, it "&lt;/span&gt;
                    &lt;span class="s2"&gt;"will default to 7/8 of the lease time."&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="the-neutron-basic-workflow"&gt;
&lt;h3&gt;The Neutron basic workflow&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;User creates a VM in a network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nova plug the VM’s NIC port to ovs-bridge&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ovs-agent process the port and install the DHCP related flows&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L2 provisioning block released (No DHCP provisioning block)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VM booting and send DHCP request out&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Match the flows and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;packet_in&lt;/span&gt;&lt;/code&gt; to ovs-agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ovs-agent directly send DHCP(v4/v6) response to VM’s port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VM booting success&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;With the new config options, the following APIs will be disabled &lt;a class="footnote-reference brackets" href="#id8" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;add_network_to_dhcp_agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;remove_network_from_dhcp_agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;list_networks_on_dhcp_agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;list_dhcp_agents_hosting_network&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the option &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enable_dhcp&lt;/span&gt;&lt;/code&gt; of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Subnet&lt;/span&gt;&lt;/code&gt;, this agent extension will set
the flows based on that. If it is False, ports under this subnet will have
no flows installed in table 77 and 78. The DHCP request will hit the final
DROP action.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="upgrading"&gt;
&lt;h3&gt;Upgrading&lt;/h3&gt;
&lt;p&gt;For native ml2/ovs deployment, this feature will be easily to upgrade to
enforce. A simple way is to run all agents as they are. But disable the DHCP
provisioning block. After enable the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dhcp&lt;/span&gt;&lt;/code&gt; extension for ovs-agent, the
DHCP request will be handled by it earlier than &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dnsmasq&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you need a pure deployment without DHCP agents, the following is an overview
about how to migrate to use this new feature:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Upgrading the Neutron code and restart neutron-server processes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Setup the ovs-agent with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dhcp&lt;/span&gt;&lt;/code&gt; extension.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Disable all DHCP agents to make sure no more scheduled network are created.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;disable&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;dhcp_agent_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This action will remove all scheduled network instances from
the admin state DOWN DHCP agent.&lt;/p&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Set the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;disable_traditional_dhcp&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt; option for neutron-server to
disable the scheduling related API/RPCs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(optional, just in case) Remove all scheduled network from all DHCP agents,
this step is to pure all DHCP namespace and DHCP woker process &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dnsmasq&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After no more scheduled network, stop all DHCP agents and remove it from DB.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This feature does not support DNS lookup. If your running deployments
are using the DNS lookup function from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dnsmasq&lt;/span&gt;&lt;/code&gt;, consider use
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;designate&lt;/span&gt;&lt;/code&gt; as an alternative.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;LIU Yulong &amp;lt;&lt;a class="reference external" href="mailto:i%40liuyulong.me"&gt;i&lt;span&gt;@&lt;/span&gt;liuyulong&lt;span&gt;.&lt;/span&gt;me&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Config options for neutron server to control DHCP related codes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create agent extension.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="functionality"&gt;
&lt;h3&gt;Functionality&lt;/h3&gt;
&lt;p&gt;We will add fullstack test case to verify this new agent extension:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create two fake fullstack VMs in two test namespaces&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use DHCP(v4 and v6) to config the fake VM ports&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ping (-4/6) from one fake  VM to another&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/neutron/+/364793"&gt;https://review.opendev.org/c/openstack/neutron/+/364793&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://tools.ietf.org/html/rfc2131"&gt;https://tools.ietf.org/html/rfc2131&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://tools.ietf.org/html/rfc8415"&gt;https://tools.ietf.org/html/rfc8415&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/c/openstack/neutron/+/772255/8/neutron/extensions/dhcpagentscheduler.py#106-126"&gt;https://review.opendev.org/c/openstack/neutron/+/772255/8/neutron/extensions/dhcpagentscheduler.py#106-126&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Mon, 28 Dec 2020 00:00:00 </pubDate></item><item><title>VPNaaS for OVN Networking</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/xena/vpnaas-ovn.html</link><description>

&lt;p&gt;This specification covers the support for VPNaaS with OVN networking by adding
a stand-alone VPN agent. This new agent will create a namespace on the node,
connect it with the OVN distributed logical router and run the Swan process in
the namespace.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The existing VPNaaS service plugin only supports the reference Neutron software
routers, such as neutron L3 router using the L3 agent. This approach does not
work if there is no L3 agent. For OVN a different solution is required.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Add a new stand-alone VPN agent to support OVN+VPN. Add OVN-specific service
and device drivers that support this new VPN agent. This will have no impact
on the existing VPN solution, the existing L3 agent and its VPN extension will
still work.&lt;/p&gt;
&lt;section id="changes-on-neutron-server"&gt;
&lt;h3&gt;Changes on neutron server&lt;/h3&gt;
&lt;section id="vpn-service-driver-and-agent-scheduler"&gt;
&lt;h4&gt;VPN service driver and Agent scheduler&lt;/h4&gt;
&lt;p&gt;The VPN service driver has different implementations for different VPNaaS
solutions. The existing implementation relies on the Neutron L3 router
scheduler to decide where the VPN service process is hosted and the VPN device
driver is part of the L3 agent. In OVN the L3 router scheduler and L3 agents
are not used anymore, so a replacement is required.&lt;/p&gt;
&lt;p&gt;For the newly-introduced agent type “VPN agent”
we also add a corresponding VPN agent scheduler. Using the OVN-related
scheduler for the router gateway port was ruled out because the VPN agent
scheduler should also keep track whether the VPN agent(s) are still alive.&lt;/p&gt;
&lt;p&gt;The new VPN agent scheduler will work on a per-router basis to have all IPSec
site connections of a router processed by the same agent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="vpn-gateway-and-transit-network"&gt;
&lt;h4&gt;VPN gateway and transit network&lt;/h4&gt;
&lt;p&gt;In the existing implementation for ML2/OVS the VPNaaS shares the router gateway
IP address with router SNAT, but for OVN the gateway public IP address (SNAT)
can’t be shared with the VPN because SNAT is not in the namespace context.
A new public IP address is needed for the VPNaaS namespace, so a VPN gateway
port is created in the external network of the router. This address will be
visible as the external_v4_ip/external_v6_ip of the VPN service.&lt;/p&gt;
&lt;p&gt;To connect the router with the namespace a “Transit network” (169.254.0.0/30)
is created and attached to the router. It is used to route traffic between
virtual machine network(s) and the VPN process namespace. The respective routes
added to the router are (per peer CIDR):&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;destination CIDR: peer CIDR&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;next hop: IP address of a port in the transit network (169.254.0.2)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The new ports and the transit network and subnet are managed using the API of
the Neutron core plugin and OVN L3 router service plugin, not “under the hood”
with OVN functions, to avoid inconsistencies between the Neutron database and
OVN Northbound. This makes sure that scripts that sync Neutron DB and OVN
Northbound (like neutron-ovn-db-sync-util) don’t delete lswitches that
were created for the VPNaaS transit network but have no corresponding Neutron
DB entries.&lt;/p&gt;
&lt;p&gt;The IDs of the newly added ports, transit network and subnet are stored in a
new database table “vpn_ext_gws” (for VPN external gateways).
The gateway port and transit network are created automatically when the first
VPN service of a router is created and are deleted after the last VPN service
of the router is removed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="naming-of-neutron-objects"&gt;
&lt;h4&gt;Naming of Neutron objects&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;External gateway port for VPN: “vpn-gw-{router_id}” (with device owner
“network:vpn_router_gateway”, device ID is the router ID)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VPN transit network: “vpn-transit-network-{router_id}”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VPN transit subnet: “vpn-transit-subnet-{router_id}”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Port in the VPN transit network, to be plugged by the agent in the VPN
namespace: “vpn-ns-{router_id}” (with device owner “network:vpn_namespace”,
device ID is the transit subnet ID)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="changes-on-vpn-agent"&gt;
&lt;h3&gt;Changes on VPN agent&lt;/h3&gt;
&lt;p&gt;For OVN the VPN functionality is implemented in a new dedicated VPN agent using
new OVN specific device drivers.&lt;/p&gt;
&lt;section id="configuration-synchronization"&gt;
&lt;h4&gt;Configuration synchronization&lt;/h4&gt;
&lt;p&gt;The existing VPNaaS implementation uses rabbitmq RPCs to synchronize the VPN
configuration between the database and the IKE daemon (strongswan etc)
controlled by the agent.&lt;/p&gt;
&lt;p&gt;Ideally a VPNaaS solution for OVN would avoid rabbitmq. But currently there
is no support for configuring VPNs in OVN (via north/southbound databases).
While it is possible to configure IPSec for tunnel ports, it’s not possible
to set up and configure IPSec site connections to external peers.&lt;/p&gt;
&lt;p&gt;To still be able to offer VPNaaS some other means than configuration via
OVN north/southbound tables is necessary. Possible solutions could be:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Use rabbitmq RPCs as in the existing VPNaaS plugin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instead of rabbitmq, implement REST APIs on both ends (neutron server and
VPN agent). This includes API endpoints that let the agent know about
configuration changes (server -&amp;gt; agent), that allow agents to fetch the
current configuration (agent -&amp;gt; server) and that allow agents to report
state changes (agent -&amp;gt; server)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The least complex implementation approach is (1) to rely on existing code
even if it is still using rabbitmq instead of rewriting the server/agent
communication with new REST APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="vpn-namespace-management"&gt;
&lt;h4&gt;VPN namespace management&lt;/h4&gt;
&lt;p&gt;The agent creates a VPN namespace and plugs two ports:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;the external gateway port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;a port in the transit network bound to 169.254.0.2&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There will be one VPN namespace per router and it’s scheduled on exactly one
VPN agent. The VPN agent shall make sure that only those VPN namespaces exist
on the node which are scheduled there. I.e. when the agent starts it will
synchronize with the controller and potentially delete superfluous VPN
namespaces and/or create missing ones.&lt;/p&gt;
&lt;p&gt;VPN namespaces are created by the VPN agent / device driver when the first
IPSec site connection of a router is created and are deleted if all IPSec site
connections of the router were deleted.&lt;/p&gt;
&lt;p&gt;Routes are configured in the namespace to route incoming traffic to the local
subnets (destination: local CIDR, next hop: router port of the transit network,
i.e. 169.254.0.1). These routes are updated whenever the IPSec site connection
configuration changes.&lt;/p&gt;
&lt;p&gt;The agent will&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;create a namespace called “qvpn-{router_id}”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create two interfaces in the namespace:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;vgxxxxxxxx-xxx, where xxxxxxxx-xxx is the prefix of the port UUID of the
VPN external gateway port (IP address in the external network)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;vrxxxxxxxx-xxx, where xxxxxxxx-xxx is the prefix of the port UUID of the
VPN transit network port (169.254.0.2)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;plug the two interfaces&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;add routes&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="liveness-of-the-vpn-agent"&gt;
&lt;h4&gt;Liveness of the VPN agent&lt;/h4&gt;
&lt;p&gt;There are two ways how liveness checks could be implemented:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Traditional way using rabbitmq. The VPN agent periodically reports its state
(“report_state” RPC). The server side plugin utilizes the
AgentSchedulerDbMixin functionality to keep track of alive agents and will
potentially reschedule VPN services if an agent is down.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Liveness check using OVN similar to OVN Metadata agent. The server sets
a new value of the “neutron:liveness_check_at” external_id in NB_Global,
the agent monitors SB_Global and will set an external_id in its chassis row
(external_id “neutron:ovn-vpnagent-sb-cfg”)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The second approach is more in line with the management of agents in the Neutron
OVN mech driver.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="vpn-plugin-configuration-for-ovn"&gt;
&lt;h3&gt;VPN plugin configuration for OVN&lt;/h3&gt;
&lt;p&gt;The OVN VPN plugin is an extension of the existing one in order to add the VPN
agent scheduler and status checks.&lt;/p&gt;
&lt;p&gt;The service plugin to be added to neutron.conf is
neutron_vpnaas.services.vpn.ovn_plugin.VPNOVNDriverPlugin&lt;/p&gt;
&lt;p&gt;For OVN there is a new dedicated service driver, so the service_provider
setting in neutron_vpnaas.conf will be:
VPN:openswan:neutron_vpnaas.services.vpn.service_drivers.ovn_ipsec.IPsecOvnVPNDriver:default&lt;/p&gt;
&lt;p&gt;There is a new agent type “VPN agent”&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The agent binary is neutron-vpn-agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The agent configuration file is /etc/neutron/vpn_agent.ini&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The agent uses the VPN device driver configured in vpnagent/vpn_device_driver.
An example device driver entry is
vpn_device_driver = neutron_vpnaas.services.vpn.device_drivers.ovn_ipsec.OvnStrongSwanDriver&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="database-impact"&gt;
&lt;h3&gt;Database impact&lt;/h3&gt;
&lt;p&gt;Two new tables are added to the neutron database:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;vpn_ext_gws: keeps the IDs of the additional network items needed for VPN
services of a router (gateway port, transit network, subnet, port)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;routervpnagentbindings: keeps the VPN agent ID per router&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-and-cli-impact"&gt;
&lt;h3&gt;REST API and CLI impact&lt;/h3&gt;
&lt;p&gt;There are no changes to the REST API or CLI of VPNaaS or Neutron.&lt;/p&gt;
&lt;p&gt;The external IP address of the VPN service is visible in its
external_v4_ip/external_v6_ip and will be different than the one of
the router.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1905391"&gt;https://bugs.launchpad.net/neutron/+bug/1905391&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 16 Dec 2020 00:00:00 </pubDate></item><item><title>Source and destination filtering for metering label rules</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/victoria/source-and-destination-metering-label-rules.html</link><description>

&lt;p&gt;This spec adds source and destination filtering options
to Neutron metering label rules.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Neutron metering label rules have a parameter called “remote-ip-prefix”, which
would allow operators to filter traffic based on the remote IP address.
However, since &lt;a class="footnote-reference brackets" href="#id6" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, its meaning was changed to the exact opposite, which makes
a bit of confusion. Instead of matching on the remote prefix (towards the
external interface), it matches the local prefix (towards the OpenStack tenant
networks).&lt;/p&gt;
&lt;p&gt;Ideally, to satisfy the use case presented in &lt;a class="footnote-reference brackets" href="#id6" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; (which was achieved by
inverting the use of “remote-ip-prefix”), operators should be able to create
rules based on local-ip-prefix and remote-ip-prefix.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;As discussed in the Neutron drivers metering that approved the RFE &lt;a class="footnote-reference brackets" href="#id7" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; of
this spec, we  will deprecate the parameter &lt;cite&gt;remote-ip-prefix&lt;/cite&gt; of Neutron
metering API.&lt;/p&gt;
&lt;p&gt;Therefore, we will be introducing two new parameters with this spec in the
Neutron metering rule API. These new parameters will be called
“source_ip_prefix”, and “destination_ip_prefix” (like in IPtables).
The behavior of “remote_ip_prefix” will be maintained, but we will fix its
documentation and mark it for removal in future releases &lt;a class="footnote-reference brackets" href="#id6" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The “source_ip_prefix” and “destination_ip_prefix” could be used together, or
only one of them can be defined. However, a metering rule must always have at
least one of them (source_ip_prefix or destination_ip_prefix) defined. On the
other hand, these two new parameters will not be allowed to be used in
conjunction with “remote_ip_prefix”.&lt;/p&gt;
&lt;section id="api-json"&gt;
&lt;h3&gt;API JSON&lt;/h3&gt;
&lt;p&gt;Current JSON  for “v2.0/metering/metering-label-rules” endpoint:&lt;/p&gt;
&lt;div class="highlight-json notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"remote_ip_prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"192.168.0.14/32"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"egress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"metering_label_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9ffd6512-9d2a-4dd2-9657-6a605126264d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f1694467-d866-4d8e-a8dc-18da516caedc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"excluded"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Adding new attributes:&lt;/p&gt;
&lt;div class="highlight-json notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"source_ip_prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"192.168.0.14/32"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"destination_ip_prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"egress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"metering_label_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9ffd6512-9d2a-4dd2-9657-6a605126264d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f1694467-d866-4d8e-a8dc-18da516caedc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"excluded"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="database-table-changes"&gt;
&lt;h3&gt;Database table changes&lt;/h3&gt;
&lt;p&gt;Currently, the table “meteringlabelrules” is defined as:&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;+-------------------+--------------------------+------+-----+---------+-------+
&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Field&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Type&lt;span class="w"&gt;                     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Key&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Default&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Extra&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
+-------------------+--------------------------+------+-----+---------+-------+
&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;id&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;varchar&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;36&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NO&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;PRI&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NULL&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;direction&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;enum&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ingress'&lt;/span&gt;,&lt;span class="s1"&gt;'egress'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;YES&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NULL&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;remote_ip_prefix&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;varchar&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;64&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;YES&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NULL&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;metering_label_id&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;varchar&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;36&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NO&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;MUL&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NULL&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;excluded&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;tinyint&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;YES&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
+-------------------+--------------------------+------+-----+---------+-------+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We would add two new fields to it. Therefore, it would look like:&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;+-----------------------+--------------------------+------+-----+---------+-------+
&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Field&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Type&lt;span class="w"&gt;                     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Key&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Default&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Extra&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
+-----------------------+--------------------------+------+-----+---------+-------+
&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;id&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;varchar&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;36&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NO&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;PRI&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NULL&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;direction&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;enum&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ingress'&lt;/span&gt;,&lt;span class="s1"&gt;'egress'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;YES&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NULL&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;remote_ip_prefix&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;varchar&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;64&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;YES&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NULL&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;source_ip_prefix&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;varchar&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;64&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;YES&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NULL&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;destination_ip_prefix&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;varchar&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;64&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;YES&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NULL&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;metering_label_id&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;varchar&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;36&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NO&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;MUL&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NULL&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;excluded&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;tinyint&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;YES&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
+-----------------------+--------------------------+------+-----+---------+-------+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="neutron-metering-agent-changes"&gt;
&lt;h3&gt;Neutron Metering agent changes&lt;/h3&gt;
&lt;p&gt;The IPtables driver in the metering agent will need to handle the new
parameters “source_ip_prefix” and “destination_ip_prefix” properly.
When building the IPtable rules the parameter “destination_ip_prefix”
(if defined) will be used with the option “-d” (IPtables option).
On the other hand, the parameter “source_ip_prefix” (if defined) will
be used with option “-s”(IPtables option).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="validations"&gt;
&lt;h3&gt;Validations&lt;/h3&gt;
&lt;p&gt;To simplify validations, we propose to remove the overlapping IP_prefixes
validations for the new fields (for the remote IP prefix, it will be
maintained). The rationally behind this removal is that if the operator
wants to somehow create rules that overlap, we should not be the ones blocking
it (there might be some business logic that needs it).&lt;/p&gt;
&lt;p&gt;We will implement the following validation:
* The source IP prefix must be a valid IPv4 CIDR
* The destination IP prefix must be a valid IPv4 CIDR
* Each metering label rule requires at least source, destination, or remote IP
prefix to be informed. The remote IP prefix is marked as deprecated.
Therefore, once it is removed, the users will have to enter at least source or
destination IP prefixes. One can also use both (source and destination IP
prefixes) to build rule.
* source and destination IP prefixes cannot be used in conjunction with
remote IP prefix.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-impacts"&gt;
&lt;h3&gt;API impacts&lt;/h3&gt;
&lt;p&gt;Two new parameters will be introduced, but they are not required.
Therefore, people using it would not suffer an immediate impact.
However, when the “remote_ip_prefix” is removed, people might
have a problem. therefore, as soon as the new method of building rules
is available, people will be encouraged to use it, instead of the
“remote_ip_prefix” metering rule base.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignees:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Rafael &amp;lt;&lt;a class="reference external" href="mailto:rafael%40apache.org"&gt;rafael&lt;span&gt;@&lt;/span&gt;apache&lt;span&gt;.&lt;/span&gt;org&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The following are the work items for the planned release.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Deprecate remote IP prefix (Neutron-lib)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Deprecate remote IP prefix&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fix documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;Add source and destination attributes (Neutron-lib) – executed via &lt;a class="footnote-reference brackets" href="#id8" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add new attributes in api/definitions/metering.py&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fix JSON of examples and documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="3"&gt;
&lt;li&gt;&lt;p&gt;Deprecate remote IP prefix (Neutron)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Deprecate remote IP prefix&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fix documentation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Log a warning when people use it&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="4"&gt;
&lt;li&gt;&lt;p&gt;Change execution flow in Neutron and Neutron metering agent to use the new fields. (Neutron)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add the new DB fields in objects.metering.MeteringLabelRule and neutron/db/models/metering.MeteringLabelRule&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB script in neutron/db/migration/alembic_migrations/versions/victoria&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Actual implementation to use the new attributes, and unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the documentation of the API with the new fields&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="5"&gt;
&lt;li&gt;&lt;p&gt;Deprecate remote IP prefix (OpenStack SDK)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Deprecate remote IP prefix&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fix documentation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Log a warning when people use it&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="6"&gt;
&lt;li&gt;&lt;p&gt;Deprecate remote IP prefix (OpenStack python client)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Deprecate remote IP prefix&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fix documentation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Log a warning when people use it&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="7"&gt;
&lt;li&gt;&lt;p&gt;Add the new fields (OpenStack SDK)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add the new fields&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fix documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="8"&gt;
&lt;li&gt;&lt;p&gt;Add the new fields (OpenStack python client)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add the new fields&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fix documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;After we finish all of these items, in a future release, we will need to
execute the following removal items.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Remove remote IP prefix (Neutron-lib)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Fix JSON of examples and documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;Remove remote IP prefix (Neutron)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Fix documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="3"&gt;
&lt;li&gt;&lt;p&gt;Remove remote IP prefix (OpenStack SDK)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Fix documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="4"&gt;
&lt;li&gt;&lt;p&gt;Remove remote IP prefix (OpenStack python client)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Fix documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id4"&gt;3&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://opendev.org/openstack/neutron/commit/92db1d4a2c49b1f675b6a9552a8cc5a417973b64"&gt;https://opendev.org/openstack/neutron/commit/92db1d4a2c49b1f675b6a9552a8cc5a417973b64&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1889431"&gt;https://bugs.launchpad.net/neutron/+bug/1889431&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/#/c/743828/"&gt;https://review.opendev.org/#/c/743828/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 04 Aug 2020 00:00:00 </pubDate></item><item><title>Port NUMA affinity policy</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/victoria/port-numa-affinity-policy.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1886798"&gt;https://bugs.launchpad.net/neutron/+bug/1886798&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add a new parameter to “port” object setting the NUMA affinity policy.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently Nova allows to define the “numa_affinity_policy” for PCI devices.
Those PCI devices could be, for example, network cards. When a port is created
using this physical device (an SR-IOV port with VNIC type “direct”,
“direct-physical”, “macvtap” or “virtio-forwarder”), Nova will select the host
to spawn the virtual machine depending on the host NUMA topology availability
and the NUMA nodes associated to this PCI network device &lt;a class="footnote-reference brackets" href="#id7" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However this filtering cannot be done currently for other backends than SR-IOV.
For example, Open vSwitch with DPDK will run the PMD threads attached to
specific CPU cores (and to specific NUMA nodes) &lt;a class="footnote-reference brackets" href="#id8" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. Nova represents
this information assigning a set of NUMA nodes to each defined physical or
tunneled network &lt;a class="footnote-reference brackets" href="#id9" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. If the port NUMA affinity policy is provided, Nova will
enforce it during the scheduling.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The goal of this spec is to create a “numa_affinity_policy” parameter
applicable to all ports. This information will be provided to Nova that will
use it while scheluding the virtual machine, independently of the network
backend.&lt;/p&gt;
&lt;p&gt;Of course, Nova should have the network backend NUMA information topology. For
example, since &lt;a class="footnote-reference brackets" href="#id9" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, Nova can be statically configured with the physical
networks NUMA location. With the port “numa_affinity_policy” parameter, the
Nova scheduler will filter those hosts matching the required policy.&lt;/p&gt;
&lt;p&gt;This spec covers the missing cases defined in &lt;a class="footnote-reference brackets" href="#id10" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. Defining the NUMA
affinity policy per port (interface), includes all type of ports, not only the
SR-IOV interfaces. It also avoids defining the NUMA affinity in the Nova
flavor; instead of this, a generic flavor can be used with ports with
different policies.&lt;/p&gt;
&lt;p&gt;This spec proposes to add a new parameter to the “port” object. This parameter,
“numa_affinity_policy”, will be an string defining the NUMA affinity policy,
based on the PCINUMAAffinityPolicy &lt;a class="footnote-reference brackets" href="#id11" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; enum defined in Nova. That field could
have different values: “required”, “legacy” and “preferred”.&lt;/p&gt;
&lt;p&gt;This information will be populated in the “port” dictionary when informing to
Nova. This parameter will be added as a new extension in the port dictionary,
in a new field called “numa_affinity_policy”. By default, the value of this new
parameter will be “None”, to keep backwards compatibility.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;A new table, “portnumaaffinitypolicy”, will be created:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/Conversion&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;port_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;numa_affinity_policy&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;enum (including None)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This child table will depend on the “ports” table. Each row will have a 1:1
relationship with a “port” row and will be deleted when the “port”
row is deleted too.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;The parameter “numa_affinity_policy” in the “port” API:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;NUMA_AFFINITY_POLICY_VALUES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'preferred'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'legacy'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'port'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'numa_affinity_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;NUMA_AFFINITY_POLICY_VALUES&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The parameter can be updated only if the port is not bound. That check does
not depend on the API but on the server.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="operators-cli-impact"&gt;
&lt;h3&gt;Operators CLI Impact&lt;/h3&gt;
&lt;p&gt;An additional parameter will be added to the OSC “port” CLI interface, in the
create, set and unset commands.&lt;/p&gt;
&lt;p&gt;For logging resource:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;numa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;numa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;preferred&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                       &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;numa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;legacy&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;numa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;numa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;preferred&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;numa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;legacy&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="n"&gt;unset&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;numa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Rodolfo Alonso Hernandez &amp;lt;&lt;a class="reference external" href="mailto:ralonsoh%40redhat.com"&gt;ralonsoh&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt; (IRC: ralonsoh)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit Test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functional test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API test&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add CLI usage into the networking guide for operator.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/nova-specs/specs/queens/implemented/share-pci-between-numa-nodes.html"&gt;https://specs.openstack.org/openstack/nova-specs/specs/queens/implemented/share-pci-between-numa-nodes.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://docs.openvswitch.org/en/latest/intro/install/dpdk/"&gt;http://docs.openvswitch.org/en/latest/intro/install/dpdk/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id9" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id3"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id4"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/nova-specs/specs/rocky/implemented/numa-aware-vswitches.html"&gt;https://specs.openstack.org/openstack/nova-specs/specs/rocky/implemented/numa-aware-vswitches.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/nova-specs/specs/ussuri/implemented/vm-scoped-sriov-numa-affinity.html#alternatives"&gt;https://specs.openstack.org/openstack/nova-specs/specs/ussuri/implemented/vm-scoped-sriov-numa-affinity.html#alternatives&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id11" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/nova/blob/d4c857dfcb1ccfa5410de55671e69c722bbc990e/nova/objects/fields.py#L740-L746"&gt;https://github.com/openstack/nova/blob/d4c857dfcb1ccfa5410de55671e69c722bbc990e/nova/objects/fields.py#L740-L746&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Fri, 31 Jul 2020 00:00:00 </pubDate></item><item><title>Floating IP port forwarding to support port ranges</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/wallaby/port-forwarding-port-ranges.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/floatingips-portforwarding-ranges"&gt;https://blueprints.launchpad.net/neutron/+spec/floatingips-portforwarding-ranges&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The use of port ranges in NAT eases the rules creation process as it replaces
the use of many entries in the iptables by just one. Also, some users, when
requesting virtual machines that have some ports exposed to the Internet,
prefer to request a range of ports to be exposed to avoid doing many requests
for operators regarding the networking configurations. Therefore, they usually
request a slice of external ports to deploy their applications, so they will
be able to choose and change the ports they desire on the fly without needing
to contact anyone else or configuring it in OpenStack.&lt;/p&gt;
&lt;p&gt;Moreover, there are applications such as FTP, video conference systems,
streaming, and others that use more than one port (ports in sequence).&lt;/p&gt;
&lt;p&gt;Therefore, it is easier to enable all of them (the requested/needed port range)
in a single configuration.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Currently, if a user wants to create NAT rules that cover multiple ports,
he/she needs to create them one by one, which is cumbersome in some use
cases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When configuring NAT via iptables &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; (and other networking
systems/applications), operators can use port ranges while configuring a
rule; therefore, it is natural for network engineers to handle/use port
ranges in their NAT configurations.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Change the Floating IP port forwarding API to allow the use of port ranges to
create NAT rules. The changes are presented as follows. Today, when a user is
creating a port forwarding rule, he/she creates a rule via API, or CLI and
sends a JSON like:&lt;/p&gt;
&lt;div class="highlight-json notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"port_forwarding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"internal_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"172.16.0.7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"internal_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"internal_port_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"b67a7746-dc69-45b4-9b84-bb229fe198a0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"external_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"desc"&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The external/internal ports are integers and if the user desires to create a
port forwarding in a floating ip for many ports, he/she will need to resend
this JSON many times to fit the number of ports he/she desires.&lt;/p&gt;
&lt;p&gt;The proposal is to change the API/CLI to accept a string in external/internal
ports range. This will allow users to create a rule with port ranges (instead
of executing multiple calls). Therefore, a user would not need anymore to
create 100 rules to reach 100 port forwards in his/her virtual machine, he/she
could just send a JSON like that:&lt;/p&gt;
&lt;div class="highlight-json notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"port_forwarding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"internal_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"172.16.0.7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"internal_port_range"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"8000:8100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"internal_port_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"b67a7746-dc69-45b4-9b84-bb229fe198a0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"external_port_range"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9000:9100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"desc"&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The API will be still accepting the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;internal_port&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_port&lt;/span&gt;&lt;/code&gt;
attributes to maintain backward compatibility.&lt;/p&gt;
&lt;p&gt;The new expected response will be a JSON like:&lt;/p&gt;
&lt;div class="highlight-json notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"port_forwarding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"internal_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"172.16.0.7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"internal_port_range"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"8000:8100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"internal_port_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"b67a7746-dc69-45b4-9b84-bb229fe198a0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"external_port_range"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9000:9100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"desc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"825ade3c-9760-4880-8080-8fc2dbab9acc"&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;New validations will be created to avoid users to enter invalid ranges in
ports. Here follows a summary of all of the validations executed by the system:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Only N(external port[s]) to N (internal port[s]) are allowed or
N(external port[s]) to 1 (internal port). Therefore, all of the other
combinations (1:N, N:M, M:N) are not allowed and will generate an error.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When defining a port(s) range, the ports in this range cannot be already
in use by any other port forwarding rule for the same floating IP and
protocol.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A valid port is a number between 1 and 65535. All other cases will generate
an error. Even though “0” is a valid port, we will not allow its use as it is
reserved.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The notation to define a port range is the following:
&amp;lt;port_range_begin&amp;gt;[:&amp;lt;port_range_end&amp;gt;]; anything that does not match this
definition will generate an error.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When doing the request, the user can choose between sending a JSON with
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;internal_port_range&lt;/span&gt;&lt;/code&gt; (string) or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;internal_port&lt;/span&gt;&lt;/code&gt; (integer), the same to
the external ports, sending both &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;internal_port_range&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;internal_port&lt;/span&gt;&lt;/code&gt; will raise a validation error.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;Today, the port_forwarding table schema is something like:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;id&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;floatingip_id&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;external_port&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;internal_neutron_port_id&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;protocol&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;socket&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;A1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;C2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;80&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;tcp&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;172.16.0.7:8080&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;B1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;C2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;81&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;B2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;tcp&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;172.16.0.7:8081&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;To make the port_forwarding table more like the PortForwarding object and the
JSON, the port_forwarding table will be updated splitting the socket column
into three new columns (internal_ip_address, internal_port_start,
internal_port_end), also, the external_port column will be split into two new
columns (external_port_start and external_port_end). The new table would be like below:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;id&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;floatingip_id&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;external_port&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;external_port_start&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;external_port_end&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;internal_neutron_port_id&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;protocol&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;internal_ip_address&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;internal_port_start&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;internal_port_end&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;socket&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;A1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;C2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;80&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;80&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;80&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;tcp&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;172.16.0.7&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;8080&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;8080&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;172.16.0.7:8080&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;B1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;C2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;81&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;81&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;81&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;B2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;tcp&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;172.16.0.7&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;8081&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;8081&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;172.16.0.7:8081&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The legacy data migration would be done with an alembic migration upgrade
script.&lt;/p&gt;
&lt;p&gt;We have 5 steps in the data migration:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Create the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;internal_ip_address&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;internal_port_start&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_port_start&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;internal_port_end&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_port_end&lt;/span&gt;&lt;/code&gt; columns with NULL values;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select id, socket and external_port columns for every table entry;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For each entry, split the socket value by ‘:’ and put the result in the new
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;internal_ip_address&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;internal_port_start&lt;/span&gt;&lt;/code&gt; columns from same id as the
socket. Migrate the value of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;internal_port_start&lt;/span&gt;&lt;/code&gt; column in the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;internal_port_end&lt;/span&gt;&lt;/code&gt; and migrate the value of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_port&lt;/span&gt;&lt;/code&gt; column
in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_port_start&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;external_port_end&lt;/span&gt;&lt;/code&gt; columns;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change the socket column to nullable;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change the external_port column to nullable;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="sub-resource-extension"&gt;
&lt;h3&gt;Sub Resource Extension&lt;/h3&gt;
&lt;p&gt;It will be created as an extension that overrides the parameters (external_port
and internal_port) to also accept port ranges in their validations. The
attributes map of new sub resource would be like:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;SUB_RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'port_forwarding'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'parameters'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'external_port_range'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:port_range'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_sort_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'internal_port_range'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:port_range'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignees:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Pedro &amp;lt;&lt;a class="reference external" href="mailto:phpm13%40gmail.com"&gt;phpm13&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rafael &amp;lt;&lt;a class="reference external" href="mailto:rafael%40apache.org"&gt;rafael&lt;span&gt;@&lt;/span&gt;apache&lt;span&gt;.&lt;/span&gt;org&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;API extension (neutron-lib)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB extension/data migration (neutron)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend Neutron API with new validations for port ranges (neutron)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend l3 agent to apply the ranges in the iptable rule (neutron)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;floating&lt;/span&gt; &lt;span class="pre"&gt;ip&lt;/span&gt; &lt;span class="pre"&gt;port&lt;/span&gt; &lt;span class="pre"&gt;forwarding&lt;/span&gt;&lt;/code&gt; command to accept and validate ranges in the CLI (python-openstackclient)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change the port types from int to string in the PortForwarding object (openstacksdk)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="to-be-done-in-future-releases"&gt;
&lt;h3&gt;To be done in future releases&lt;/h3&gt;
&lt;p&gt;1) Remove the columns “socket” and “external_port” from the port_forwarding
table in the neutron’s database, as these columns are no more used after the
release wallaby.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.netfilter.org/documentation/HOWTO/NAT-HOWTO-6.html"&gt;https://www.netfilter.org/documentation/HOWTO/NAT-HOWTO-6.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Mon, 06 Jul 2020 00:00:00 </pubDate></item><item><title>Fix the dns-assignment on neutron port</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/victoria/port_dns_assignment.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1873091"&gt;https://bugs.launchpad.net/neutron/+bug/1873091&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The dns-domain part of the dns-assignment for the neutron port is always taken
from the dns-domain defined in the neutron configuration&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;When the user enable the dns or dns_domain_ports extension there are multiple ways to
define Designate dns_domain (Designate zone) in Neutron side as follows:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron configuration file which contain the default value for dns_domain&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron network definition which define the dns_domain for network and enable the dns
extension for that network so every port created under the network will have a dns
record in that dns_domain and it override the default value in configuration file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron port definition when the dns_domain_ports extension is enabled which is used
to override the Neutron network dns_domain and create the dns record under another
dns_domain&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The dns-domain can be set on network level using &lt;cite&gt;openstack network set –dns-domain&lt;/cite&gt;
and on port level using dns_domain_ports extension &lt;cite&gt;openstack port create –dns-domain&lt;/cite&gt;
and both of those values (network level, port level dns-domians) are ignored when forming
the port dns-assignment which always take the dns-domain in neutron config&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The port level dns-domain should take precedence over network level dns-domain which take
precedence over the neutron config dns-domain which will be the default if the above two levels
dont have dns-domain assigned&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="unit-test"&gt;
&lt;h3&gt;Unit Test&lt;/h3&gt;
&lt;p&gt;Unit test should be added to make sure that the right dns-domain is used in Neutron port dns assignment&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;The documemtation is showing the dns assignment with the dns domain defined in the Neutron configurations
or defined in the Neutron network (which is usually the same) but not the dns_domain comming from Neutron
port creare (use case 3) which should be updated&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/admin/config-dns-int-ext-serv.html#config-dns-int-ext-serv"&gt;https://docs.openstack.org/neutron/latest/admin/config-dns-int-ext-serv.html#config-dns-int-ext-serv&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2020 00:00:00 </pubDate></item><item><title>Allow sharing security groups as read-only</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/victoria/share-security-groups-readonly.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1875516"&gt;https://bugs.launchpad.net/neutron/+bug/1875516&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Allow sharing security groups as read-only.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently, security groups can be shared with the rbac system, but the only
valid action is &lt;cite&gt;access_as_shared&lt;/cite&gt;, which allows the target tenant to
create/delete (only) new rules on the security group. This works fine for
use-cases where the group should be shared in a nearly equal way.&lt;/p&gt;
&lt;p&gt;However, some users/services may want a security group to be visible, but
read-only. A prime example of this would be to enable ProjectB to add a
security group owned by ProjectA as a remotely trusted group on their own
security group.&lt;/p&gt;
&lt;p&gt;The immediate need for this is found in an existing Octavia patch &lt;a class="footnote-reference brackets" href="#id5" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.
Octavia would like to share the security group it creates for each
load-balancer with the load-balancer’s owner, so they can open access to their
backend members for only a specific load-balancer.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Add a new action type for security group RBAC: &lt;cite&gt;access_as_readonly&lt;/cite&gt;. This
action would allow the target tenant to see the shared security group with
show/list, but not create/delete new rules for it or change it in any way.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Neutron documentation about sharing security groups will need to be modified to
add the action type &lt;cite&gt;access_as_readonly&lt;/cite&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Adam Harwell&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add new action type &lt;cite&gt;access_as_readonly&lt;/cite&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation update in config-rbac.rst &lt;a class="footnote-reference brackets" href="#id6" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; as seen in &lt;a class="footnote-reference brackets" href="#id7" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create additional tempest tests in RbacSharedSecurityGroupTest class &lt;a class="footnote-reference brackets" href="#id8" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/723735"&gt;https://review.opendev.org/723735&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/master/doc/source/admin/config-rbac.rst"&gt;https://github.com/openstack/neutron/blob/master/doc/source/admin/config-rbac.rst&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron/train/admin/config-rbac.html#sharing-a-security-group-with-specific-projects"&gt;https://docs.openstack.org/neutron/train/admin/config-rbac.html#sharing-a-security-group-with-specific-projects&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-tempest-plugin/blob/master/neutron_tempest_plugin/api/test_security_groups.py"&gt;https://github.com/openstack/neutron-tempest-plugin/blob/master/neutron_tempest_plugin/api/test_security_groups.py&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Fri, 15 May 2020 00:00:00 </pubDate></item><item><title>Address Groups Support in Security Group Rules</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/victoria/address-groups-support-in-security-group-rule.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1592028"&gt;https://bugs.launchpad.net/neutron/+bug/1592028&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This specification describes how to support address groups (groups of IP
address blocks) in Neutron security group rules. The concept of address groups
was introduced in FWaaS v2.0 but not implemented [1].&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Neutron security group rules currently support using an IP address block or a
security group as the remote end of the network access rule. In actual usage,
an OpenStack cloud may require connectivity between instances and external
services which are not provisioned by OpenStack. And each service may also
have multiple endpoint addresses which are not contiguous. To allow the
connectivity, one rule per external address needs to be created which can be
very cumbersome and difficult to maintain as the number of external addresses
may be substantial.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Add an API to aggregate IP address blocks into an address group object which
could be later referenced when creating a security group rule. Thus the number
of security group rules can be effectively reduced when there is the need to
allow connectivity to a number of external service addresses. When IP addresses
are updated in the address group, changes will also be reflected in the
associated security group rules.&lt;/p&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;section id="new-address-groups-api"&gt;
&lt;h4&gt;New address groups API&lt;/h4&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the
address_group object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable name for the address
group (255 characters limit). Does not
have to be unique.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable description for the
address group (255 characters limit).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of the address group. Only
admin users can specify a project
identifier other than their own.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;addresses&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;List&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Array of address. It supports both
CIDR and IP range objects.
An example of addresses:
[“132.168.4.12/24”,
“132.168.5.12-132.168.5.24”,
“2001::db8::f00/64”]&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="list-address-groups"&gt;
&lt;h5&gt;List address groups&lt;/h5&gt;
&lt;p&gt;Lists address groups.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/address-groups&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example List address groups: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example List address groups: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"address_groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ADDR_GP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"addresses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
               &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s2"&gt;"132.168.5.12-132.168.5.24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="show-address-group-details"&gt;
&lt;h5&gt;Show address group details&lt;/h5&gt;
&lt;p&gt;Shows address group details.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/address-groups/&amp;lt;address_group_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Not Found (404)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Show address group: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;8722e0&lt;/span&gt;&lt;span class="n"&gt;e0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;cc9&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4490&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9660&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;c9a5732fbb0&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Show address group: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"address_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ADDR_GP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"addresses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"132.168.5.12-132.168.5.24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="create-address-group"&gt;
&lt;h5&gt;Create address group&lt;/h5&gt;
&lt;p&gt;Creates an address group.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/address-groups/&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;201&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Bad Request(400)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Create address group: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"address_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ADDR_GP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"addresses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"132.168.5.12-132.168.5.24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Create address group: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"address_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ADDR_GP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"addresses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"132.168.5.12-132.168.5.24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="update-address-group"&gt;
&lt;h5&gt;Update address group&lt;/h5&gt;
&lt;p&gt;Updates an address group. To update addresses, use the add addresses and
remove addresses operations.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/address-groups/&amp;lt;address_group_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Bad Request(400) Not Found(404)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Update address group: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;8722e0&lt;/span&gt;&lt;span class="n"&gt;e0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;cc9&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4490&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9660&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;c9a5732fbb0&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"address_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"new description"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"new name"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Update address group: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"address_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"new description"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"new name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"addresses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"132.168.5.12-132.168.5.24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="add-addresses-to-address-group"&gt;
&lt;h5&gt;Add addresses to address group&lt;/h5&gt;
&lt;p&gt;Add addresses to an existing address group.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/address-groups/&amp;lt;address_group_id&amp;gt;/add_addresses&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Bad Request(400), Not Found(404)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Update addresses: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;8722e0&lt;/span&gt;&lt;span class="n"&gt;e0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;cc9&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4490&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9660&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;c9a5732fbb0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;add_addresses&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"addresses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
       &lt;span class="s2"&gt;"10.0.0.1/32"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s2"&gt;"2001:3889:120:fe42::/64"&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Update addresses: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"address_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ADDR_GP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"addresses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"132.168.5.12-132.168.5.24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"10.0.0.1/32"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"2001:3889:120:fe42::/64"&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="remove-addresses-from-address-group"&gt;
&lt;h5&gt;Remove addresses from address group&lt;/h5&gt;
&lt;p&gt;Remove addresses from an existing address group.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/address-groups/&amp;lt;address_group_id&amp;gt;/remove_addresses&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Bad Request(400), Not Found(404)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Remove addresses: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;8722e0&lt;/span&gt;&lt;span class="n"&gt;e0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;cc9&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4490&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9660&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;c9a5732fbb0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;remove_addresses&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"addresses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
       &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Remove addresses: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"address_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ADDR_GP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"addresses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="s2"&gt;"132.168.5.12-132.168.5.24"&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="delete-address-group"&gt;
&lt;h5&gt;Delete address group&lt;/h5&gt;
&lt;p&gt;Deletes an address group.&lt;/p&gt;
&lt;p&gt;This operation does not return a response body.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DELETE&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/address-groups/&amp;lt;address_group_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;204&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Not Found(404)
Conflict(409) The Conflict error response
is returned when an operation is
performed while address group is in use.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Delete address group: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;8722e0&lt;/span&gt;&lt;span class="n"&gt;e0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;cc9&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4490&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9660&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;c9a5732fbb0&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Delete address group: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="changes-to-the-existing-security-group-rules-api"&gt;
&lt;h4&gt;Changes to the existing security group rules API&lt;/h4&gt;
&lt;section id="list-security-group-rules"&gt;
&lt;h5&gt;List security group rules&lt;/h5&gt;
&lt;p&gt;Lists security group rules.&lt;/p&gt;
&lt;p&gt;Remote address group id field will be added to response.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;security&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rules&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example List security group rules: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"security_group_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ingress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"ethertype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"IPv4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"f7d45c89-008e-4bab-88ad-d6811724c51c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"port_range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"port_range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"remote_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"remote_ip_prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"remote_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"security_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"85cc3048-abc3-43cc-89b3-377341426ac5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"e4f50856753b4dc6afee5fa6b9b6c550"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"revision_number"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2018-03-19T19:16:56Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2018-03-19T19:16:56Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"e4f50856753b4dc6afee5fa6b9b6c550"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="show-security-group-rule-details"&gt;
&lt;h5&gt;Show security group rule details&lt;/h5&gt;
&lt;p&gt;Shows security group rule details.&lt;/p&gt;
&lt;p&gt;Remote address group id field will be added to response.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example Show security group rule: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;security&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;f7d45c89&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;008e-4&lt;/span&gt;&lt;span class="n"&gt;bab&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="n"&gt;ad&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;d6811724c51c&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Show security group rule: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"security_group_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ingress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ethertype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"IPv4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"f7d45c89-008e-4bab-88ad-d6811724c51c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"port_range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"port_range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"remote_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"remote_ip_prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"remote_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"security_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"85cc3048-abc3-43cc-89b3-377341426ac5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"e4f50856753b4dc6afee5fa6b9b6c550"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"revision_number"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2018-03-19T19:16:56Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2018-03-19T19:16:56Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"e4f50856753b4dc6afee5fa6b9b6c550"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="create-security-group-rule"&gt;
&lt;h5&gt;Create security group rule&lt;/h5&gt;
&lt;p&gt;Creates a security group rule with a remote address group.&lt;/p&gt;
&lt;p&gt;Note: At most one of remote-group, remote-ip and remote-address-group can be
specified. The rule is matched when the remote IP address in the packet matches
any one of: remote_ip_address, one of the IP addresses in the address group,
or an IP address of one of the ports in the remote security group.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example Create security group rule: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;security&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rules&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"security_group_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ingress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"port_range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"80"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ethertype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"IPv4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"port_range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"80"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"remote_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"security_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"a7734e61-b545-452d-a3cd-0189cbd9747a"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Create security group rule: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"security_group_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ingress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ethertype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"IPv4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2bc0accf-312e-429a-956e-e4407625eb62"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"port_range_max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"port_range_min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"remote_ip_prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"remote_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"remote_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"security_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"a7734e61-b545-452d-a3cd-0189cbd9747a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"e4f50856753b4dc6afee5fa6b9b6c550"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"revision_number"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"e4f50856753b4dc6afee5fa6b9b6c550"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2018-03-19T19:16:56Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2018-03-19T19:16:56Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;The following are the backend database tables for the REST API proposed above.&lt;/p&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;strong&gt;Address Groups&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the
address_group object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable name for the address
group (255 characters limit). Does not
have to be unique.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable description for the
address group (255 characters limit).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of the address group. Only
admin users can specify a project
identifier other than their own.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;strong&gt;Address Group Address Associations&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;address_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID of address group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;address&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Address that has to be associated to
the address group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;strong&gt;Security Group Rules&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Attribute remote_address_group_id will be added to security group rules table&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;remote_address
_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When a remote_address_group is
specified, it is matched when the
remote IP address in the packet
matches one of the IP addresses in
the address group. This is exclusive
with remote_ip_prefix and
remote_group_id.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Hang Yang&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;REST API update&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB schema update&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI update&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open vSwitch and iptables firewall drivers update&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RBAC support for address groups&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation update&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DB mixin and schema tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New tests need to be written&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;REST API and attributes validation tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron CLI and API documentation have to be modified.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron API devref and documentation need to be updated.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/rocky/fwaas-2.0-address-groups-support.html"&gt;https://specs.openstack.org/openstack/neutron-specs/specs/rocky/fwaas-2.0-address-groups-support.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[2] &lt;a class="reference external" href="https://docs.openstack.org/api-ref/network/v2/#security-group-rules-security-group-rules"&gt;https://docs.openstack.org/api-ref/network/v2/#security-group-rules-security-group-rules&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 20 Apr 2020 00:00:00 </pubDate></item><item><title>Integration of Neutron Classifier and QoS DSCP</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/ussuri/qos_classifier.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1476527"&gt;https://bugs.launchpad.net/neutron/+bug/1476527&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron Classifier(NC) is a service plugin which provides an API to define
traffic classes for consumption by other Neutron services.&lt;/p&gt;
&lt;p&gt;Quality of service(QoS) is an OpenStack Neutron extension which provides
administrators with a service to specify and enforce SLAs based on
drop priority, bandwidth policing and bandwidth guarantees at a port level.&lt;/p&gt;
&lt;p&gt;By introducing the consumption of NC’s Classification Group resources
into QoS’s Rule resources we can allow for a more targeted form of SLA
allowing admins to limit, prioritize or guarantee traffic based on
traffic classes rather than on a Neutron Port level. This spec
will focus on drop priority based on traffic class per port.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Neutron’s Quality of Service extension allows for SLAs to be enforced at a
Neutron port level, however it does not provide a resource to allow
administrators to define SLAs for the different traffic classes entering or
leaving the port.&lt;/p&gt;
&lt;p&gt;This results in an all or nothing approach to traffic class SLAs, either
all the traffic leaving a port recieves the same DSCP mark or the traffic
retains its default DSCP mark assigned by the workload.&lt;/p&gt;
&lt;p&gt;Example Use Cases:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Assigning a higher drop priority for traffic leaving TCP port YY
than other traffic leaving the Neutron port.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Overriding an existing DSCP mark assigned by the instance destined for
IPv6 address XX with UDP port YY specifically.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;In order to consume the classification resources of the Neutron Classifier
in a way that does not involve the introduction of external dependencies
in Neutron, the Neutron Classifier service plugin will require it to be
migrated into the core Neutron repository.&lt;/p&gt;
&lt;p&gt;Details of the resource models and API can be found here ‘NC API spec’_&lt;/p&gt;
&lt;p&gt;The modifications required to Neutron’s QoS extension is minimal,
it involves the introduction of a two variables to the DSCP Marking rule.
The first variable takes an ID for a classification group (a collection of
individual classifications) which the QoS backends can consume to target
DSCP Marks to traffic classes as opposed to marking all traffic leaving
the port.&lt;/p&gt;
&lt;p&gt;The other, a priority value, will be a positive integer ranging from 0-1000
in ascending priority. This will allow admins to decide which DSCP marking
rules should be applied in a case where 2 DSPC rule classifications overlap.
eg:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;example_policy&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt; &lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;example_policy&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="n"&gt;dscp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;marking&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;dscp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mark&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;ethernet&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;ethertype&lt;/span&gt; &lt;span class="mh"&gt;0x0800&lt;/span&gt; \
    &lt;span class="n"&gt;eth_ipv4&lt;/span&gt;
&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;ipv4&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;protocol&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; \
    &lt;span class="n"&gt;ipv4_tcp&lt;/span&gt;
&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;tcp&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;max&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt; \
    &lt;span class="n"&gt;tcp_80&lt;/span&gt;
&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;class_1&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="n"&gt;tcp_80&lt;/span&gt; &lt;span class="n"&gt;ipv4_tcp&lt;/span&gt; &lt;span class="n"&gt;eth_ipv4&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt; &lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;example_policy&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="n"&gt;dscp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;marking&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;dscp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mark&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;classification&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="n"&gt;class_1&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;classification&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;priority&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;ipv4&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.5&lt;/span&gt; \
    &lt;span class="n"&gt;ipv4_dst&lt;/span&gt;
&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;class_2&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="n"&gt;ipv4_dst&lt;/span&gt; &lt;span class="n"&gt;eth_ipv4&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt; &lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;example_policy&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="n"&gt;dscp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;marking&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;dscp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mark&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;classification&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="n"&gt;class_2&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;classification&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;priority&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;ethernet&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;ethertype&lt;/span&gt; &lt;span class="mh"&gt;0x86DD&lt;/span&gt; \
    &lt;span class="n"&gt;eth_ipv6&lt;/span&gt;
&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;ipv6&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ffff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;a00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="n"&gt;ipv6_dst&lt;/span&gt;
&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;udp&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;max&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt; \
    &lt;span class="n"&gt;udp_21&lt;/span&gt;
&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;class_3&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="n"&gt;eth_ipv6&lt;/span&gt; &lt;span class="n"&gt;ipv6_dst&lt;/span&gt; &lt;span class="n"&gt;udp_21&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt; &lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;example_policy&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="n"&gt;dscp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;marking&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;dscp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mark&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;classification&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="n"&gt;class_3&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;classification&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;priority&lt;/span&gt; &lt;span class="mi"&gt;158&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;ethernet&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;ethertype&lt;/span&gt; &lt;span class="mh"&gt;0x0806&lt;/span&gt; \
    &lt;span class="n"&gt;eth_arp&lt;/span&gt;
&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;class_4&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="n"&gt;eth_arp&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt; &lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;example_policy&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="n"&gt;dscp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;marking&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;dscp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mark&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;classification&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="n"&gt;class_4&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;classification&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;priority&lt;/span&gt; &lt;span class="mi"&gt;999&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt; &lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="n"&gt;example_policy&lt;/span&gt;
&lt;span class="o"&gt;+--------------------------------------+--------------------------------------+--------------+----------+-----------------+----------+-----------+-----------+--------------------------------------+----------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt;                                   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;QoS&lt;/span&gt; &lt;span class="n"&gt;Policy&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Max&lt;/span&gt; &lt;span class="n"&gt;Kbps&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Max&lt;/span&gt; &lt;span class="n"&gt;Burst&lt;/span&gt; &lt;span class="n"&gt;Kbits&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Min&lt;/span&gt; &lt;span class="n"&gt;Kbps&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;DSCP&lt;/span&gt; &lt;span class="n"&gt;mark&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Direction&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Classification&lt;/span&gt; &lt;span class="n"&gt;Group&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Priority&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------------------------------+--------------------------------------+--------------+----------+-----------------+----------+-----------+-----------+--------------------------------------+----------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mf"&gt;153e4957&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;c50&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="n"&gt;f5&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b934&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c30eb3ada180&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;812&lt;/span&gt;&lt;span class="n"&gt;c3e2e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cc86&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4842&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b41b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="n"&gt;b69419a123b&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;dscp_marking&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="mi"&gt;40&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ae0de79d&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c26a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4090&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;ec2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;d1ae62797f2&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="mi"&gt;999&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;184&lt;/span&gt;&lt;span class="n"&gt;d7156&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ab93&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;444e-96&lt;/span&gt;&lt;span class="n"&gt;eb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;f91cf8c9160e&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;812&lt;/span&gt;&lt;span class="n"&gt;c3e2e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cc86&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4842&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b41b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="n"&gt;b69419a123b&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;dscp_marking&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;b0fd0ca7&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8596&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4053&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b69b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;630016&lt;/span&gt;&lt;span class="n"&gt;acfd28&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="mi"&gt;158&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;385970&lt;/span&gt;&lt;span class="n"&gt;f8&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;a6c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;fe2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a328&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;95630138&lt;/span&gt;&lt;span class="n"&gt;c9ca&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;812&lt;/span&gt;&lt;span class="n"&gt;c3e2e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cc86&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4842&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b41b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="n"&gt;b69419a123b&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;dscp_marking&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="n"&gt;adb4199&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;e42f&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;fa9&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;ab6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;bf64e2ea68d&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="n"&gt;fa581ac&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;b82&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;d64&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9032&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="n"&gt;b1ce9f3509&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;812&lt;/span&gt;&lt;span class="n"&gt;c3e2e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cc86&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4842&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b41b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="n"&gt;b69419a123b&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;dscp_marking&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="mi"&gt;22&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;                                      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;d1c5268b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;302&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;498&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bfd7&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;484e19&lt;/span&gt;&lt;span class="n"&gt;fd28af&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;812&lt;/span&gt;&lt;span class="n"&gt;c3e2e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cc86&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4842&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b41b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="n"&gt;b69419a123b&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;dscp_marking&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;cd0a1ea2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;cdf&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="n"&gt;b0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a4fc&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="n"&gt;f581d4a4be2&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="mi"&gt;600&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------------------------------+--------------------------------------+--------------+----------+-----------------+----------+-----------+-----------+--------------------------------------+----------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Without a clear priority between the above classes there are instances where
classes class_1, class_3, class_4 and class_5 will also match class_2.
Depending on the backend this can result in unpredictible behavior without
a clear prioritization mechanism between traffic classes.&lt;/p&gt;
&lt;p&gt;To accomodate these changes, modifications will need to be made in the
backend to allow drivers to retrieve the classification definitions from
the service plugin. This will be achieved through the extension of the
agent extensions API. By extending this API all extensions will have
access to classifications without having to introduce any additional
resources.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;In order to provide consistent functionality on upgrade the
classification_group_id defaults to None, meaning a DSCP marking rule
will behave the same way it did before the introduction of this feature.&lt;/p&gt;
&lt;p&gt;The proposed change would result in the model looking like this:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;QoSRule
identifier&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;qos_policy_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;QoSPolicy
reference UUID&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;dscp_mark&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer
(enum)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, tenant&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0 and 56, except
2-6, 42, 44, and
50-54&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;DSCP Mark&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;classification_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, tenant&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Classification
Group
reference UUID&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;classification_priority&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, tenant&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A positive
integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Positive integer
to denote prioity
of this rule&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Another modification is the removal of the of the unique contraint on the
qos_policy_id. This has been replaced by a unique constraint on the
qos_policy_id and classification_group_id as a tuple.
This is to allow multiple DSCP rules with different classifications within
the same policy, this includes when the classification_group_id is None.
As a result, a QosPolicy can only have a single DSCPMarkingRule with
classification_group_id set to None.&lt;/p&gt;
&lt;p&gt;Neutron DB table: QosDSCPMarkingRule&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;id: primary key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;qos_policy_id: foreign key to QosPolicy.id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;dscp_mark: Integer within a defined set of values.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;classification_group_id: foreign key to ClassificationGroup.id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;classification_priority: positive integer between 0 and 1000&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Before delving into further detail in regards to the data model, API and how
classifications can be used, a few points need to be clarified:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;1 Classification is of a single type, e.g. either Ethernet, IP, HTTP,
or another supported at the time of a specific CCF release. The definition,
i.e. fields to match on, depends on the type specified.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To clarify, Classification Types define the set of possible fields and values
for a Classification (essentially, an instance of that Classification Type).
Classification Types are defined in code, where Classifications are created
via the REST API as instances of those types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Not all supported fields need to be defined - only the ones
required by the Consuming Service - which it should validate on consumption.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are also Classification Groups, which allow Classifications or other
Classification Groups to be grouped together using boolean operators. CGs
are the resources that will end up being consumed by Consuming Services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the Consuming Service’s point of view, Classifications can only be read,
not created or deleted. They need to have been previously
created using the User-facing Classifications API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As Neutron Classifier is unable to force an update action to it’s
consumers and as users may be unaware of all the consumers of a
classification, the classification “definition” and “type” fields and the
classification group “classifications”, “classification_groups” and
“operator” fields cannot be updated after creation.
ie.
A classification is consumed by both QoS and Security Groups with
a user only knowing about QoS consuming the classification.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The initial model of the CCF will include the following Classification Types:
Ethernet, IPv4, IPv6, TCP and UDP, which when combined are sufficient
to provide any 5-tuple classification.&lt;/p&gt;
&lt;p&gt;The following table presents the attributes of a Classification Group
(asterisk on RW means that the attribute is non-updatable):&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access
CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO,
all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;from auth
token&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Project ID&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Name of Classification Group&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human-readable description&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;shared&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;False&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;boolean&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Shared with other projects&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;operator&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(values)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW*,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;“and”&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;[“and”,&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;“or”]&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Boolean connective: AND/OR&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;classification_groups&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW*,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[]&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;List of Classification
Groups included&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;classifications&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW*
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[]&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;List of Classifications
included&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Consuming Services will consume Classification Groups, and not atomic
Classifications, any Classification needs to be grouped in a Classification
Group to be consumed individually. As such, the “operator” field is to be
ignored for Classification Groups that only contain 1 Classification inside.&lt;/p&gt;
&lt;p&gt;The following table presents the attributes of Classifications
of any of the types stated in this spec
(asterisk on RW means that the attribute is non-updatable):&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO,
all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;from auth
token&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Project ID&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Name of Classification&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human-readable description&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW*,
project&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;from enum
of types&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The type of the
Classification&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;definition&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="5"&gt;&lt;p&gt;type-specific attributes will go here,
given their volume I won’t detail them unless requested.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Classification Groups and Classifications of every type will be stored as the
following tables and relationships (with table name prefix &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ccf_&lt;/span&gt;&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                          &lt;span class="o"&gt;+---------------------+&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_groups&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;+---------------------+&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;                   &lt;span class="o"&gt;|*&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;cg_id&lt;/span&gt;                &lt;span class="o"&gt;+--------+&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;               &lt;span class="o"&gt;+--------+&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;operator&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
                          &lt;span class="o"&gt;+---------------------+&lt;/span&gt;
                                      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
                                      &lt;span class="o"&gt;|&lt;/span&gt;
                                      &lt;span class="o"&gt;|*&lt;/span&gt;
                      &lt;span class="o"&gt;+------------------------------+&lt;/span&gt;
                      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_groups_mapping&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                      &lt;span class="o"&gt;+------------------------------+&lt;/span&gt;
                      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;cg_id&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;
                      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_id&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
                      &lt;span class="o"&gt;+------------------------------+&lt;/span&gt;
                                      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;+--------------------+&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;+--------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ipv4_classifications&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ipv6_classifications&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------------+&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;+--------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_id&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_id&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ihl&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;traffic_class&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;diffserv&lt;/span&gt;            &lt;span class="o"&gt;+--------+&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+--------+&lt;/span&gt;&lt;span class="n"&gt;traffic_class_mask&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;diffserv_mask&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;next_header&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;hops&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;flags_mask&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;src_addr&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ttl&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dst_addr&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;protocol&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+---------------------+&lt;/span&gt;     &lt;span class="o"&gt;+--------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;src_addr&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classifications&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dst_addr&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+---------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;options_mask&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------------+&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
                           &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
                           &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+-------------------+&lt;/span&gt;
                           &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;tcp_classifications&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
                           &lt;span class="o"&gt;+---------------------+&lt;/span&gt;     &lt;span class="o"&gt;+-------------------+&lt;/span&gt;
                             &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_id&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-------------------+&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;src_port&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;udp_classifications&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dst_port&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-------------------+&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_id&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;flags_mask&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;src_port&lt;/span&gt;           &lt;span class="o"&gt;+---------+&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+--------+&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dst_port&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;data_offset&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+------------------------+&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;option_kind&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;window_size&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ethernet_classifications&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+-------------------+&lt;/span&gt;
&lt;span class="o"&gt;+-------------------+&lt;/span&gt;     &lt;span class="o"&gt;+------------------------+&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_id&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;preamble&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;src_addr&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dst_addr&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ethertype&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;+------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Masking fields allow the user to specify which individual bits of the
respective main field should be looked up during classification.&lt;/p&gt;
&lt;p&gt;Classification Types are used to select the appropriate model of the
Classification and consequently what table it will be stored in.&lt;/p&gt;
&lt;p&gt;Classification Groups get stored in a single table and can point to other
Classification Groups, to allow mixing boolean operators.&lt;/p&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;operator&lt;/span&gt;&lt;/code&gt; in Classification Group: specifies the boolean operator used
to connect all the child Classifications and Classification Groups of that
group. This can be either AND or OR.&lt;/p&gt;
&lt;p&gt;OR: Logical OR, the classifications contained in these groups are
inter-changable within the traffic class ie.
ipv4 dst_addr y.y.y.y or ipv6 dst_addr Z::ZZZZ.&lt;/p&gt;
&lt;p&gt;AND: logical AND, the classifications or classification groups are used
to create a traffic class, the composition of this classification can
be made up of Classifications or OR operand ClassificationGroups.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Proposed attribute:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;SUB_RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s1"&gt;'dscp_marking_rules'&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
        &lt;span class="s1"&gt;'parent'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'collection_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'policies'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'member_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'policy'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'parameters'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QOS_RULE_COMMON_FIELDS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'dscp_mark'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;common_constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
                            &lt;span class="n"&gt;VALID_DSCP_MARKS&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="s1"&gt;'classification_group_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="s1"&gt;'classification_priority'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Sample REST calls:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;policies&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"AF32"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;project-id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"This policy marks DSCP outgoing AF32 traffic for DTV Control"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"False"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;policies&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;tenant-id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"AF32"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"This policy marks DSCP outgoing AF32 traffic for DTV Control"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"dscp_marking_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;policy-uuid&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"dscp_mark"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"classification_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;classification_group_id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"classification_priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;
        &lt;span class="p"&gt;}]&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;policies&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;dscp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;marking&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"dscp_marking_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"dscp_mark"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"dscp_marking_rule"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;policy-uuid&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"dscp_mark"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"classification_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"classification_priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;classification_groups&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;classification_group_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"classification_group"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;classification_group_id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;project_id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ipv4-group"&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"classification"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;classification_id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"ipv4-dscp"&lt;/span&gt;
                &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;project_id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"c_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ipv4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"classification_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
        &lt;span class="s2"&gt;"operator"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"AND"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;policies&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;dscp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;marking&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"dscp_marking_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"dscp_mark"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"classification_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;classification_group_id&amp;gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"dscp_marking_rule"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;policy-uuid&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"dscp_mark"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"classification_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;classification_group_id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"classification_priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Existing &lt;a class="reference external" href="https://github.com/openstack/openstack-manuals/blob/master/doc/networking-guide/source/adv-config-qos.rs"&gt;Networking Guide&lt;/a&gt; will be updated for this feature.&lt;/p&gt;
&lt;p&gt;Existing &lt;a class="reference external" href="https://github.com/openstack/openstack-manuals/blob/master/doc/cli-reference/source/neutron.rst"&gt;CLI guide&lt;/a&gt; will be updated for this feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Existing &lt;a class="reference external" href="https://github.com/openstack/neutron/blob/master/doc/source/devref/quality_of_service.rst"&gt;QoS devref document&lt;/a&gt; will be updated for this feature.
A New Document will be drafted for the Neutron Classifier API also.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-documentation"&gt;
&lt;h3&gt;API Documentation&lt;/h3&gt;
&lt;p&gt;Existing &lt;a class="reference external" href="https://docs.openstack.org/api-ref/network/v2/#quality-of-service"&gt;QoS API documentation&lt;/a&gt; will be updated for this feature.
A New Document will be drafted for the Neutron Classifier API also.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Mon, 20 Jan 2020 00:00:00 </pubDate></item><item><title>Neutron OVS Agent Support for Baremetal with Smart NIC</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stein/neutron-ovs-agent-support-baremetal-with-smart-nic.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1785608"&gt;https://bugs.launchpad.net/neutron/+bug/1785608&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec describes proposed changes to the Neutron OVS mechanism driver and
the Neutron OVS agent to enable a generic, vendor-agnostic, baremetal
networking service running on smart NICs, enabling baremetal networking
with feature parity to the virtualization use-case.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;While Ironic today supports Neutron provisioned network connectivity for
baremetal servers through an ML2 mechanism driver, the existing support
is based largely on configuration of TORs through vendor-specific mechanism
drivers, with limited capabilities.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;There is a wide range of smart/intelligent NICs emerging on the market.
These NICs generally incorporate one or more general purpose CPU cores along
with data-plane packet processing acceleration, and can efficiently run
virtual switches such as OVS, while maintaining the existing interfaces to the
SDN layer.&lt;/p&gt;
&lt;p&gt;The proposal is to extend the Neutron OVS mechanism driver and Neutron OVS Agent
to bind the Neutron port for the baremetal host with smart NIC. This will allow
the Neutron OVS Agent to configure the pipeline of the OVS running on the
smart NIC and leverage the pipeline features such as: VXLAN, Security Groups and
ARP Responder.&lt;/p&gt;
&lt;p&gt;This spec is complementary to the Ironic spec &lt;a class="footnote-reference brackets" href="#id3" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In this proposal, we address two use-cases:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron OVS L2 agent runs locally on the smart NIC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron OVS L2 agent(s) run remotely and manages the OVS bridges for all
the baremetal smart NICs.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Example of smart NIC model:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+---------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="n"&gt;baremetal&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+-----------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;OS&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+------|--------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+------|--------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;OS&lt;/span&gt; &lt;span class="n"&gt;SmartNIC&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;+-+&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;-+&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;OVS&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;+-+&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;-+&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+------|--------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------|------------+&lt;/span&gt;
         &lt;span class="o"&gt;|&lt;/span&gt;

&lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;baremetal&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="n"&gt;represents&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;baremetal&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;smart&lt;/span&gt; &lt;span class="n"&gt;NIC&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="n"&gt;represents&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;physical&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;smart&lt;/span&gt; &lt;span class="n"&gt;NIC&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ironic creation of Neutron Port:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Create Neutron port with new vnic_type called &lt;cite&gt;smart-nic&lt;/cite&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add local_link_information with the following attributes:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;smart NIC hostname - the hostname of server/smart NIC where the Neutron
OVS agent is running. (required)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;smart NIC port id - the port name that needs to be plugged to the
integration bridge. B in the diagram above(required)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;smart NIC SSH public key - ssh public key of the smart NIC
(required only for remote)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;smart NIC OVSDB SSL certificate - OVSDB SSL of the OVS in smart NIC
(required only remote)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron OVS ML2 Mechanism Driver:&lt;/p&gt;
&lt;p&gt;The OVS ML2 will allow binding the &lt;cite&gt;smart-nic&lt;/cite&gt; vnic_type. The rationale
for creating new vnic_type and not using the barmetal one is that there is a
wide range of mechanism drivers that use hierarchical port binding for
configuring TOR switches and we want to allow this to work with smart NICs.
for example mechanism_drivers=cisco_nexus,openvswitch&lt;/p&gt;
&lt;p&gt;The OVS ML2 mechanism driver will determine if the Neutron OVS Agent runs
locally or remotely based on smart NIC configuration passed from ironic as
described above.&lt;/p&gt;
&lt;p&gt;In case the Neutron OVS L2 agent runs locally on the smart NIC the OVS
mechanism driver will locate the Neutron OVS agent by the smart
NIC hostname attribute. For the remote case the changes are captured
in this neutron spec &lt;a class="footnote-reference brackets" href="#id4" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron OVS Agent:&lt;/p&gt;
&lt;p&gt;Extend the port_update rpc method as following:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;port_update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'port'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# get the port data from cache&lt;/span&gt;
  &lt;span class="n"&gt;port_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plugin_rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remote_resource_cache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; \
          &lt;span class="n"&gt;get_resource_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="c1"&gt;# if smart-nic port add it to updated_smart_nic_ports with&lt;/span&gt;
  &lt;span class="c1"&gt;# the required information for adding the port to OVSDB&lt;/span&gt;
  &lt;span class="n"&gt;port_binding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;port_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'bindings'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;port_binding&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'vnic_type'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'smart-nic'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;ifname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;smart_nic_port_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'port_binding'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'profile'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; \
              &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'local_link_information'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'port_id'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
          &lt;span class="n"&gt;mac&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;port_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'mac_address'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
          &lt;span class="n"&gt;node_uuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;port_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'device_id'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
          &lt;span class="n"&gt;port_binding&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'vif_type'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vif_type&lt;/span&gt;
          &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;updated_smart_nic_ports&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                          &lt;span class="s1"&gt;'mac'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mac&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="s1"&gt;'node_uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;node_uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="s1"&gt;'iface_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                          &lt;span class="s1"&gt;'iface_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ifname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="s1"&gt;'vif_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;vif_type&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;updated_ports&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When Neutron processes the ports the Neutron OVS agent will add the
smart NIC port(s) to the OVSDB by ovs plugin in os-vif.&lt;/p&gt;
&lt;p&gt;Because RPC is not reliable we need to extend the full sync to do the following:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;when sync is True we will retrieve all the smart-nic ports for this agent.
This requires to add another RPC call.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will compare the retrieved smart-nic ports for the Neutron server to the
existing smart-nic port on the integration bridge.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;if the smart-nic port is only on the Neutron server we will add it to
the added list in the port_info.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;if the smart-nic port is only on the integration bridge we will add it
to the removed list in the port_info.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/582767/"&gt;https://review.openstack.org/#/c/582767/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/595402/"&gt;https://review.openstack.org/#/c/595402/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 19 Nov 2019 00:00:00 </pubDate></item><item><title>Allow user to create default record on port creation from shared network</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/ussuri/allow-user-to-create-default-record-on-port-creation-from-shared-network.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1843218"&gt;https://bugs.launchpad.net/neutron/+bug/1843218&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As discussed in the bug thread above, we could add the feature to allow a user
to have default zone configured on a shared network.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;On Neutron, when the DNS ML2 plugin is enabled, each user can manage their own network, and
configure a dns_domain (i.e. example.com) for that network. The dns_domain (called zone) can
be hosted in one and only one tenant. To create a record in a zone, the record’s tenant must be
the same as the zone’s tenant. If a user creates a port in that network, it has to be the same
tenant as zone to get the record created.&lt;/p&gt;
&lt;p&gt;Network (A project) &amp;lt;~~&amp;gt; Port (B project) &amp;lt;==&amp;gt; Zone (B project) &amp;lt;==&amp;gt; Record (B project)&lt;/p&gt;
&lt;p&gt;So we need to have all these resources hosted on the same project (port, zone and record) to
get this feature working.&lt;/p&gt;
&lt;p&gt;As ports are able to be created from several different projects in the case of a shared
network, this feature doesn’t work for that case.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;As described in the RFE, the idea is to let the network’s admin user configure keywords in
the default dns_domain on their network to allow zone to be different per user or per project.&lt;/p&gt;
&lt;p&gt;Here are the accepted keywords :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;project_id&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;project_name&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;user_name&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;user_id&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For instance, configuring &amp;lt;user_name&amp;gt;.&amp;lt;project_id&amp;gt;.example.com. as dns_domain on any
network will allow users to have one default zone per user and per project, and then be able
to create records.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ source openrc_admin
$ openstack network set --dns-domain "&amp;lt;user_name&amp;gt;.&amp;lt;project_id&amp;gt;.example.com." shared
$ source openrc_demo
$ openstack zone create --email dnsmaster@defaultzone.com UserName.HisProjectId.example.com.
$ openstack port create --dns-name myport port
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Further changes included:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Documentation: api-ref.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;neutron-lib adaptation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;neutron dns_integration ML2 driver adaptation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;dns_integration unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;dns_integration integration tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="planned-impact"&gt;
&lt;h3&gt;Planned Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;No impact expected on upgrades.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No impact expected on configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No breaking changes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;RFE bug report of this spec: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1843218"&gt;https://bugs.launchpad.net/neutron/+bug/1843218&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron Drivers Meeting discussion about the feature validation : &lt;a class="reference external" href="http://eavesdrop.openstack.org/meetings/neutron_drivers/2019/neutron_drivers.2019-10-04-14.00.log.html#l-171"&gt;http://eavesdrop.openstack.org/meetings/neutron_drivers/2019/neutron_drivers.2019-10-04-14.00.log.html#l-171&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 09 Oct 2019 00:00:00 </pubDate></item><item><title>Improve Extraroute API</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/train/improve-extraroute-api.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1826396"&gt;https://bugs.launchpad.net/neutron/+bug/1826396&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As discussed in an &lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-discuss/2019-April/005121.html"&gt;openstack-discuss thread&lt;/a&gt;
we could improve the extraroute API to better support Neutron API clients,
especially Heat.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The first problem is that the current extraroute API does
not allow atomic additions/deletions of particular routing
table entries. In the current API the routes attribute of a
router (containing all routing table entries) &lt;a class="reference external" href="https://developer.openstack.org/api-ref/network/v2/?expanded=update-router-detail#update-router"&gt;must be updated at once&lt;/a&gt;.
Therefore additions and deletions must be performed on the client
side. Therefore multiple clients race to update the routes attribute
and updates may get lost.&lt;/p&gt;
&lt;p&gt;This problem can be easily (but nondeterministically) reproduced by a
&lt;a class="reference external" href="#extraroute-concurrent-yaml"&gt;simple HOT template as included in the References section below&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ openstack stack create --wait -t extraroute-concurrent.yaml stack0
$ openstack stack resource list stack0 --filter name=router0 -f value -c physical_resource_id \
  | xargs -r openstack router show -f value -c routes
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The second problem perceived by programmatic users of the Neutron API
is that the ownership of extra routes cannot be expressed because they
don’t have unique identifiers. For example consider two Heat stacks
(or any other user of Neutron’s API) needing and therefore creating
the same extra route. When one of them is deleted the extra route gets
deleted for both unless we have a way to track multiple needs for the
same extra route. Since addressing the second problem would involve
changing the conceptual abstraction of an extra route this problem is
not addressed in this specification.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This RFE proposes to expose the extraroute functionality of Neutron in a
new way beyond the current ‘routes’ attribute of routers.&lt;/p&gt;
&lt;p&gt;Introduce a new API extension: extraroutes-atomic&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;routers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;add_extraroutes&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"router"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"routes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"179.24.1.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"nexthop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"172.24.3.99"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"router"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"1ecae6b8-be64-11e9-98ba-733d5460217b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"router1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"routes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"179.24.1.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"nexthop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"172.24.3.99"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;routers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;remove_extraroutes&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"router"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"routes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"179.24.1.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"nexthop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"172.24.3.99"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"router"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"1ecae6b8-be64-11e9-98ba-733d5460217b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"router1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"routes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;remaining&lt;/span&gt; &lt;span class="n"&gt;routes&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Partial failures are not allowed. If the addition or removal of any routing
table entry fails then the whole update is reverted.&lt;/p&gt;
&lt;p&gt;If a routing table entry to be added (removed) is already present (missing)
that is not an error, but considered a successful update.&lt;/p&gt;
&lt;p&gt;Handling of duplicate and overlapping routes is not changed from the
current behavior. That is exact duplicates are rejected, but overlapping
routes are allowed.&lt;/p&gt;
&lt;p&gt;Deleting a router cascades to deleting all extra routes of that router.&lt;/p&gt;
&lt;p&gt;The DB and OVO layer in Neutron is ready for this change, the routes
attribute is is already de-composed to its own table:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="n"&gt;routerroutes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;+-------------+-------------+------+-----+---------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Default&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Extra&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-------------+-------------+------+-----+---------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;destination&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NO&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;PRI&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;nexthop&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NO&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;PRI&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;router_id&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NO&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;PRI&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-------------+-------------+------+-----+---------+-------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Further changes included:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Documentation: api-ref.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest test in neutron-tempest-plugin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adapt python-neutronclient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adapt openstackclient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adapt openstacksdk.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I also hope to improve Heat’s OS::Neutron::Extraroute resource building
on this work, but that will be described in its own Heat blueprint.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="deprecations"&gt;
&lt;h3&gt;Deprecations&lt;/h3&gt;
&lt;p&gt;As soon as the new API is merged direct updates to the ‘routes’ attribute
of a router are deprecated, but keeping in line with the long standing
Neutron tradition of not making backward incompatible API changes the
old extraroutes extension is &lt;em&gt;not&lt;/em&gt; removed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-impact"&gt;
&lt;h3&gt;Other Impact&lt;/h3&gt;
&lt;p&gt;No impact expected on upgrades.
No impact expected on configuration.
No impact expected on RPC.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;section id="compare-and-swap"&gt;
&lt;h4&gt;Compare and Swap&lt;/h4&gt;
&lt;p&gt;Neutron has &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1703234"&gt;compare-and-swap API update logic&lt;/a&gt;. However using that
to solve this problem is awkward on the client side (retry until success
if the routes attibute change while the client edited it). Plus as the
number of racing clients grow use of the compare-and-swap API is going
to generate unnecessary load on API as update requests must be thrown
away and retried.&lt;/p&gt;
&lt;p&gt;Additionally current client code bases do not have support built in for
compare-and-swap operations.&lt;/p&gt;
&lt;p&gt;For other alternatives please see the review discussion of this specification.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;RFE bug report of this spec: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1826396"&gt;https://bugs.launchpad.net/neutron/+bug/1826396&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Heat story to consume the API proposed here: &lt;a class="reference external" href="https://storyboard.openstack.org/#!/story/2005522"&gt;https://storyboard.openstack.org/#!/story/2005522&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="extraroute-concurrent-yaml"&gt;
&lt;h3&gt;extraroute-concurrent.yaml&lt;/h3&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;extraroute&lt;/span&gt; &lt;span class="n"&gt;concurrency&lt;/span&gt;
&lt;span class="n"&gt;heat_template_version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2015&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;

&lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

  &lt;span class="n"&gt;net0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OS&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Net&lt;/span&gt;

  &lt;span class="n"&gt;subnet0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OS&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Subnet&lt;/span&gt;
    &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get_resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;net0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;cidr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;

  &lt;span class="n"&gt;router0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OS&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Router&lt;/span&gt;

  &lt;span class="n"&gt;routerinterface0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OS&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;RouterInterface&lt;/span&gt;
    &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get_resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;router0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;subnet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get_resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;subnet0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;extraroute0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OS&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ExtraRoute&lt;/span&gt;
    &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.1.0.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;
      &lt;span class="n"&gt;nexthop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.10&lt;/span&gt;
      &lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get_resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;router0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;extraroute1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OS&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ExtraRoute&lt;/span&gt;
    &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.1.1.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;
      &lt;span class="n"&gt;nexthop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.11&lt;/span&gt;
      &lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get_resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;router0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;extraroute2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OS&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ExtraRoute&lt;/span&gt;
    &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.1.2.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;
      &lt;span class="n"&gt;nexthop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.12&lt;/span&gt;
      &lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get_resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;router0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;extraroute3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OS&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ExtraRoute&lt;/span&gt;
    &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.1.3.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;
      &lt;span class="n"&gt;nexthop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.13&lt;/span&gt;
      &lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get_resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;router0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;extraroute4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OS&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ExtraRoute&lt;/span&gt;
    &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.1.4.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;
      &lt;span class="n"&gt;nexthop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.14&lt;/span&gt;
      &lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get_resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;router0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;extraroute5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OS&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ExtraRoute&lt;/span&gt;
    &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.1.5.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;
      &lt;span class="n"&gt;nexthop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.15&lt;/span&gt;
      &lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get_resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;router0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;extraroute6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OS&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ExtraRoute&lt;/span&gt;
    &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.1.6.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;
      &lt;span class="n"&gt;nexthop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.16&lt;/span&gt;
      &lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get_resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;router0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;extraroute7&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OS&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ExtraRoute&lt;/span&gt;
    &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.1.7.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;
      &lt;span class="n"&gt;nexthop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.17&lt;/span&gt;
      &lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get_resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;router0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;extraroute8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OS&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ExtraRoute&lt;/span&gt;
    &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.1.8.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;
      &lt;span class="n"&gt;nexthop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.18&lt;/span&gt;
      &lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get_resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;router0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;extraroute9&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OS&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ExtraRoute&lt;/span&gt;
    &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.1.9.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;
      &lt;span class="n"&gt;nexthop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.19&lt;/span&gt;
      &lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get_resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;router0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Wed, 14 Aug 2019 00:00:00 </pubDate></item><item><title>API Support for Managing Custom Ethertypes</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/train/custom_ethertypes.html</link><description>

&lt;p&gt;Some operators need to allow/deny custom Ethertypes for applications which use
their own non-IP traffic (such as for clustering applications). The Security
Group API only handles specifying behavior within the IP protocol. With the
firewall reference implementation (OVS Firewall) anything other than IPv4 and
IPv6 is subject to the default deny. This means OpenStack customers have no
options to use OpenStack to permit protocols that use separate ethertypes like
InfiniBand and FCoE.&lt;/p&gt;
&lt;p&gt;This specification proposes adding to the Security Group API the capability to
specify standard security group behaviors (allow, deny) for custom ethertypes,
with the aim of implementing these controls in the OVS and OVN firewalls.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The first implementation of security groups in Openstack was based on iptables,
which only controls traffic for the IPv4 or IPv6 ethertypes.  Since all
subsequent implementations have been built on the conceptual foundation of that
initial implementation, the behavior of Neutron security groups for traffic that
has other ethertypes has been undefined.&lt;/p&gt;
&lt;p&gt;In the case of the OVS Firewall driver, the behavior is for traffic with non-IP
ethertypes to fall through to the default deny action.  A flow could be added by
an operator to permit this traffic, but it would be removed the next time the
neutron-openvswitch-agent restarted.  This is a runtime requirement, so
deployment time tools like TripleO or Ansible are unable to handle it.&lt;/p&gt;
&lt;p&gt;Use case: Customer is running an application using InfiniBand (ethertype 0x4008)
in OpenStack, and that OpenStack transitions from iptables_hybrid to OVS
firewall. The Infiniband traffic is blocked by the OVS firewall, and at present
the Neutron API offers no methodology to unblock it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The best solution is a new API extension that makes Neutron aware of permitted
ethertypes and adjust OVS firewall rules appropriately.  The current security
group APIs take an ethertype option, which is constrained to IPv4 and IPv6;
implementing this spec will lift that restriction, so that additional security
types can be specified by hexadecimal number.  If a non-IP ethertype is
specified then the following arguments are ignored: protocol, port_range_max,
port_range_min, remote_group_id, remote_ip_prefix.&lt;/p&gt;
&lt;p&gt;Control for traffic with a custom ethertype will be all or nothing, a given
protocol will be either entirely blocked or entirely allowed.&lt;/p&gt;
&lt;p&gt;The ‘ethertype’ field of a SecurityGroupRule object is of type EtherTypeEnumField
which is an enum of the VALID_ETHERTYPES constant; this would need to be altered
to be a two octet hexadecimal number between 0x0000 and 0xffff.  The security
group rule database field for ethertypes is a String(40), so no modification is
needed.  A validator validate_ethertype is suggested, which would also replace
use of sg_supported_ethertypes in the security group extension.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;RFE bug report of this spec: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1832758"&gt;https://bugs.launchpad.net/neutron/+bug/1832758&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Fri, 28 Jun 2019 00:00:00 </pubDate></item><item><title>Toward Convergence of ML2+OVS+DVR and OVN</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/ussuri/ml2ovs-ovn-convergence.html</link><description>

&lt;p&gt;Launchpad Bug:
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1828607"&gt;https://bugs.launchpad.net/neutron/+bug/1828607&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In its current state, DVR lacks some functionality that would be of benefit to
operators. When looking at ways to address these items, it has become
apparent there is substantial overlap in functionality between the desired
state of DVR on ML2+OVS and OVN. This spec is meant to outline the areas of
overlap and the areas where either OVN or ML2+OVS+DVR are lacking
functionality, then describe a plan for converging these 2 solutions.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;In its current state, ML2+OVS+DVR has the following gaps:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Control plane scalability when handling both large numbers of ports and
when large numbers of nodes participate in the neutron deployment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support for distributed ingress/egress when using IPv6 in conjunction with
BGP and/or neutron-dynamic-routing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DVR cannot be cleanly offloaded with smart-NIC technology or user-space
tools due to its use of linux namespaces.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition to the above shortcomings, DVR would also benefit from the
following enhancements:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Support for running without network nodes if an operator chooses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support for distributed DHCP (local DHCP responder) &lt;a class="footnote-reference brackets" href="#id19" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support for distributed SNAT&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When looking at enhancing control plane scalability, distributed DHCP, and
pushing all forwarding policy into OVS for potential hardware offload, it
has been noted that OVN already implements many of these things.  OVN also
lacks some functionality that ML2+OVS+DVR has such as fully-distributed ingress
and egress which makes it possible to route all north-south traffic directly
to the appropriate compute, bypassing a central network node.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;To address the issues previously discussed, the ML2+OVS+DVR solution will be
merged with the networking-ovn solution. As a desired end state, neutron will
have OVN as its reference ML2 plugin for OVS-based environments. This has the
following benefits:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron can take advantage of the control plane performance optimizations
OVN provides.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Removes the duplication of effort for both core neutron developers and
networking-ovn developers, and allows for cross-pollination of ideas for
addressing scale, data plane performance, and usability issues in neutron.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Aligns the community of developers supporting neutron and OVN, broadening
the potential contributor base for neutron.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For this effort to be successful and minimally disruptive to users, the
following things should be considered:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Will users actually observe better control plane scale?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Will users lose support for any use cases?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What is the migration path? How disruptive will migration be? How can it be
simplified?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following sections attempt to answer these questions and outline the
procedural and technical aspects of the convergence of ML2+OVS+DVR and
networking-ovn.&lt;/p&gt;
&lt;section id="feature-gap-analysis"&gt;
&lt;h3&gt;Feature Gap Analysis&lt;/h3&gt;
&lt;p&gt;This is a list of some of the currently known gaps between ML2/OVS and OVN.
It is not a complete list, but is enough to be used as a starting point for
implementors working on closing these gaps. A TODO list for OVN is located
at &lt;a class="footnote-reference brackets" href="#id20" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Fragmentation and Jumbo frames support&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Upstream work to support this in the OVS/OVN code has been completed,
additional work is required in the networking-ovn repository to enable it.
Change at &lt;a class="footnote-reference brackets" href="#id21" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Port forwarding&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Currently ML2/OVS supports Port Forwarding in the North/South plane.
Specific L4 Ports of the Floating IP can be directed to a specific
FixedIP:PortNumber of a VM, so that different services running in a VM
can be isolated, and can communicate with external networks easily.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This is a relatively new extension, support would need to be added to OVN.&lt;/p&gt;
&lt;p&gt;One possible way would be to use the OVN native load balancing feature.
An OVN load balancer is expressed in the OVN northbound load_balancer
table. Normally the VIP and its members are expressed as &lt;a class="footnote-reference brackets" href="#id22" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;VIP:PORT = MEMBER1:MPORT1, MEMBER2:MPORT2&lt;/p&gt;
&lt;p&gt;The same could be extended for port forwarding as:&lt;/p&gt;
&lt;p&gt;FIP:PORT = PRIVATE_IP:PRIV_PORT&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security Groups logging API&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;ML2/OVS supports a log file where security groups events are logged to be
consumed by a security entity. This allows users to have a way to check if
an instance is trying to execute restricted operations, or access
restricted ports in remote servers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This is a relatively new extension, support would need to be added to OVN.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;QoS DSCP support&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Currently ML2/OVS supports QoS DSCP tagging and egress bandwidth limiting.
Those are basic QoS features that while integrated in the OVS/OVN C core
are not integrated (or fully tested) in the neutron OVN mechanism driver.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;QoS for Layer 3 IPs&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Currently ML2/OVS supports floating IP and gateway IP bandwidth limiting
based on Linux TC. Networking-ovn has a prototype implementation &lt;a class="footnote-reference brackets" href="#id23" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; based
on the meter of openvswitch &lt;a class="footnote-reference brackets" href="#id24" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; utility, which is supported in user space
datapath only, or kernel versions 4.15+ &lt;a class="footnote-reference brackets" href="#id25" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;QoS Minimum Bandwidth support&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Currently ML2/OVS supports QoS Minimum Bandwidth limiting, but it is
not supported in OVN.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;BGP support&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Currently ML2/OVS supports making a tenant subnet routable via BGP, and
can announce host routes for both floating and fixed IP addresses.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Performance tests carried out in late 2018 showed OVN outperforming ML2/OVS
in most operations &lt;a class="footnote-reference brackets" href="#id26" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. Only creating networks and listing ports were
slower, which is mostly due to the fact that OVN creates an extra port
(for metadata) upon network creation, so the amount of ports listed for
the same rally task is 2x for the OVN case.&lt;/p&gt;
&lt;p&gt;Also, the resources utilization is lower in OVN &lt;a class="footnote-reference brackets" href="#id27" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;9&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; vs ML2/OVS
&lt;a class="footnote-reference brackets" href="#id28" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;10&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; mainly due to the lack of agents and from not using RPC.&lt;/p&gt;
&lt;p&gt;One question that has been raised is OVNs use of Geneve instead of VXLAN,
and if that introduces any performance issues. Research showed that this
is not a problem. Normally, NICs that support VXLAN also support
Geneve hardware offload. Interestingly, even in the cases where they
do not, performance was found to be better using Geneve due to other
optimizations that Geneve benefits from. More information can be found
in Russell Bryant’s blog &lt;a class="footnote-reference brackets" href="#id29" id="id11" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;11&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, who did extensive work in this space.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Migration from ML2/OVS to OVN is specific to the deployment tool being used.
Currently there is documentation on migration using TripleO at &lt;a class="footnote-reference brackets" href="#id30" id="id12" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;12&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, some
of which might be applicable to other deployment tools. Re-writing the
information into different sections - one being a generic, high-level
description of what steps are required, and the other being deployment-specific
notes, would help others when adding more tools.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Move networking-ovn code to neutron repo and treat OVN as an in-tree driver&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Moving networking-ovn into the neutron repository is the first step toward
supporting convergence.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An etherpad to track information and work items is located at &lt;a class="footnote-reference brackets" href="#id31" id="id13" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;13&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Distributed ingress/egress for IPv6&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In its current state, DVR supports distributed ingress and egress when
using IPv4. When a floating IP is in use, it can either be routed with a
/32 host route directly to the fip-xxxxx namespace on the compute node
(when using neutron-dynamic-routing) or gratutitous ARP can be sent from
the fip-xxxxx namespace for the floating IP.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When IPv6 is used, all cloud ingress and egress traffic is sent through the
centralized router. This means that traffic cannot be steered directly to
compute nodes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To address this, distributed ingress/egress (AKA “fast-exit”) would be
implemented for IPv6. This will allow IPv6 packets arriving in the
fip-xxxxx namespace to be routed through the appropriate qrouter-xxxxx
namespace on the compute node, bypassing the centralized router hosted on
a network node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is an existing RFE for this, see &lt;a class="footnote-reference brackets" href="#id32" id="id14" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;14&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support for smart-NIC or user-space offloads&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This involves pushing all DVR forwarding policy into OVS and implementing
it via OpenFlow.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As all forwarding/security policy is pushed directly to OVS, an evaluation
of what flow rules are currently being offloaded to hardware should be
done if it is possible. If possible, any rules that should be tweaked for
optimizing offload potential should be re-written to support offloading.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is an existing blueprint for openflow-based DVR in neutron, see &lt;a class="footnote-reference brackets" href="#id33" id="id15" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;15&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;,
but the proof of concept patch has been abandoned &lt;a class="footnote-reference brackets" href="#id34" id="id16" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;16&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allow for completely de-centralized operation&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This involves making it possible for operators to run their environments
without introducing the concept of network nodes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This implies support for distributed SNAT, distributed DHCP, and
distributed ingress/egress for IPv4 and IPv6.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compatibility with neutron-dynamic-routing for routing directly to tenant
networks &lt;a class="footnote-reference brackets" href="#id35" id="id17" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;17&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In a completely de-centralized deployment, a router as a logical construct
doesn’t need to be thought of as “HA” or “distributed” as it is inherently
both by virtue of being instantiated on each compute node.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Distributed SNAT&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This involves allowing SNAT to happen directly on the compute node instead
of centralizing it on a network node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To provide proper tenant isolation when using the namespace-based
implementation of DVR, SNAT would be performed twice
(Insert diagram and explain in detail here).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Should SNAT traffic use the FIP gateway IP as the source address, or
should it use an IP address specific to the tenant router? Using the
FIP gateway IP seems simpler and does cut down on address usage
(although subnet service types does make this less of an issue). On the
flip side, an address associated with the router does allow for better
scrutiny of network traffic as traffic flows can be tied to a specific
project and router.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allowing operators to choose whether to use distributed SNAT or not
is the best way forward.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;See &lt;a class="footnote-reference brackets" href="#id36" id="id18" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;18&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; for some historical context and details.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="cli-impact"&gt;
&lt;h3&gt;CLI Impact&lt;/h3&gt;
&lt;p&gt;No CLI impact is anticipated. All existing CLI commands will continue to be
supported.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-impact-and-required-extensions"&gt;
&lt;h3&gt;API Impact and Required Extensions&lt;/h3&gt;
&lt;p&gt;The extensions supported by OVN plugins vs. ML2+OVS should provide equivalent
functionality in terms of data plane features such trunks, routed networks,
address scopes, etc. Matching support for every specific extension is not
necessary in all cases. For example, OVN provides DVR functionality in its
implementation without implementing the API extensions DVR introduces.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Brian Haley &amp;lt;&lt;a class="reference external" href="mailto:haleyb.dev%40gmail.com"&gt;haleyb&lt;span&gt;.&lt;/span&gt;dev&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Move networking-ovn into the neutron tree.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensure RFE’s have been created for all items in feature gaps and developer
impact sections.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rally jobs for capturing control plane performance with OVN in place.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id19" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blogs.rdoproject.org/2016/08/native-dhcp-support-in-ovn/"&gt;https://blogs.rdoproject.org/2016/08/native-dhcp-support-in-ovn/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id20" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/ovn-org/ovn/blob/master/TODO.rst"&gt;https://github.com/ovn-org/ovn/blob/master/TODO.rst&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id21" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/#/c/671766/"&gt;https://review.opendev.org/#/c/671766/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id22" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/ovn-org/ovn/blob/master/ovn-nb.ovsschema#L148"&gt;https://github.com/ovn-org/ovn/blob/master/ovn-nb.ovsschema#L148&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id23" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/#/c/539826/"&gt;https://review.opendev.org/#/c/539826/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id24" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openvswitch/ovs/commit/66d89287269ca7e2f7593af0920e910d7f9bcc38"&gt;https://github.com/openvswitch/ovs/commit/66d89287269ca7e2f7593af0920e910d7f9bcc38&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id25" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/torvalds/linux/blob/master/net/openvswitch/meter.h"&gt;https://github.com/torvalds/linux/blob/master/net/openvswitch/meter.h&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id26" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://imgur.com/a/4QtaN6b"&gt;https://imgur.com/a/4QtaN6b&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id27" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;9&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://imgur.com/a/N9jrIXV"&gt;https://imgur.com/a/N9jrIXV&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id28" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id10"&gt;10&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://imgur.com/a/oOmuAqj"&gt;https://imgur.com/a/oOmuAqj&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id29" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id11"&gt;11&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blog.russellbryant.net/2017/05/30/ovn-geneve-vs-vxlan-does-it-matter/"&gt;https://blog.russellbryant.net/2017/05/30/ovn-geneve-vs-vxlan-does-it-matter/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id30" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id12"&gt;12&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/networking-ovn/latest/install/migration.html"&gt;https://docs.openstack.org/networking-ovn/latest/install/migration.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id31" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id13"&gt;13&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/ML2-OVS-OVN-Convergence"&gt;https://etherpad.openstack.org/p/ML2-OVS-OVN-Convergence&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id32" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id14"&gt;14&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1774463"&gt;https://bugs.launchpad.net/neutron/+bug/1774463&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id33" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id15"&gt;15&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/openflow-based-dvr"&gt;https://blueprints.launchpad.net/neutron/+spec/openflow-based-dvr&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id34" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id16"&gt;16&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.opendev.org/#/c/472289/"&gt;https://review.opendev.org/#/c/472289/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id35" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id17"&gt;17&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/admin/config-bgp-dynamic-routing.html"&gt;https://docs.openstack.org/neutron/latest/admin/config-bgp-dynamic-routing.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id36" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id18"&gt;18&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/boston-dvr"&gt;https://etherpad.openstack.org/p/boston-dvr&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Fri, 10 May 2019 00:00:00 </pubDate></item><item><title>Port binding records, capabilities and events</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/train/port-binding-extended-information.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1821058"&gt;https://bugs.launchpad.net/neutron/+bug/1821058&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There are several cases in the Nova/Neutron/os-vif interaction where the
knowledge of the neutron core plugin or ML2 driver would be useful to
facilitate a more robust handling of guest networking. For example,
&lt;a class="footnote-reference brackets" href="#id12" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This spec aims to enhance the port binding API via the introduction of a new
extension to provide the additional information required to enable Nova and
os-vif to make more intelligent use of port binding info.&lt;/p&gt;
&lt;p&gt;Please remember os-vif was only intended to remove the VIF plugging process
from Nova. The hypervisor configuration (e.g.: libvirt XML generation) is still
Nova’s responsibility. Although os-vif removes the networking back-end logic
related to the plug and unplug process, Nova still needs to handle the
information proposed in this spec.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;This spec aims to resolve 3 related problems.&lt;/p&gt;
&lt;section id="network-connectivity"&gt;
&lt;h3&gt;Network connectivity&lt;/h3&gt;
&lt;p&gt;&lt;a class="footnote-reference brackets" href="#id12" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; blueprint seeks to enable the use of instances with ip_allocation=none.
The port parameter “ip_allocation” was introduced in the &lt;a class="footnote-reference brackets" href="#id10" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, to “distinguish
the unaddressed port case from the deferred IP allocation case where routed
networks is involved” (extracted from &lt;a class="footnote-reference brackets" href="#id11" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;To do this safely and guarantee the guest will have network connectivity, Nova
must ensure that the network backend that bound the port provides L2
connectivity.&lt;/p&gt;
&lt;p&gt;For example, in a mixed Calico/SR-IOV deployment, it is valid to use
ip_allocation=none for any port that is bound by the SR-IOV ML2 driver, but not
for the Calico backend. In this case, the only connectivity Calico provides to
a guest is L3, therefore is not possible to spawn a VM without an IP address.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="network-isolation"&gt;
&lt;h3&gt;Network isolation&lt;/h3&gt;
&lt;p&gt;In resolving &lt;a class="footnote-reference brackets" href="#id13" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, a new config option was required in os-vif to allow
enabling VIF isolation for the ML2/ovs backend. As Nova cannot differentiate
between VIF_TYPE=”ovs” that is bound by ML2/odl or ML2/ovs it cannot
automatically instruct os-vif to enable or disable VIF isolation for ML2/ovs
hosts. If the ML2 driver(s) that bound the port are recorded in the port
binding details, Nova and os-vif can use that information to more
intelligently enable backend specific code paths without requiring additional
network backend specific config options.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="bandwidth-scheduling"&gt;
&lt;h3&gt;Bandwidth scheduling&lt;/h3&gt;
&lt;p&gt;The network driver information can be used too for the bandwidth scheduling
featured implemented in Stein, as pointed out in this &lt;a class="footnote-reference brackets" href="#id15" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. Currently Nova
cannot handle the case where the PF is used by one ML2 driver while the VF is
managed by the SR-IOV ML2 driver.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;To address the 3 problems stated above, the following additions to the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding:vif_details&lt;/span&gt;&lt;/code&gt; dictionary in the port object are proposed:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;connectivity&lt;/span&gt;&lt;/code&gt; field will be introduced with allowed values of “l2”,
“l3” and “legacy”. The “legacy” &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;connectivity&lt;/span&gt;&lt;/code&gt; value will be the default
and is a sentinel to indicate the driver does not support this extension yet
and no connectivity info is available. “l2” drivers provide layer 2
connectivity, like for example Linux Bridge, Open vSwitch or SR-IOV. “l3”
drivers provide only layer 3 connectivity, like for example Calico &lt;a class="footnote-reference brackets" href="#id17" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;bound_drivers&lt;/span&gt;&lt;/code&gt; field will be added that is a dictionary mapping
binding_level to driver name. The driver name will be the stevedore entry
point name for the driver which is already used in config files and intended
to be stable. A POC is available in &lt;a class="footnote-reference brackets" href="#id16" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To enable declaration of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;connectivity&lt;/span&gt;&lt;/code&gt;, a new property will be added to
the ML2 driver base class which will default to “legacy”. ML2 drivers that
inherit from this will override the property.&lt;/p&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;bound_drivers&lt;/span&gt;&lt;/code&gt; field will be used by the OVS os-vif plugin to remove the
need for &lt;a class="footnote-reference brackets" href="#id14" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. We can enable this option only when
needed.&lt;/p&gt;
&lt;section id="examples"&gt;
&lt;h3&gt;Examples&lt;/h3&gt;
&lt;p&gt;ML2/ovs:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;binding_details&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="s2"&gt;"connectivity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"l2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"bound_drivers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"openvswtich"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;ML2/odl v1:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;binding_details&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="s2"&gt;"connectivity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"legacy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"bound_drivers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"opendaylight"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;ML2/odl v2:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;binding_details&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="s2"&gt;"connectivity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"l2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"bound_drivers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"opendaylight_v2"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;ML2/calico&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;binding_details&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="s2"&gt;"connectivity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"l3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"bound_drivers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"calico"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;BP Allow vm to boot without l3 address&lt;/cite&gt;:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/vm-without-l3-address"&gt;https://blueprints.launchpad.net/neutron/+spec/vm-without-l3-address&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id11" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;commit 361455&lt;/cite&gt;:
&lt;a class="reference external" href="https://review.openstack.org/#/c/361455/"&gt;https://review.openstack.org/#/c/361455/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;Boot a VM with an unaddressed port&lt;/cite&gt;:
&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/boot-vm-with-unaddressed-port"&gt;https://blueprints.launchpad.net/nova/+spec/boot-vm-with-unaddressed-port&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id13" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;bug 1734320&lt;/cite&gt;:
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1734320"&gt;https://bugs.launchpad.net/neutron/+bug/1734320&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id14" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;isolate_vif config option&lt;/cite&gt;:
&lt;a class="reference external" href="https://github.com/openstack/os-vif/blob/stable/stein/vif_plug_ovs/ovs.py#L146-L159"&gt;https://github.com/openstack/os-vif/blob/stable/stein/vif_plug_ovs/ovs.py#L146-L159&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id15" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;review 1&lt;/cite&gt;:
&lt;a class="reference external" href="https://review.opendev.org/#/c/623543/40/nova/compute/manager.py@2161"&gt;https://review.opendev.org/#/c/623543/40/nova/compute/manager.py@2161&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id16" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;review 2&lt;/cite&gt;:
&lt;a class="reference external" href="https://review.openstack.org/#/c/635083"&gt;https://review.openstack.org/#/c/635083&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id17" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;Calico project&lt;/cite&gt;:
&lt;a class="reference external" href="https://docs.openstack.org/networking-calico/latest/"&gt;https://docs.openstack.org/networking-calico/latest/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Thu, 21 Mar 2019 00:00:00 </pubDate></item><item><title>Change the segment ID of a VLAN provider network</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stein/change-segmentation-id-vlan-provider-network.html</link><description>

&lt;p&gt;Launchpad bug:
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1806052"&gt;https://bugs.launchpad.net/neutron/+bug/1806052&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes a method to change the segmentation ID of a VLAN-type
network, which is the external VLAN ID of the network. The implementation
described is limited to only the OVS back-end and to single-segment
provider networks.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently, Neutron does not allow the segmentation ID parameter of a provider
network to change, regardless of the status of the network (active or not) or
if ports exist on the network (or not). In order to change the segmentation ID,
the administrator needs to delete the network, first un-binding any bound
ports, then create a new network with the required segmentation ID, and
finally bind the ports back to the network.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposed solution is to be able to change the segmentation ID of a VLAN-
type network, using one single command (“openstack network set”) in an atomic
operation.&lt;/p&gt;
&lt;p&gt;In order to implement this, several changes are needed:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The CLI, to allow to update the segmentation ID in an existing network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Neutron server, to allow writing those changes in the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The networking back-end. In this spec only OVS is covered and the
implementation will be limited to it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="openstack-client"&gt;
&lt;h3&gt;OpenStack Client&lt;/h3&gt;
&lt;p&gt;Currently, the OpenStack Client allows updating the segmentation ID of an
existing network. No changes are needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="neutron-server"&gt;
&lt;h3&gt;Neutron server&lt;/h3&gt;
&lt;p&gt;Currently, when a network update message is sent to the Neutron server, if any
provider attribute is present in this message, for example ‘segmentation ID’,
this command is rejected. The new implementation will allow updating the
segmentation ID:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If the segmentation ID is the only provider parameter to be updated. No other
provider parameters (network type, physical network) are allowed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the network has only one segment. In multi provider networks the server
doesn’t know which one of the segments should be updated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the provider segment type is ‘vlan’. No other types are allowed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If all ports bound to this network belong to a compatible network driver. A
compatible network driver is one which has implemented this change. In
this spec, the OVS agent implementation is described. For example, with OVS,
ports with VIF type ‘vhostuser’ and ‘ovs’ are accepted, and ‘unbound’ or
‘binding_failed’ are also allowed because they are not yet bound to any
network driver.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the above conditions are all met, the Neutron server will execute the
following actions (in order):&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Validate the new segment, to know if the segmentation ID falls inside the
minimum and maximum VLAN tags.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reserve a new provider segment. This will ensure the segmentation ID is not
used in this network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new provider segment in the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Release the old provider segment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete the old provider segment from the database.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All these operations will be executed inside a write context, to provide
concurrency and enable rollback in case of failure. If any of these database
operations fail, including subsequent ones, the context will prevent the old
segment from being deleted and the new one will not be created.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="mechanism-driver"&gt;
&lt;h3&gt;Mechanism driver&lt;/h3&gt;
&lt;p&gt;The agent mechanism driver interface will be extended with a new function. This
function will return a list of provider network attributes that can be modified
in a network with ports bound to this networking back-end.&lt;/p&gt;
&lt;p&gt;By default, this function will return an empty list.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="neutron-ovs-agent"&gt;
&lt;h3&gt;Neutron OVS agent&lt;/h3&gt;
&lt;p&gt;In the OVS agent, VLAN provider networks can access the provider network
outside the host through the physical bridges. Each provider network has a
single physical bridge assigned. A physical bridge can host the traffic of
multiple provider networks, but each provider network can only send and receive
traffic through one physical bridge. There is a N:1 (network:physical bridge)
relationship.&lt;/p&gt;
&lt;p&gt;Inside the integration bridge, the tenant networks are isolated using virtual
networks. These virtual networks have their own VLAN ID mapping, different from
the provider networks VLAN ID mapping. Both VLAN maps are related through the
“LocalVlanManager”, which is in charge of correlating both mappings. When a
packet from a tenant exits the integration bridge to the corresponding physical
bridge, a flow changes the VLAN tag from the tenant VLAN ID to the provider
segmentation ID. The opposite process happens in the physical bridge:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;br_int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;cookie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xb46613524bd0de42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;23646.484&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_packets&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;n_bytes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"int-br-phy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_vlan&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1074&lt;/span&gt;
  &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;mod_vlan_vid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;resubmit&lt;/span&gt;&lt;span class="p"&gt;(,&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;br_phy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;cookie&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0x43209f9280b7fc88&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;23666.003&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_packets&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;n_bytes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;788&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"phy-br-phy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_vlan&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;mod_vlan_vid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1074&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;NORMAL&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When a network segmentation ID is updated, the only change needed is to update
the new segmentation ID in both flows. This could be done by deleting both
flows and then creating them again with the new segmentation ID. For example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;phys_br&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reclaim_local_vlan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;phys_port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lvid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;lvid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;phys_br&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;provision_local_vlan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;phys_port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lvid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;lvid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;segmentation_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;new_segmentation_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;distributed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable_distributed_routing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;int_br&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reclaim_local_vlan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;int_port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;segmentation_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;old_segmentation_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;int_br&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;provision_local_vlan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;int_port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lvid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;lvid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;segmentation_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;new_segmentation_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="limitations"&gt;
&lt;h3&gt;Limitations&lt;/h3&gt;
&lt;p&gt;As commented, this solution will be available only for:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Single segment networks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VLAN type networks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Only OVS (kernel OVS or DPDK OVS) bound ports to this network.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model"&gt;
&lt;h3&gt;Data Model&lt;/h3&gt;
&lt;p&gt;No changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api"&gt;
&lt;h3&gt;REST API&lt;/h3&gt;
&lt;p&gt;A new ML2 RPC call, requested from the agent side, is needed. This new call
will provide information about the updated network. With this information the
agent will know if the network has changed the segmentation ID (as commented,
the “LocalVlanManager” singleton stores this information).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="cli-impact"&gt;
&lt;h3&gt;CLI impact&lt;/h3&gt;
&lt;p&gt;No changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="operation-impact"&gt;
&lt;h3&gt;Operation Impact&lt;/h3&gt;
&lt;p&gt;The segmentation ID change implies two actions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;To change the segmentation ID of a Neutron network without unbinding the
attached ports. Once this process is done in Neutron, the traffic from those
ports will be tagged with the new VLAN ID and transmitted through the
provider network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To change the provider network segmentation. This process is external to
Neutron (and OpenStack).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Because those processes cannot be done at the same time, the administrator
should decide, depending on the site network infrastructure, the order of
execution. Until both the segmentation ID of the Neutron network and the
VLAN ID of the external provider network are synchronized, there will be a
networking disruption.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 28 Jan 2019 00:00:00 </pubDate></item><item><title>Network Segment Range Management</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stein/network-segment-range-management.html</link><description>

&lt;p&gt;Launchpad blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/network-segment-range-management"&gt;https://blueprints.launchpad.net/neutron/+spec/network-segment-range-management&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, network segment ranges are configured as an entry in ML2 config
file &lt;a class="footnote-reference brackets" href="#id9" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; that is statically defined for tenant network allocation and
therefore must be managed as part of the host deployment and management. When a
normal tenant user creates a network, Neutron assigns the next free
segmentation ID (VLAN ID, VNI etc.) from the configured segment ranges. Only an
administrator can assign a specific segment ID via the provider extension.&lt;/p&gt;
&lt;p&gt;This spec introduces an extension which exposes the segment range management to
be administered via the Neutron API. In addition, it introduces the ability for
the administrator to control the segment ranges globally or on a per-tenant
basis.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Self-service networks, aka tenant networks primarily enable general
(non-privileged) projects to manage networks without involving administrators.
These networks are entirely virtual and require virtual routers to interact
with provider and external networks such as the Internet. In most cases,
self-service networks use overlay protocols such as VXLAN or GRE because they
can support many more networks than layer-2 segmentation using VLAN tagging
(802.1q) which typically requires additional configuration of physical network
infrastructure. Nevertheless, in some other cases, OpenStack Neutron also
supports the self-service network isolation using VLAN etc. &lt;a class="footnote-reference brackets" href="#id10" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The current Neutron implementation sets entries in a config file to statically
define network segment ranges for tenant network allocation. It does not
support another dynamic way (e.g. at the API level) after initialization.
Neutron services have to be restarted in order to make any change to the
network segment ranges take effect. However, cloud network infrastructure
deployments can be complex and non-homogeneous. This rigidity brings about
complexity and difficulty to cloud administrators when dealing with varied
requirements.&lt;/p&gt;
&lt;p&gt;Network segment range management provides an additional level of flexibility at
the API level which enables full network orchestration of all the types of
tenant networks using standard REST API rather than needing to interact with
the host configuration directly. Apart from this, for VLAN tenant networks in
particular, network segment range management enables a control over the
management of the cloud/network infrastructure for tenant networks. It also
facilitates per-tenant assignments (including shared). This enables a cloud
administrator to directly control the VLAN tenant segment mapping, and
ultimately the underlying L2/L3 path of the tenant traffic without exposing
specific network segment range information to the tenant user. The segment
allocations for tenant networks will refer to the network segment ranges which
are assigned to that tenant by an administrator.&lt;/p&gt;
&lt;p&gt;Several sample use cases are demonstrated below.&lt;/p&gt;
&lt;section id="use-case-i"&gt;
&lt;h3&gt;Use Case I&lt;/h3&gt;
&lt;p&gt;Enable cloud administrators to create and assign per-tenant network segment
ranges. This gives an administrator the privilege to manage the underlying
network segment ranges. When a tenant creates a network, it will allocate a
segment ID from the segment ranges assigned to the tenant or shared if no
tenant specific range available. It helps map the VMs created by that tenant
with an explicit set of existing networks, for privacy or dedicated business
connection needs. One example illustration is shown below:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                            &lt;span class="o"&gt;+------------------+&lt;/span&gt;
                            &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Physical&lt;/span&gt; &lt;span class="n"&gt;Network&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
     &lt;span class="o"&gt;+------------+---------+&lt;/span&gt; &lt;span class="n"&gt;Infrastructures&lt;/span&gt;  &lt;span class="o"&gt;+-------------------+&lt;/span&gt;
     &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;+---------+--------+&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;
     &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;                            &lt;span class="o"&gt;|&lt;/span&gt;
     &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;                            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----+----+&lt;/span&gt;  &lt;span class="o"&gt;+----+----+&lt;/span&gt;         &lt;span class="o"&gt;+----+----+&lt;/span&gt;                 &lt;span class="o"&gt;+----+----+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Tenant&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Tenant&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|.........|&lt;/span&gt; &lt;span class="n"&gt;Tenant&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;|.................|&lt;/span&gt; &lt;span class="n"&gt;Tenant&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----+----+&lt;/span&gt;  &lt;span class="o"&gt;+----+----+&lt;/span&gt;         &lt;span class="o"&gt;+----+----+&lt;/span&gt;                 &lt;span class="o"&gt;+----+----+&lt;/span&gt;
     &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;
     &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;
     &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;    &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;           &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;k1&lt;/span&gt;                  &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;
                                        &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;k2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;One cloud is connecting and mapping with a large number of existing l2
physical network infrastructures.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;n+1 tenants: Tenant 0, …Tenant k…, Tenant n are available in this cloud.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each tenant needs to be assigned with one (or more) network segment range(s)
respectively (range-0, …range-k1…, …range-k2…, range-n) by the cloud
administrator, so that the networks it creates can reach the corresponding
dedicated physical network infrastructure it would like to connect to
according to different business requirements.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A possible workflow is presented as follows:&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Cloud administrator lists all network segment ranges existing:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;segment&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If no network segment range created for one target tenant, then cloud
administrator could create one for it:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;segment&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;
            &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;range_name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;network_type&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;network_type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;physical_network&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;physical_network_name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;minimum&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;range_minimum&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;maximum&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;range_maximum&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now a normal tenant user can create networks in regular way &lt;a class="footnote-reference brackets" href="#id11" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. The
network created will automatically allocate a segment ID from the segment
ranges assigned to the tenant (per step 3) or shared if no tenant specific
range available.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This helps deciding the correct VLAN mapping when multiple tenants exist. It
also provides the possibility to dynamically create a network segment range for
each tenant, even if it’s not pre-deployed in the host configuration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="use-case-ii"&gt;
&lt;h3&gt;Use Case II&lt;/h3&gt;
&lt;p&gt;In some VLAN tenant network scenarios, it is not uncommon that the existing
physical network infrastructures’ segment configurations have been changed.
Thus, it is a must for cloud administrators to update the VLAN allocation range
for tenant networks at the same time in order to keep aligned with the
connection or mapping. Hence offering the ability to dynamically manage segment
ranges of self-service networks, as this spec proposes, is imperative for VLAN
tenant networks and is definitely a plus for other overlay tenant networks.&lt;/p&gt;
&lt;p&gt;A possible workflow is presented as follows:&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Cloud administrator lists all network segment ranges existing and
identifies the one needs to update:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;segment&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cloud administrator updates a network segment range based on the actual
requirement changing:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;segment&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;
            &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;range_name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;minimum&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;range_minimum&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;maximum&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;range_maximum&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;network_segment_range&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now a normal tenant user can create networks in regular way &lt;a class="footnote-reference brackets" href="#id11" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. The network
created will automatically allocate free segment ID from the updated network
segment ranges available.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;To address the above use cases, this spec introduces a new resource called
network_segment_ranges together with its implementation.&lt;/p&gt;
&lt;p&gt;Currently by default, all pre-configured segment information (e.g.
network_vlan_ranges, vni_ranges etc. defined in &lt;a class="footnote-reference brackets" href="#id9" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;) is loaded into
“ml2_xxx_allocations” DB tables by ML2 type drivers once the Neutron services
are up. For all self-service networks’ segmentation ID sync, allocations and
releases, they will be based on this information.&lt;/p&gt;
&lt;p&gt;All this information will be maintained. The network segment ranges introduced
in this spec will augment this initial allocation that is loaded from the
configuration file to become part of the shared ranges. It proposes an API way
that user with administrative privileges can create and manage various network
segment ranges for all network types supported by ML2.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;The following new table is added as part of the network network management
feature:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;network_segment_ranges&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="n"&gt;CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt; &lt;span class="n"&gt;PRI&lt;/span&gt; &lt;span class="n"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="n"&gt;BOOL&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;shared&lt;/span&gt; &lt;span class="n"&gt;BOOL&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;project_id&lt;/span&gt; &lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;network_type&lt;/span&gt; &lt;span class="n"&gt;ENUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'vlan'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'vxlan'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'gre'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'geneve'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;physical_network&lt;/span&gt; &lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;minimum&lt;/span&gt; &lt;span class="n"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;maximum&lt;/span&gt; &lt;span class="n"&gt;INT&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For different network types, the validation strategies and responses should
have the following variants:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;VLAN: minimum = 1, maximum = 4094.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VXLAN: minimum = 1, maximum = 2 ** 24 - 1.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GRE: minimum = 1, maximum = 2 ** 32 - 1.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Geneve: minimum = 1, maximum = 2 ** 24 - 1.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Notes: Other validation rules like minimum &amp;lt;= maximum are always applicable and
should be paid attention to. Most of the cited above have been supported in
neutron_lib.plugins.utils.&lt;/p&gt;
&lt;p&gt;Mixin classes to add the network segment range management extension should be
provided. The DB operation logic should be handled by the ML2 type manager and
the type drivers. For the values present in the existing ML2 configuration
options &lt;a class="footnote-reference brackets" href="#id9" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; (e.g. ml2_type_vlan, ml2_type_vxlan etc.), they will be loaded as
&lt;cite&gt;shared&lt;/cite&gt; and &lt;cite&gt;default&lt;/cite&gt; segment ranges into network_segment_ranges DB in order
to provide backward compatibility for initial deployment when this extension is
present.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="resource-extension"&gt;
&lt;h3&gt;Resource Extension&lt;/h3&gt;
&lt;p&gt;The following new resource is being introduced and its attributes maps would be
like:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;NETWORK_TYPE_LIST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TYPE_VLAN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TYPE_VXLAN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TYPE_GRE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TYPE_GENEVE&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAPS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s1"&gt;'network_segment_ranges'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s1"&gt;'is_sort_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;db_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NAME_FIELD_SIZE&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s1"&gt;'is_sort_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;converters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;'shared'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;converters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;'project_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;db_const&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PROJECT_ID_FIELD_SIZE&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                   &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'is_sort_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;'network_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;NETWORK_TYPE_LIST&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                     &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ATTR_NOT_SPECIFIED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;'physical_network'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                           &lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PHYSICAL_NETWORK_MAX_LEN&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                         &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ATTR_NOT_SPECIFIED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s1"&gt;'is_filter'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;'minimum'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;converters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;'maximum'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;converters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;'used'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;'available'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_none_to_empty_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;The idea is to add a new resource extension with the below defined attributes.
Resource extension network_segment_ranges:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Identifier of network
segment range&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Name of network
segment range&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;default&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;False&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Default network
segment range that is
loaded from the host
ML2 config file &lt;a class="footnote-reference brackets" href="#id9" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;shared&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Shared with other
projects&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Current
project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of network
range. Optional when
&lt;cite&gt;shared&lt;/cite&gt; is True.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;network_type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Enum&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;VLAN, VxLAN, GRE
Geneve&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;physical_network&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Optional. Only
applicable for VLAN.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;minimum&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;INT&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Floor integer of the
segment range&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;maximum&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;INT&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Ceiling integer of the
segment range&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;used&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Dict&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;{}&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Mapping of which
segmentation ID in the
range is used by which
tenant&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;available&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;List&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[]&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;List of available
segmentation IDs in
this segment range&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;To specify a range with single item, min equals to max can do the trick. For
discrete segment ranges of one given network type, they are represented as
several ones, each with a min and a max.&lt;/p&gt;
&lt;p&gt;The following network segment range management Rest APIs will be provided in
line with the new resources previously introduced:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;List all network segment ranges.
GET /v2.0/network_segment_ranges&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;network_segment_ranges&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"network_segment_ranges"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"d23abc8d-2991-4a55-ba98-2aaea84cc72f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"network_segment_range_physnet1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"network_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"vlan"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"physical_network"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"physnet1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"minimum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"maximum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;105&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"used"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"100"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"07ac1127ee9647d48ce2626867104a13"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s2"&gt;"101"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"d4fa62aa47d340d98d076801aa7e6ec4"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="s2"&gt;"available"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;103&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;104&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;105&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;List a network segment range information.
GET /v2.0/network_segment_ranges/&amp;lt;network_segment_range-id&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;network_segment_ranges&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;d23abc8d&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2991&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;a55&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ba98&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;aaea84cc72f&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"network_segment_range"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"d23abc8d-2991-4a55-ba98-2aaea84cc72f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"network_segment_range_physnet1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"network_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"vlan"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"physical_network"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"physnet1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"minimum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"maximum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;105&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"used"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"100"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"07ac1127ee9647d48ce2626867104a13"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"101"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"d4fa62aa47d340d98d076801aa7e6ec4"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s2"&gt;"available"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;103&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;104&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;105&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create a network segment range for a given tenant.
POST /v2.0/network_segment_ranges&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;network_segment_ranges&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"network_segment_range"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"network_segment_range_physnet1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"network_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"vlan"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"physical_network"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"physnet1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"minimum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"maximum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Delete a network segment range by id.
DELETE /v2.0/network_segment_ranges/&amp;lt;network_segment_range-id&amp;gt;&lt;/p&gt;
&lt;p&gt;Normal Response Code: 204&lt;/p&gt;
&lt;p&gt;Error Response Codes: Unauthorized (401), Not Found (404), Conflict (409).
The Conflict error response is returned when an operation is performed while
the network segment range has resource allocated within it.&lt;/p&gt;
&lt;p&gt;This operation does not require a request body.&lt;/p&gt;
&lt;p&gt;This operation does not return a response body.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;network_segment_ranges&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;d23abc8d&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2991&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;a55&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ba98&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;aaea84cc72f&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update a network segment range with given data.
PUT /v2.0/network_segment_ranges/&amp;lt;network_segment_range-id&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;network_segment_ranges&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;d23abc8d&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2991&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;a55&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ba98&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;aaea84cc72f&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"network_segment_range"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"minimum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"maximum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="command-line-client-impact"&gt;
&lt;h3&gt;Command Line Client Impact&lt;/h3&gt;
&lt;p&gt;Openstack Client would add network segment range management related CLIs. They
should be admin only CLI commands. For example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;segment&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;used&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="ow"&gt;not&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;used&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;available&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="ow"&gt;not&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;available&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;segment&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;network_segment_range&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;segment&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;
            &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;network_type&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;network_type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;minimum&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;range_minimum&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;maximum&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;range_maximum&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;range_name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;physical_network&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;physical_network&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;Notes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Arguments&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt;
       &lt;span class="n"&gt;taken&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;the&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;given&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;physical_network&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;optional&lt;/span&gt;
       &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;applicable&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;VLAN&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;All&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="n"&gt;parameters&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt;
       &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;segment&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;range_name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;minimum&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;range_minimum&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;maximum&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;range_maximum&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;network_segment_range&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;segment&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;network_segment_range&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="other-impact"&gt;
&lt;h3&gt;Other Impact&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;ML2 plugin, plugin manager and type drivers will need to be refined and added
with several new methods correspondingly in order to support this feature.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When this extension is loaded, the Neutron server will populate the proposed
network_segment_ranges DB table with the ranges defined within the existing
ML2 configuration as &lt;cite&gt;default&lt;/cite&gt; and &lt;cite&gt;shared&lt;/cite&gt; ranges. These &lt;cite&gt;default&lt;/cite&gt; ranges
are read-only and an administrator can make per-tenant segment range
assignment based on this information. When a Neutron server starts/restarts,
the &lt;cite&gt;default&lt;/cite&gt; segment ranges will be reloaded and be visible to all servers.
Interactions from the REST APIs will always operate based on the segment
ranges defined within the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Validation work is needed for quite a few cases, including but not limited
to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Admin privilege should always be checked before performing any network
segment range operation cited previously.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When deleting one network segment range, the operation should be rejected
if one of the network segments is in use.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is allowed to update one network segment range if it does not impact the
in-use segment allocated within the range (e.g. enlarging that range).
Otherwise, we should fail the updating.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We’re maintaining the consistency by “ml2_xxx_allocations” DB tables and
relying on them to do the eventual validation and the underlying segment
allocation. This means network segment ranges can be configured before
agents are actually mapped to specific physical network mappings.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Theoretically, multiple network segment ranges can be created for one
tenant (while one network segment range cannot be owned by several tenants).
If a tenant has more than one segment range configured, it would pick up the
next free segmentation ID (VLAN ID, VNI etc.) from all its owned network
segment ranges.&lt;/p&gt;
&lt;p&gt;Backwards compatibility comes from having the default behavior of segment
ranges being assigned as a &lt;cite&gt;shared&lt;/cite&gt; resource to tenants. If both of &lt;cite&gt;shared&lt;/cite&gt;
and &lt;cite&gt;specified&lt;/cite&gt; segment range resources are exposed to a tenant, the
&lt;cite&gt;specified&lt;/cite&gt; should override the &lt;cite&gt;shared&lt;/cite&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The extension will be optional (an option in &lt;a class="footnote-reference brackets" href="#id12" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; with functionality disabled
by default should be added), in which case the existing ML2 configuration
options will be applicable.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;Users with admin privileges will be able to dynamically manage network segment
ranges for which supports segmentation, all tenants and tenant networks. If no
dynamic network segment range is created for a given tenant, or the feature is
disabled due to the backwards compatibility consideration, there will be no
impact to end users.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Deployers should have an option available to enable or disable this
functionality so that they can continue to use the configuration file as
before. They also need to be strongly warned to update their operational
documentation to ensure that the new network segment information is managed
using the correct facility. If the feature is disabled, nothing at the
deployment level would be impacted.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Performance testing must be conducted to see what is the overhead of enabling
this feature, of course if the feature is disabled no performance impact should
be noticed.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Kailun Qin &amp;lt;&lt;a class="reference external" href="mailto:kailun.qin%40intel.com"&gt;kailun&lt;span&gt;.&lt;/span&gt;qin&lt;span&gt;@&lt;/span&gt;intel&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Adjust the DB model and add the new table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend current API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify type drivers and all related references.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add CLI openstackclient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests, functional tests, API tests and scenario tests are necessary.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The Neutron API reference will need to be updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id9" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id5"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id6"&gt;3&lt;/a&gt;,&lt;a role="doc-backlink" href="#id7"&gt;4&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;ml2_conf.ini&lt;/cite&gt;:
/etc/neutron/plugins/ml2/ml2_conf.ini&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;OpenStack Networking&lt;/cite&gt;:
&lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/admin/intro-os-networking.html"&gt;https://docs.openstack.org/neutron/latest/admin/intro-os-networking.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id11" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id3"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id4"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;Self-service network&lt;/cite&gt;:
&lt;a class="reference external" href="https://docs.openstack.org/newton/install-guide-rdo/launch-instance-networks-selfservice.html"&gt;https://docs.openstack.org/newton/install-guide-rdo/launch-instance-networks-selfservice.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;neutron.conf&lt;/cite&gt;:
/etc/neutron/neutron.conf&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;section id="related-information"&gt;
&lt;h3&gt;Related Information&lt;/h3&gt;
&lt;p&gt;Neutron v2 API: &lt;a class="reference external" href="https://developer.openstack.org/api-ref/network/v2/"&gt;https://developer.openstack.org/api-ref/network/v2/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Wed, 09 Jan 2019 00:00:00 </pubDate></item><item><title>Registering RouterInfo by L3 extension API</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stein/router-factory-with-l3-extension.html</link><description>

&lt;p&gt;Launchpad blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/router-factory-with-l3-extension"&gt;https://blueprints.launchpad.net/neutron/+spec/router-factory-with-l3-extension&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, most plugin implementations related to L3 override the &lt;em&gt;L3NATAgent&lt;/em&gt;
class itself for their own logic since there is no proper interface to
extend the &lt;em&gt;RouterInfo&lt;/em&gt; class. This adds unnecessary complexity for developers
who just want to extend the agent mechanism instead of the whole RPC related
to L3 functionalities.&lt;/p&gt;
&lt;p&gt;This spec introduces the &lt;em&gt;RouterFactory&lt;/em&gt; class which acts on the factory for
creating the &lt;em&gt;RouterInfo&lt;/em&gt; class, and adds a new parameter to the L3 agent
extension API which enables it to dynamically register &lt;em&gt;RouterInfo&lt;/em&gt; to the
factory. Now plugin developers can use the new extension API for their own
specific router.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Current L3 agent implementation in Neutron consists of two parts in general.
One is to implement an RPC Plugin API from Neutron server, and the other is to
create ports, namespaces, and iptables rules using the data obtained from the
RPC API on the server. To be more specific, the former is the &lt;em&gt;L3NATAgent&lt;/em&gt;
class and the latter is the &lt;em&gt;RouterInfo&lt;/em&gt; class.&lt;/p&gt;
&lt;p&gt;The problem is that the two parts mentioned are now tightly coupled which means
there is no clear way to extend each part individually. A lot of projects
related to Neutron called networking-* &lt;a class="footnote-reference brackets" href="#id7" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, &lt;a class="footnote-reference brackets" href="#id8" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, &lt;a class="footnote-reference brackets" href="#id9" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; are making new L3
agent classes on their own by extending the &lt;em&gt;L3NATAgent&lt;/em&gt; class even though
they did not modify the RPC mechanism but only changed the &lt;em&gt;RouterInfo&lt;/em&gt;
mechanism running on their server.&lt;/p&gt;
&lt;p&gt;Also, the current &lt;em&gt;RouterInfo&lt;/em&gt; class does not have an abstract interface which
makes it harder to extend the class for plugin developers. They have to find
what functions and variables in &lt;em&gt;RouterInfo&lt;/em&gt; are externally used in the L3
agent to extend the &lt;em&gt;RouterInfo&lt;/em&gt; behaviors.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Today, &lt;em&gt;RouterInfo&lt;/em&gt; is extended in several ways according to specific router
features such as distributed, ha, and distributed + ha. This document proposes
changing the L3 agent to have a new class called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RouterFactory&lt;/span&gt;&lt;/code&gt; which has
several pre-registered classes to extend the &lt;em&gt;RouterInfo&lt;/em&gt; class with certain
features. When it comes to creating an actual &lt;em&gt;RouterInfo&lt;/em&gt; instance, the L3
agent create a new instance from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RouterFactory&lt;/span&gt;&lt;/code&gt; following the features
of the router. There is no functional change for existing code.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;L3AgentExtensionAPI&lt;/em&gt; now has a new parameter &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;router_factory&lt;/span&gt;&lt;/code&gt; and a new
function &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;register_router&lt;/span&gt;&lt;/code&gt;. A new abstract class called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BaseRouterInfo&lt;/span&gt;&lt;/code&gt;
will be added. It will declare interfaces that are currently used externally.&lt;/p&gt;
&lt;p&gt;An L3 extension can register their own &lt;em&gt;RouterInfo&lt;/em&gt; class which implements
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BaseRouterInfo&lt;/span&gt;&lt;/code&gt; using the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;register_router&lt;/span&gt;&lt;/code&gt; API which has two parameters.&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;router&lt;/span&gt;&lt;/code&gt;: RouterInfo declared in extension which overrides the one
pre-registered at &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RouterFactory&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;features&lt;/span&gt;&lt;/code&gt;: features of RouterInfo. Currently it should be one of the
below.&lt;/p&gt;
&lt;p&gt;Features should be a list of strings describing router characteristics, and
the ordering does not matter since it is interpreted as a &lt;em&gt;set&lt;/em&gt; internally.
(&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;['ha',&lt;/span&gt; &lt;span class="pre"&gt;'distributed']&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;['distributed',&lt;/span&gt; &lt;span class="pre"&gt;'ha']&lt;/span&gt;&lt;/code&gt; are the same)&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[]&lt;/span&gt;&lt;/code&gt;: No feature. (e.g. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;LegacyRouter&lt;/span&gt;&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;['distributed']&lt;/span&gt;&lt;/code&gt;: Distributed router. (e.g. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DvrEdgeRouter&lt;/span&gt;&lt;/code&gt;,&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DvrLocalRouter&lt;/span&gt;&lt;/code&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;['ha']&lt;/span&gt;&lt;/code&gt;: HA router. (e.g. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;HaRouter&lt;/span&gt;&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;['ha',&lt;/span&gt; &lt;span class="pre"&gt;'distributed']&lt;/span&gt;&lt;/code&gt;: Distributed HA router. (e.g.&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DvrEdgeHaRouter&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DvrLocalRouter&lt;/span&gt;&lt;/code&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that a router with the feature of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;['ha',&lt;/span&gt; &lt;span class="pre"&gt;'distributed']&lt;/span&gt;&lt;/code&gt; can be
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DvrLocalRouter&lt;/span&gt;&lt;/code&gt; when L3 agent mode is not &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dvr_snat&lt;/span&gt;&lt;/code&gt; &lt;a class="footnote-reference brackets" href="#id10" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;L3 extensions can override the &lt;em&gt;RouterInfo&lt;/em&gt; class implemented in the Neutron
codebase when it is initialized using the &lt;em&gt;initialize&lt;/em&gt; function.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Yang Youseok &amp;lt;&lt;a class="reference external" href="mailto:ileixe%40gmail.com"&gt;ileixe&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add &lt;em&gt;RouterInfo&lt;/em&gt; registration in &lt;em&gt;L3AgentExensionAPI&lt;/em&gt; and pre-register
existing &lt;em&gt;RouterInfo&lt;/em&gt; to &lt;em&gt;L3NATAgent&lt;/em&gt;. &lt;a class="footnote-reference brackets" href="#id11" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new exception named &lt;em&gt;RouterNotFoundInRouterFactory&lt;/em&gt; to &lt;em&gt;neutron_lib&lt;/em&gt;.
&lt;a class="footnote-reference brackets" href="#id12" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;networking-odl&lt;/cite&gt;:
&lt;a class="reference external" href="https://github.com/openstack/networking-odl/blob/master/networking_odl/l3/l3_odl_v2.py#L47"&gt;https://github.com/openstack/networking-odl/blob/master/networking_odl/l3/l3_odl_v2.py#L47&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;networking-ovn&lt;/cite&gt;:
&lt;a class="reference external" href="https://github.com/openstack/networking-ovn/blob/master/networking_ovn/l3/l3_ovn.py#L50"&gt;https://github.com/openstack/networking-ovn/blob/master/networking_ovn/l3/l3_ovn.py#L50&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id9" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;networking-calico&lt;/cite&gt;:
&lt;a class="reference external" href="https://github.com/openstack/networking-calico/blob/master/networking_calico/plugins/calico/plugin.py#L26"&gt;https://github.com/openstack/networking-calico/blob/master/networking_calico/plugins/calico/plugin.py#L26&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/configuration/l3-agent.html#DEFAULT.agent_mode"&gt;https://docs.openstack.org/neutron/latest/configuration/l3-agent.html#DEFAULT.agent_mode&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id11" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/620349/"&gt;https://review.openstack.org/#/c/620349/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/620348/"&gt;https://review.openstack.org/#/c/620348/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 18 Dec 2018 00:00:00 </pubDate></item><item><title>QoS minimum bandwidth allocation in Placement API</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/rocky/minimum-bandwidth-allocation-placement-api.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1578989"&gt;https://bugs.launchpad.net/neutron/+bug/1578989&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec describes how to model, from Neutron, new resource providers
in Placement API to describe bandwidth allocation.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently there are several parameters, quantitative and qualitative,
that define a Nova server and are used to select the correct host
and network backend devices to run it. Network bandwidth is not yet
among these parameters. This allows situations where a physical network
device could be oversubscribed.&lt;/p&gt;
&lt;p&gt;This spec addresses managing the bandwidth on the first physical device
ie. the pyhsical interface closest to the nova server. Managing bandwidth
further away, for example on the backplane of a Top-Of-Rack switch or
end-to-end, is out of scope here.&lt;/p&gt;
&lt;p&gt;Guaranteeing bandwidth generally involves enforcement of constraints on
two levels.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;placement: Avoiding oversubscription when placing (scheduling) nova servers
and their ports.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;data plane: Enforcing the guarantee on the physical network devices.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This spec addresses placement enforcement only. (Data plane enforcement
is covered by &lt;a class="footnote-reference brackets" href="#id21" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.) However the design must respect that users are
interested in the joint use of these enforcements.&lt;/p&gt;
&lt;p&gt;Since the placement enforcement itself is a Nova-Neutron cross-project
feature this spec is meant to be read, commented and maintained together
with its Nova counterpart: &lt;cite&gt;Network bandwidth resource provider&lt;/cite&gt; &lt;a class="footnote-reference brackets" href="#id19" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This spec is based on the approved Neutron spec &lt;cite&gt;Add a spec for strict
minimum bandwidth support&lt;/cite&gt; &lt;a class="footnote-reference brackets" href="#id20" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. The aim of the current spec is not
to redefine what is already approved in &lt;a class="footnote-reference brackets" href="#id20" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, but to specify how it is
going to be implemented in Neutron.&lt;/p&gt;
&lt;section id="use-cases"&gt;
&lt;h3&gt;Use Cases&lt;/h3&gt;
&lt;p&gt;The most straightforward use case is when a user, who has paid for a
premium service that guarantees a minimum network bandwidth, wants to
spawn a Nova server. The scheduler needs to know how much bandwidth is
already in use in each physical network device in each compute host and
how much bandwidth the user is requesting.&lt;/p&gt;
&lt;p&gt;Data plane only enforcement was merged in Newton for SR-IOV egress
(see &lt;cite&gt;Newton Release Notes&lt;/cite&gt; &lt;a class="footnote-reference brackets" href="#id23" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Placement only enforcement may be a viable feature for users able
to control all traffic (e.g. in a single tenant private cloud). Such
placement only enforcement can be also used together with the bandwidth
limit rule. The admin can set two rules in a QoS policy, both with
the same bandwidth values and then each server on such chosen compute
host will be able to use at most as much bandwidth as it has guaranteed.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;The user must be able to express the resource needs of a port.&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Extend &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qos_minimum_bandwidth_rule&lt;/span&gt;&lt;/code&gt; with ingress direction.&lt;/p&gt;
&lt;p&gt;Unlike enforcement in the data plane, Placement can handle both
directions by the same effort.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mark &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qos_minimum_bandwidth_rule&lt;/span&gt;&lt;/code&gt; as supported QoS
policy rule for each existing QoS driver.&lt;/p&gt;
&lt;p&gt;Placement enforcement is orthogonal to backend mechanisms. A user
can have placement enforcement for drivers not having data plane
enforcement (yet).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Due to the fact that we exposed (and likely want to expose further)
partial results of this development effort to end users, the meaning
of a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qos_minimum_bandwidth_rule&lt;/span&gt;&lt;/code&gt; depends on OpenStack version,
Neutron backend driver and the rule’s direction. A rule may be enforced
by placement and/or on the data plane. Therefore we must document, next
to the already existing support matrix in the &lt;cite&gt;QoS devref&lt;/cite&gt; &lt;a class="footnote-reference brackets" href="#id27" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;10&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, which
combinations of versions, drivers, rule directions and (placement and/or
data plane) enforcements are supported.&lt;/p&gt;
&lt;p&gt;Since Neutron’s choice of backend is hidden from the cloud user, the
deployer must also clearly document which subset of the above support
matrix is applicable for a cloud user in a particular deployment.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron must convey the resource needs of a port to Nova.&lt;/p&gt;
&lt;p&gt;Extend port with attribute &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; according to section
‘How required bandwidth for a Neutron port is modeled’ below. This
attribute is computed, read-only and admin-only.&lt;/p&gt;
&lt;p&gt;Information available at port create time (ie. before the port
is bound) must be sufficient to generate the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt;
attribute.&lt;/p&gt;
&lt;p&gt;The port extension must be decoupled from ML2 and kept
in the QoS service plugin. One way to do that is to use
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron.db._resource_extend&lt;/span&gt;&lt;/code&gt; like &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;trunk_details&lt;/span&gt;&lt;/code&gt; uses it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron must populate the Placement DB with the available resources.&lt;/p&gt;
&lt;p&gt;Report information on available resources to the Placement service
using the &lt;cite&gt;Placement API&lt;/cite&gt; &lt;a class="footnote-reference brackets" href="#id18" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. That is information about the physical
network devices, their physnets, available bandwidth and supported
VNIC types.&lt;/p&gt;
&lt;p&gt;The cloud admin must be able to control (by configuration) what is
reported to Placement. To ease the configuration work autodiscovery
of networking devices may be employed, but the admin must be able to
override its results.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="which-devices-and-parameters-will-be-tracked"&gt;
&lt;h3&gt;Which devices and parameters will be tracked&lt;/h3&gt;
&lt;p&gt;Even inside a compute host many networking topologies are possible.
For example:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;OVS agent: physical network - OVS bridge - single physical NIC (or a bond):
1-to-1 mapping between physical network and physical interface&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SR-IOV agent: physical network - one or more PFs:
1-to-n mapping between physical network and physical interface(s)
(See &lt;cite&gt;Networking Guide: SR-IOV&lt;/cite&gt; &lt;a class="footnote-reference brackets" href="#id24" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Each Neutron agent (Open vSwitch, Linux Bridge, SR-IOV) has a
configuration parameter to map a physical network with one or more
provider interfaces (SR-IOV) or a bridge connected to a provider interface
(Open vSwitch or Linux Bridge).&lt;/p&gt;
&lt;p&gt;OVS agent configuration:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ovs&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# bridge_mappings as it exists already.&lt;/span&gt;
&lt;span class="n"&gt;bridge_mappings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;physnet0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;br0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;physnet1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;br1&lt;/span&gt;

&lt;span class="c1"&gt;# Each right hand side value in bridge_mappings:&lt;/span&gt;
&lt;span class="c1"&gt;#   * will have a corresponding resource provider created in Placement&lt;/span&gt;
&lt;span class="c1"&gt;#   * must be listed as a key in resource_provider_bandwidths&lt;/span&gt;

&lt;span class="n"&gt;resource_provider_bandwidths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;br0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;EGRESS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;INGRESS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;br1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;EGRESS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;INGRESS&lt;/span&gt;

&lt;span class="c1"&gt;# Examples:&lt;/span&gt;

&lt;span class="c1"&gt;# Resource provider created, no inventory reported.&lt;/span&gt;
&lt;span class="n"&gt;resource_provider_bandwidths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;br0&lt;/span&gt;
&lt;span class="n"&gt;resource_provider_bandwidths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;br0&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;

&lt;span class="c1"&gt;# Report only egress inventory in kbps (same unit as in the QoS rule API).&lt;/span&gt;
&lt;span class="n"&gt;resource_provider_bandwidths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;br0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="c1"&gt;# Report egress and ingress inventories in kbps.&lt;/span&gt;
&lt;span class="n"&gt;resource_provider_bandwidths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;br0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1000000&lt;/span&gt;

&lt;span class="c1"&gt;# Later we may introduce auto-discovery (for example via ethtool).&lt;/span&gt;
&lt;span class="c1"&gt;# We reserve the option to make auto-discovery the default behavior&lt;/span&gt;
&lt;span class="c1"&gt;# when it is implemented.&lt;/span&gt;
&lt;span class="n"&gt;resource_provider_bandwidths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;br0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;auto&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;SR-IOV agent configuration:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sriov_nic&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;physical_device_mappings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;physnet0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;eth0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;physnet0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;eth1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;physnet1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;eth2&lt;/span&gt;

&lt;span class="n"&gt;resource_provider_bandwidths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;eth0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;EGRESS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;INGRESS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;eth1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;EGRESS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;INGRESS&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="how-required-bandwidth-for-a-neutron-port-is-modeled"&gt;
&lt;h3&gt;How required bandwidth for a Neutron port is modeled&lt;/h3&gt;
&lt;p&gt;The required minimum network bandwidth needed for a port is modeled
defining a QoS policy along with one or more QoS minimum bandwidth rules
&lt;a class="footnote-reference brackets" href="#id21" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. However neither Nova nor Placement know about any QoS policy
rule directly. Neutron translates the resource needs of a port into a
standard port attribute describing the needed resource classes, amounts
and traits.&lt;/p&gt;
&lt;p&gt;In this spec we assume that a single port requests resources from a
single RP. Later we may allow a port to request resources from multiple RPs.&lt;/p&gt;
&lt;p&gt;The resources needed by a port are expressed via the new attribute
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; extending the port as follows.&lt;/p&gt;
&lt;p&gt;Figure: resource_request in the port&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"port0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="s2"&gt;"device_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5e3898d7-11be-483e-9732-b2f5eccd2b2e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"resource_request"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"resources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"NET_BW_IGR_KILOBIT_PER_SEC"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"NET_BW_EGR_KILOBIT_PER_SEC"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CUSTOM_PHYSNET_NET0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"CUSTOM_VNIC_TYPE_NORMAL"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; port attribute will be implemented by a new
API extension named &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;port-resource-request&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If a nova server boot request has a port defined and this port has a
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; attribute, that means the Placement Service must
enforce the minimum bandwidth requirements.&lt;/p&gt;
&lt;p&gt;A host will satisfy the requirements if it has a physical network
interface RP with the following properties. First, inventory of the
new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;NET_BANDWIDTH_*&lt;/span&gt;&lt;/code&gt; resource classes and there is enough bandwidth
available as shown in the ‘Networking RP model’ section. If a host doesn’t
have an inventory of the requested network bandwidth resource class(es),
it won’t be a candidate for the scheduler. Second, the physical network
interface RP must have all the traits associated with it as listed in the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;required&lt;/span&gt;&lt;/code&gt; field of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; attribute.&lt;/p&gt;
&lt;p&gt;We propose two kinds of custom traits. First to express and request support
for certain &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vnic_types&lt;/span&gt;&lt;/code&gt;. This trait uses prefix &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CUSTOM_VNIC_TYPE_&lt;/span&gt;&lt;/code&gt;.
The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vnic_type&lt;/span&gt;&lt;/code&gt; is then appended in all upper case.
For example:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CUSTOM_VNIC_TYPE_NORMAL&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CUSTOM_VNIC_TYPE_DIRECT&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Second we’ll use traits to decide if a segment of a network (identified
by its physnet name) is connected on the compute host considered in
scheduling.  This trait uses prefix &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CUSTOM_PHYSNET_&lt;/span&gt;&lt;/code&gt;. The physnet name
is then appended in all upper case, any characters prohibited in traits must
be replaced with underscores.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CUSTOM_PHYSNET_PUBLIC&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CUSTOM_PHYSNET_NET1&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If a nova server boot request has a network defined and this network has
a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qos_minimum_bandwidth_rule&lt;/span&gt;&lt;/code&gt;, that boot request is going to fail as
documented in the ‘Scoping’ section of &lt;a class="footnote-reference brackets" href="#id19" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; until Nova is refactored to
create the port earlier (that is before scheduling). See also &lt;cite&gt;SPEC:
Prep work for Network aware scheduling (Pike)&lt;/cite&gt; &lt;a class="footnote-reference brackets" href="#id28" id="id11" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;11&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For multi-segment Neutron networks each static segment’s physnet trait
must be included in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; attribute in a format that
we can only specify after Placement supports request matching logic
of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;any(traits)&lt;/span&gt;&lt;/code&gt;. See &lt;cite&gt;any-traits-in-allocation_candidates-query&lt;/cite&gt; &lt;a class="footnote-reference brackets" href="#id26" id="id12" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;9&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="reporting-available-resources"&gt;
&lt;h3&gt;Reporting Available Resources&lt;/h3&gt;
&lt;p&gt;Some details of reporting are described in the following sections of &lt;a class="footnote-reference brackets" href="#id19" id="id13" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron agent first start&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron agent restart&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finding the compute RP&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Details internal to Neutron are the following:&lt;/p&gt;
&lt;section id="networking-rp-model"&gt;
&lt;h4&gt;Networking RP model&lt;/h4&gt;
&lt;p&gt;We made the following assumptions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron supports the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;multi-provider&lt;/span&gt;&lt;/code&gt; extension therefore a single
logical network might map to more than one physnet. Physnets of
non-dynamic segments are known before port binding. For the sake of
simplicity in this spec we assume each segment directly connected to a
physical interface with a mimimum bandwidth guarantee is a non-dynamic
segment. Therefore those physnets can be included in the port’s
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; as traits.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multiple SRIOV physical functions (PFs) can give access to the same
physnet on a given compute but those PFs always implement the same
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vnic_type&lt;/span&gt;&lt;/code&gt;. This means that using only physnet traits in Placement
and in the port’s resource request does not select one PF unambiguously
but it is not a problem as both PFs are equivalent from resource
allocation perspective.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Two different backends (e.g. SRIOV and OVS) can give access to the same
physnet on the same compute host. In this case Neutron selects the
backend based on &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vnic_type&lt;/span&gt;&lt;/code&gt; of the Neutron port specified by the
end user during port create. Therefore physical device selection during
scheduling should consider the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vnic_type&lt;/span&gt;&lt;/code&gt; of the port as well. This
can be done via the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vnic_type&lt;/span&gt;&lt;/code&gt; based traits previously described.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Two different backends (e.g. OVS and LinuxBridge) can give access to
the same physnet on the same compute host while they are also
implementing the same &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vnic_type&lt;/span&gt;&lt;/code&gt; (e.g. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;normal&lt;/span&gt;&lt;/code&gt;). In this
case the backend selection in Neutron is done according to
the order of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;mechanism_drivers&lt;/span&gt;&lt;/code&gt; configured by the admin in
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron.conf&lt;/span&gt;&lt;/code&gt;. Therefore physical device selection during scheduling
should consider the same preference order. As the backend order is
just a preference but not a hard rule supporting this behavior is &lt;em&gt;out
of scope&lt;/em&gt; in this spec but in theory it can be done by a new weigher
in nova-scheduler.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Based on these assumptions, Neutron will construct in Placement a RP tree
as follows:&lt;/p&gt;
&lt;p&gt;Figure: networking RP model&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Compute&lt;/span&gt; &lt;span class="n"&gt;RP&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="o"&gt;+&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;+-------+&lt;/span&gt;&lt;span class="n"&gt;Network&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="n"&gt;RP&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;OVS&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent_uuid&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# later, model number of OVS ports here&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;+&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;+------+&lt;/span&gt;&lt;span class="n"&gt;Physical&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;RP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;uuid5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;br0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="n"&gt;traits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CUSTOM_PHYSNET_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CUSTOM_VNIC_TYPE_NORMAL&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;NET_BW_IGR_KILOBIT_PER_SEC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="n"&gt;NET_BW_EGR_KILOBIT_PER_SEC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;+------+&lt;/span&gt;&lt;span class="n"&gt;Physical&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;RP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;uuid5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;br1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="n"&gt;traits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CUSTOM_PHYSNET_2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CUSTOM_VNIC_TYPE_NORMAL&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;NET_BW_IGR_KILOBIT_PER_SEC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="n"&gt;NET_BW_EGR_KILOBIT_PER_SEC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;+-------+&lt;/span&gt;&lt;span class="n"&gt;Network&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="n"&gt;RP&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;LinuxBridge&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent_uuid&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;+&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;+------+&lt;/span&gt;&lt;span class="n"&gt;Physical&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;RP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;uuid5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;virbr0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="n"&gt;traits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CUSTOM_PHYSNET_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CUSTOM_VNIC_TYPE_NORMAL&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;NET_BW_IGR_KILOBIT_PER_SEC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;                        &lt;span class="n"&gt;NET_BW_EGR_KILOBIT_PER_SEC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;+-------+&lt;/span&gt;&lt;span class="n"&gt;Network&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="n"&gt;RP&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;SRIOV&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent_uuid&lt;/span&gt;
               &lt;span class="o"&gt;+&lt;/span&gt;
               &lt;span class="o"&gt;|&lt;/span&gt;
               &lt;span class="o"&gt;+------+&lt;/span&gt;&lt;span class="n"&gt;Physical&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;RP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;uuid5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;eth0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="n"&gt;traits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CUSTOM_PHYSNET_2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CUSTOM_VNIC_TYPE_DIRECT&lt;/span&gt;
               &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
               &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;VF&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# VF resource is out of scope&lt;/span&gt;
               &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="n"&gt;NET_BW_IGR_KILOBIT_PER_SEC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="n"&gt;NET_BW_EGR_KILOBIT_PER_SEC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
               &lt;span class="o"&gt;|&lt;/span&gt;
               &lt;span class="o"&gt;+------+&lt;/span&gt;&lt;span class="n"&gt;Physical&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;RP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;uuid5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;eth1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="n"&gt;traits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CUSTOM_PHYSNET_2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CUSTOM_VNIC_TYPE_DIRECT&lt;/span&gt;
               &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
               &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;VF&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# VF resource is out of scope&lt;/span&gt;
               &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="n"&gt;NET_BW_IGR_KILOBIT_PER_SEC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="n"&gt;NET_BW_EGR_KILOBIT_PER_SEC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
               &lt;span class="o"&gt;|&lt;/span&gt;
               &lt;span class="o"&gt;+------+&lt;/span&gt;&lt;span class="n"&gt;Physical&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;RP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;uuid5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;eth2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                         &lt;span class="n"&gt;traits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CUSTOM_PHYSNET_3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CUSTOM_VNIC_TYPE_DIRECT&lt;/span&gt;
                         &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                         &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;VF&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# VF resource is out of scope&lt;/span&gt;
                          &lt;span class="n"&gt;NET_BW_IGR_KILOBIT_PER_SEC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="n"&gt;NET_BW_EGR_KILOBIT_PER_SEC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Custom traits will be used to indicate which physical network a given
Physical network interface RP is connected to, as previously described.&lt;/p&gt;
&lt;p&gt;Custom traits will be used to indicate which &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vnic_type&lt;/span&gt;&lt;/code&gt; a backend
supports so different backend technologies can be distinguished, as previously
described.&lt;/p&gt;
&lt;p&gt;The current purpose of agent RPs is to allow us detecting the deletion of an
RP. Later we may also start to model agent-level resources and capabilities.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="report-directly-or-indirectly"&gt;
&lt;h4&gt;Report directly or indirectly&lt;/h4&gt;
&lt;p&gt;Considering only agent-based MechanismDrivers we have two options:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;direct: The agent reports resource providers, traits and inventories
directly to the Placement API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;indirect: The agent reports resource providers, traits and
inventories to Neutron-server which in turn reports the information
to the Placement API.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both have pros and cons. Direct reporting involves fewer components
therefore it’s more efficient and more reliable. On the other hand
freshness of the resource information may be important information in
itself. Nova has the compute heartbeat mechanism to ensure scheduler
considers the live Placement records only. In case freshness of Neutron
resource information is needed the only practical way is to build
on the Neutron-agent heartbeat mechanism. Otherwise the reporting
and heartbeat mechanism would take different paths. If resource
information is reported through the agent heartbeat mechanism then
freshness of resource information is known by Neutron-server and other
components (for example a nova scheduler filter) could query it from
Neutron-server.&lt;/p&gt;
&lt;p&gt;When Placement and nova-scheduler choose to allocate the requested
bandwidth on a particular network resource provider (that represents
a physical network interface) that choice has its implications on:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron-server’s choice of a Neutron backend for a port.
(vif_type, vif_details)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron-agent’s choice of a physical network interface.
(Only in some cases like when multiple SR-IOV PFs back one physnet.)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The later choices (of neutron-server and neutron-agent) must respect the
first (in the allocation), otherwise resources could be used somewhere
else than allocated.&lt;/p&gt;
&lt;p&gt;The choice in the allocation can be easily communicated to Neutron
using the chosen network resource provider UUID if this UUID is known
to both Neutron-server and Neutron-agent. If available resources are
reported directly from Neutron-agent to Placement then Neutron-server
may not know about resource provider UUIDs. Therefore indirect reporting
is recommended.&lt;/p&gt;
&lt;p&gt;Even when reporting indirectly we must keep the (Neutron reported part
of the) content of the Placement DB under the as direct as possible control
of Neutron agents. It is best to keep Neutron-server in a basically
proxy-like role.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="content-and-format-of-resource-information-reported-from-agent-to-server"&gt;
&lt;h4&gt;Content and format of resource information reported (from agent to server)&lt;/h4&gt;
&lt;p&gt;We propose to extend the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;configurations&lt;/span&gt;&lt;/code&gt; field of the agent heartbeat
RPC message.&lt;/p&gt;
&lt;p&gt;Beyond the agent’s hardcoded set of supported &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vnic_types&lt;/span&gt;&lt;/code&gt; the following
agent configuration options are the input to extend the heartbeat message:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;bridge_mappings&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;physical_device_mappings&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_provider_bandwidths&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If needed further options controlling inventory attributes like:
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;allocation_ratio&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;min_unit&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;max_unit&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;step_size&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reserved&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Based on the input above the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;configurations&lt;/span&gt;&lt;/code&gt; dictionary of the
heartbeat message shall be extended with the following keys:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;(custom) &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;traits&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_providers&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_provider_inventories&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_provider_traits&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The values must be (re-)evaluated after the agent configuration is
(re-)read. Each heartbeat message shall contain all items known by
the agent at that time. The extension of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;configurations&lt;/span&gt;&lt;/code&gt; fields
intentionally mirrors the structure of the placement API (and does not
directly mirror the agent configuration format, though can be derived
from it). The values of these fields shall be formatted so they can be
readily pasted into requests sent to the Placement API.&lt;/p&gt;
&lt;p&gt;Agent resource providers shall be identified by their already existing
Neutron agent UUIDs as shown in the ‘Networking RP model’ section above.&lt;/p&gt;
&lt;p&gt;Neutron-agents shall generate UUIDs for physical network interface
resource providers. Version 5 (name-based) UUIDs should be used by
hashing names like &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;HOSTNAME:OVS-BRIDGE-NAME&lt;/span&gt;&lt;/code&gt; for ovs-agent and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;HOSTNAME:PF-NAME&lt;/span&gt;&lt;/code&gt; for sriov-agent since this way the UUIDs will
be stable through an agent restart.&lt;/p&gt;
&lt;p&gt;Please note that the agent heartbeat message contains traits and their
associations with resource providers, but there’s no traits directly
listed in the agent configurations. This is possible because both physnet
and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vnic_type&lt;/span&gt;&lt;/code&gt; traits we’ll use can be inferred from already known
pieces of information.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="synchronization-of-resource-information-reported"&gt;
&lt;h4&gt;Synchronization of resource information reported&lt;/h4&gt;
&lt;p&gt;Ideally Neutron-agent, Neutron-server and Placement must have the same
view of resources. We propose the following synchronization mechanism
between Neutron-server and Placement:&lt;/p&gt;
&lt;p&gt;Each time Neutron-server learns of a new agent it diffs the heartbeat
message (for traits, providers, inventories and trait associations)
with all objects found in Placement under the agent RP. It creates
the objects missing from Placement. It deletes those missing from the
heartbeat. It updates the objects whose attributes are different in
Placement and the heartbeat.&lt;/p&gt;
&lt;p&gt;At subsequent heartbeats received Neutron-server diffs the new and
the previous heartbeats. If nothing changed no Placement request
is sent. If a change in heartbeats is detected Neutron sends the
appropriate Placement request based on the diff of heartbeats using
the last seen Placement generation number. If the Placement request is
successful Neutron stores the new generation number. If the request
fails with generation conflict Neutron falls back to diffing between
Placement and the heartbeat.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="progress-or-block-until-the-compute-host-rp-is-created"&gt;
&lt;h4&gt;Progress or block until the Compute host RP is created&lt;/h4&gt;
&lt;p&gt;Neutron-server cannot progress to report resource information until
the relevant Nova-compute host RP is created. (The reason being the
Nova-compute host RP UUID is unpredictable to Neutron.) We believe
that while waiting for the Nova-compute host RP a Neutron-server can
progress with its other functions.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="port-binding-changes"&gt;
&lt;h3&gt;Port binding changes&lt;/h3&gt;
&lt;p&gt;The order of relevant operations are the following:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Placement DB is populated with both compute and network resource
information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Triggered by a nova server boot Placement selects a list of candidates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scheduler chooses exactly one candidate and allocates it in a single
transaction. (In some complex nova server move cases the conductor
may allocate but that’s unimportant here.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron binds the port.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In steps (2) and (3) the selection includes the choice of RPs representing
network backend objects (beyond the obvious choice of compute host). This
naturally conflicts with Neutron’s current port binding mechanism.&lt;/p&gt;
&lt;p&gt;To solve the conflict we must make sure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Placement must produce candidates whose ports later can be bound by
Neutron. (At least with roughly the same probability as scheduler is
able today.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The choices made by Placement and made by Neutron port binding must
be the same. Therefore the selection must be coordinated.&lt;/p&gt;
&lt;p&gt;If more than one Neutron backend can satisfy the resource requirements
of a port on the same host then it cannot happen that Placement chooses
one, but Neutron binds another.&lt;/p&gt;
&lt;p&gt;One way to do that is for Neutron-server to read (from Placement)
the allocation of the port currently being bound and let it influence
the binding. However this introduces a slow remote call in the middle of
port binding therefore it is not recommended.&lt;/p&gt;
&lt;p&gt;Another way is to pass down part of the allocation record in the
call/message chain leading to the port binding PUT request. In the
port binding PUT request use the binding_profile attribute. That way
we would not need a new remote call, just to add an argument/payload
to already existing calls/messages.&lt;/p&gt;
&lt;p&gt;The Nova spec (&lt;a class="footnote-reference brackets" href="#id19" id="id14" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;) proposes that the resources requested for a port
are included in a numbered request group (see &lt;cite&gt;Granular Resource Request
Syntax&lt;/cite&gt; &lt;a class="footnote-reference brackets" href="#id25" id="id15" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;). A numbered request group is always matched by a single
resource. In general Neutron needs to know which resource provider
matched the numbered request group of the port.&lt;/p&gt;
&lt;p&gt;To express the choice made by placement and nova-scheduler we propose
to add an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;allocation&lt;/span&gt;&lt;/code&gt; entry to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding_profile&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"port with minimum bw being bound"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"network_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"binding_profile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"allocation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RP_UUID&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If a port has the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; attribute then it must
be bound with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding_profile.allocation&lt;/span&gt;&lt;/code&gt; supplied. Otherwise
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding_profile.allocation&lt;/span&gt;&lt;/code&gt; must not be present.&lt;/p&gt;
&lt;p&gt;Usually ML2 port binding tries the mechanism drivers in their
configuration order until one succeeds to set the binding. However
if a port being bound has &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding_profile.allocation&lt;/span&gt;&lt;/code&gt; then only a
single mechanism driver can be tried - the one implicitly identified by
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RP_UUID&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In case of hierarchical port binding &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding_profile.allocation&lt;/span&gt;&lt;/code&gt;
is meant to drive the binding only on the binding level that represents
the closest physical interface to the nova server.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="out-of-scope"&gt;
&lt;h3&gt;Out of Scope&lt;/h3&gt;
&lt;p&gt;Minimum bandwidth rule update:
When a minimum bandwidth rule is updated, the ML2 plugin will list the bound
ports with this QoS policy and rule attached and will update the Allocation
value. The &lt;cite&gt;consumer_id&lt;/cite&gt; of each Allocation is the &lt;cite&gt;device_id&lt;/cite&gt; of the port.
This is out of scope in this spec and should be done during the work related
to &lt;cite&gt;os-vif migration tasks&lt;/cite&gt; &lt;a class="footnote-reference brackets" href="#id22" id="id16" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Trunk port:
Subports of a trunk port are unknown to Nova. Allocating resources for
subports is a task for Neutron only. This is out of scope too.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functional tests.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Agent-server interactions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fullstack.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Handling agent failure cases.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest API tests.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Port API extended with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extensions of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding_profile&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest scenario tests.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;End-to-end feature test.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In test frameworks where we cannot depend on Nova we can mock it away by:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Creating and binding the port as Nova would have done it, including.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Setting its &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding_profile&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Setting its &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding_host_id&lt;/span&gt;&lt;/code&gt; as if Placement and Scheduler would
have chosen the host.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="upgrade"&gt;
&lt;h3&gt;Upgrade&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When upgrading a system with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;minimum_bandwidth&lt;/span&gt;&lt;/code&gt; rules to support
both data plane and placement enforcement we see two options:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;It is the responsibility of the admin to create the
allocations in Placement for all ports using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;minimum_bandwidth&lt;/span&gt;&lt;/code&gt;
rules. Please note: this assumes that bandwidth is not overallocated
at the time of upgrade.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add tooling for 1. as described in the ‘Upgrade impact’ section of &lt;a class="footnote-reference brackets" href="#id19" id="id17" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The desired upgrade order of components is the following:
Placement, Nova, Neutron&lt;/p&gt;
&lt;p&gt;If for some reason the reverse Neutron-Nova order is desired, then the
Neutron port API extension of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; must not be turned on
until both components are upgraded.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron-server must be able to handle agent heartbeats both with
and without resource information in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;configurations&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;These work items are designed so Neutron end-to-end behavior can be
prototyped and tested independently of the progress of related work in
Nova. But part of it depends on already available Placement features.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Extend agent heartbeat configuration with resource provider information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(We already have it): Persist extended agent configuration reported via
heartbeat.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(We already have it): Placement client in neutron-lib for the use of
neutron-server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron-server initially diffs resource info reported by agent against
Placement.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron-server diffs consequent agent heartbeat configurations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron-server turns the diffs into Placement requests (with generation
handling).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend rule &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qos_minimum_bandwidth_rule&lt;/span&gt;&lt;/code&gt; with direction &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ingress&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend port with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_request&lt;/span&gt;&lt;/code&gt; based on QoS rule
mimimum-bandwidth-placement.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make the reported agent configuration queriable so neutron-server can
infer which backend is implied in the RP allocated (as in
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding_profile.allocation&lt;/span&gt;&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In binding a port with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding_profile.allocation&lt;/span&gt;&lt;/code&gt; replace the list of
tried mechanism drivers with the one-element list of the inferred backend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(We already have it): Send &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;binding_profile&lt;/span&gt;&lt;/code&gt; to all agents.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In sriov-agent force the choice of PF as implied by the RP allocated.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For each of the above:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: api-ref, devref, networking guide.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Release notes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id18" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;Placement API&lt;/cite&gt;:
&lt;a class="reference external" href="https://docs.openstack.org/nova/latest/user/placement.html"&gt;https://docs.openstack.org/nova/latest/user/placement.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id19" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id10"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id13"&gt;3&lt;/a&gt;,&lt;a role="doc-backlink" href="#id14"&gt;4&lt;/a&gt;,&lt;a role="doc-backlink" href="#id17"&gt;5&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;SPEC: Network bandwidth resource provider&lt;/cite&gt;:
&lt;a class="reference external" href="https://review.openstack.org/502306"&gt;https://review.openstack.org/502306&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id20" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id3"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id4"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;Add a spec for strict minimum bandwidth support&lt;/cite&gt;:
&lt;a class="reference external" href="https://review.openstack.org/396297"&gt;https://review.openstack.org/396297&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id21" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id9"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;[RFE] Minimum bandwidth support (egress)&lt;/cite&gt;:
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1560963"&gt;https://bugs.launchpad.net/neutron/+bug/1560963&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id22" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id16"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;BP: os-vif migration tasks&lt;/cite&gt;:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/os-vif-migration"&gt;https://blueprints.launchpad.net/neutron/+spec/os-vif-migration&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id23" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;Newton Release Notes&lt;/cite&gt;:
&lt;a class="reference external" href="https://docs.openstack.org/releasenotes/neutron/newton.html"&gt;https://docs.openstack.org/releasenotes/neutron/newton.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id24" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;Networking Guide: SR-IOV&lt;/cite&gt;:
&lt;a class="reference external" href="https://docs.openstack.org/neutron/queens/admin/config-sriov.html#enable-neutron-sriov-agent-compute"&gt;https://docs.openstack.org/neutron/queens/admin/config-sriov.html#enable-neutron-sriov-agent-compute&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id25" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id15"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;Granular Resource Request Syntax&lt;/cite&gt;:
&lt;a class="reference external" href="https://specs.openstack.org/openstack/nova-specs/specs/rocky/approved/granular-resource-requests.html"&gt;https://specs.openstack.org/openstack/nova-specs/specs/rocky/approved/granular-resource-requests.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id26" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id12"&gt;9&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;any-traits-in-allocation_candidates-query&lt;/cite&gt;:
&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/any-traits-in-allocation-candidates-query"&gt;https://blueprints.launchpad.net/nova/+spec/any-traits-in-allocation-candidates-query&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id27" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;10&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;QoS devref&lt;/cite&gt;:
&lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/contributor/internals/quality_of_service.html#agent-backends"&gt;https://docs.openstack.org/neutron/latest/contributor/internals/quality_of_service.html#agent-backends&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id28" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id11"&gt;11&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;SPEC: Prep work for Network aware scheduling (Pike)&lt;/cite&gt;:
&lt;a class="reference external" href="https://specs.openstack.org/openstack/nova-specs/specs/pike/approved/prep-for-network-aware-scheduling-pike.html"&gt;https://specs.openstack.org/openstack/nova-specs/specs/pike/approved/prep-for-network-aware-scheduling-pike.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 13 Nov 2018 00:00:00 </pubDate></item><item><title>QoS DSCP marking support</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/newton/ml2-qos-with-dscp.html</link><description>

&lt;p&gt;RFE: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1468353"&gt;https://bugs.launchpad.net/neutron/+bug/1468353&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The current &lt;a class="reference external" href="https://review.openstack.org/#/c/88599/"&gt;QoS API&lt;/a&gt; does not
provide functionality to mark outgoing network traffic with a DSCP value. This
proposal talks about enhancing the existing QoS API’s by adding DSCP marking
support. The functionality will make use of the Open vSwitch support for adding
DSCP marks to the outbound network traffic.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;We propose an update to the QoS API and OVS driver to support DSCP marks.
Valid DSCP mark values are even numbers between 0 and 56, except 2-6, 42, 44,
and 50-54.  The full list of valid DSCP marks is:&lt;/p&gt;
&lt;p&gt;0, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 46, 48, 56&lt;/p&gt;
&lt;p&gt;This will serve as the reference implementation for how to use the QoS API to
manage DSCP marks using the OVS driver.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;The model follows the way that the QoS Bandwidth Limiting functionality applies
to QoS policies by adding a QosDscpMarkingRule table.&lt;/p&gt;
&lt;p&gt;The QosDscpMarkingRule model would look like:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;qos_policy_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;QoSPolicy
reference&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;dscp_mark&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, tenant&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0 and 56, except
2-6, 42, 44, and
50-54&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;DSCP Mark&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Proposed attribute:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;SUB_RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s1"&gt;'dscp_marking_rules'&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
        &lt;span class="s1"&gt;'parent'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'collection_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'policies'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'member_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'policy'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'parameters'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QOS_RULE_COMMON_FIELDS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'dscp_mark'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;common_constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
                            &lt;span class="n"&gt;VALID_DSCP_MARKS&lt;/span&gt;&lt;span class="p"&gt;}}})&lt;/span&gt;
              &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Sample REST calls:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;policies&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"AF32"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"This policy marks DSCP outgoing AF32 traffic for DTV Control"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"False"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;policies&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;tenant-id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"AF32"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"This policy marks DSCP outgoing AF32 traffic for DTV Control"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"dscp_marking_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;policy-uuid&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"dscp_mark"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
        &lt;span class="p"&gt;}]&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;policies&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;dscp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;marking&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"dscp_marking_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"dscp_mark"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"dscp_marking_rule"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;policy-uuid&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"dscp_mark"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;policies&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;dscp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;marking&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"dscp_marking_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"dscp_mark"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"dscp_marking_rule"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;policy-uuid&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"dscp_mark"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="command-line-client-impact"&gt;
&lt;h3&gt;Command Line Client Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;qos-dscp-marking-rule-create &amp;lt;policy-id&amp;gt; –dscp_mark &amp;lt;value&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;qos-dscp-marking-rule-show &amp;lt;mark-rule-id&amp;gt; &amp;lt;policy-id&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;qos-dscp-marking-rule-list &amp;lt;policy-id&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;qos-dscp-marking-rule-update &amp;lt;mark-rule-id&amp;gt; &amp;lt;policy-id&amp;gt; –dscp_mark &amp;lt;value&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;qos-dscp-marking-rule-delete &amp;lt;mark-rule-id&amp;gt; &amp;lt;policy-id&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Deployers may need to configure the specific QoS driver / ML2 agent extension.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;The ability to set DSCP marks on QoS policies on ports or networks using OVS.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;victor-r-howard&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;nate-johnston&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;james-reeves5546&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;margaret-frances&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Versioned DB objects for the new rule type&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API changes to allow for DSCP API modifications&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client changes to allow for DSCP values being set&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Openflow integration within OVS driver to add qos_dscp marking functionality&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API-tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Creating DSCP values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updating DSCP values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deleting DSCP values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Listing DSCP values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Showing a DSCP Value&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional tests will be used to verify system interactions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Setting DSCP values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updating DSCP values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deleting DSCP values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Listing DSCP values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensure traffic is using DSCP marks outbound&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="fullstack-tests"&gt;
&lt;h3&gt;Fullstack Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Setting a QoS policy for marking on a port from API, inspecting that the low-level system bits are set to do DSCP correctly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updating QoS policy, and checking the low bits (DSCP mark bits)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deleting QoS policy and verifying all the DSCP rules are deleted properly or not&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Existing &lt;a class="reference external" href="https://github.com/openstack/openstack-manuals/blob/master/doc/networking-guide/source/adv-config-qos.rst"&gt;Networking Guide&lt;/a&gt;
will be updated for this feature.&lt;/p&gt;
&lt;p&gt;Existing &lt;a class="reference external" href="https://github.com/openstack/openstack-manuals/blob/master/doc/cli-reference/source/neutron.rst"&gt;CLI guide&lt;/a&gt;
will be updated for this feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Existing &lt;a class="reference external" href="https://github.com/openstack/neutron/blob/master/doc/source/devref/quality_of_service.rst"&gt;QoS devref document&lt;/a&gt;
will be updated for this feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-documentation"&gt;
&lt;h3&gt;API Documentation&lt;/h3&gt;
&lt;p&gt;Existing &lt;a class="reference external" href="https://review.openstack.org/#/c/226834/"&gt;QoS API documentation&lt;/a&gt; will be updated for this feature.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/88599/"&gt;QoS API spec&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/master/doc/source/devref/quality_of_service.rst"&gt;QoS devref&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/226834/"&gt;QoS API doc&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 16 Jul 2018 00:00:00 </pubDate></item><item><title>Neutron Stadium Evolution</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/newton/neutron-stadium.html</link><description>

&lt;p&gt;The objective of this specification is three-fold:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Define what the Neutron Stadium is.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define the meaning of the networking community within OpenStack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define guidelines on how to maintain the Stadium over time.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Neutron grew to become a big monolithic codebase, and its core team had a
tough time making progress on a number of fronts, like adding new
features, ensuring stability, etc. During the Kilo timeframe, a
decomposition &lt;a class="reference external" href="http://specs.openstack.org/openstack/neutron-specs/specs/kilo/core-vendor-decomposition.html"&gt;effort&lt;/a&gt;
started, where the codebase got disaggregated into separate efforts, like
the high level services, and the various third-party solutions for L2
and L3 services.&lt;/p&gt;
&lt;p&gt;The outcome of that initiative has yielded mixed results, nonetheless giving
the various individual teams that came out of it the opportunity to iterate
faster and reduce the time to feature. This has been due to the increased
autonomy and implicit trust model that made the lack of oversight of the
PTL and the Neutron drivers/core team acceptable for a small number of
initiatives. However, the proposed &lt;a class="reference external" href="https://review.openstack.org/#/c/175952/"&gt;arrangement&lt;/a&gt;
made it possible for projects to be &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/governance/commit/?id=321a020cbcaada01976478ea9f677ebb4df7bd6d"&gt;automatically&lt;/a&gt;
enlisted as a Neutron project based simply on description, and desire for
affiliation. With the ever growing number of inclusions, the mission of the
PTL/drivers team of ensuring consistency in the APIs, architecture, design,
implementation and testing of the project, as well as a level of quality in
all aspects, like documentation, inter-project communication, release
management, stable backports etc are dealt with have become harder and harder.
The point about uniform APIs is particularly important, because the Neutron
platform is so flexible that a project can take a totally different turn in
the way it exposes functionality, that it is virtually impossible for the
PTL and the drivers team to ensure that good API design principles are being
followed over time. In a situation where each project is on its own, that
might be acceptable, but allowing independent API evolution while still under
the Neutron umbrella is counterproductive.&lt;/p&gt;
&lt;p&gt;In a nutshell, the existing arrangement of conceding autonomy, and striving
for consistency is clearly challenging because of the two conflicting forces
at play. A better balance must be struck in a way that Neutron development
can continue on its trajectory of agile development without compromising
consistency, and without making the PTL, and the Neutron team a bottleneck
in the day to day management duties of the project.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The Neutron Stadium is the list of projects that show up in the following document:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://governance.openstack.org/tc/reference/projects/neutron.html"&gt;https://governance.openstack.org/tc/reference/projects/neutron.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The list includes projects that the Neutron PTL and core team are directly
involved in, and manage on a day to day basis. To do so, the PTL and team
ensure that common practices and guidelines are followed throughout the Stadium,
for all aspects that pertain software development, from inception, to coding,
testing, documentation and more.&lt;/p&gt;
&lt;p&gt;The Stadium is not to be intended as a VIP club for OpenStack networking
projects, or an upper tier within OpenStack. It is simply the list of projects
the Neutron team and PTL claim responsibility for when producing Neutron
deliverables throughout the release &lt;a class="reference external" href="https://github.com/openstack/releases"&gt;cycles&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This spec proposes how the current list (as of May 2016) needs to be revised in
order to maintain the integrity of the Stadium, and how to ensure this
integrity be maintained over time when modifications to the list are required.&lt;/p&gt;
&lt;section id="when-is-a-project-part-of-the-stadium"&gt;
&lt;h3&gt;When is a project part of the Stadium?&lt;/h3&gt;
&lt;p&gt;In order to be considered part of the Stadium, a project must show a track
record of alignment with the Neutron core project. This means showing proof
of adoption of practices as led by the Neutron core team. Some of these
practices are typically already followed by the most mature OpenStack
projects and should not be perceived as particularly stringent:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;exhaustive documentation: it is expected that each project will have a
developer, user/operator and API guide, reachable from docs.o.o;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;exhaustive OpenStack CI coverage (unit, functional, tempest), using
OpenStack CI (upstream) resources (this means using infra CI, not just
downstream CI, as Grafana support will be required); access to CI
resources and historical data by the team is key to ensuring stability
and robustness of a project;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;good release footprint, according to the chosen release model;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;adherence to deprecation and stable backports policies;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;demonstrated ability to do &lt;a class="reference external" href="https://governance.openstack.org/tc/reference/tags/assert_supports-upgrade.html"&gt;upgrades&lt;/a&gt;
and/or &lt;a class="reference external" href="https://governance.openstack.org/tc/reference/tags/assert_supports-rolling-upgrade.html"&gt;rolling upgrades&lt;/a&gt;,
where applicable;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;adoption of neutron-lib (with related hacking rules applied), and proof
of good decoupling from Neutron core internals; having unit tests executed
against neutron-lib changes is also beneficial in order to show stability
of the project;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;develop client bindings and CLI according to OSC transition &lt;a class="reference external" href="https://github.com/openstack/python-neutronclient/blob/master/doc/source/devref/transition_to_osc.rst"&gt;plan&lt;/a&gt;
(where applicable). This means that Neutron Stadium projects will have
their client side hosted in python-neutronclient.
The problem stems from the fact that some service extensions do not
release on pypi (like fw, vpn or lb) thus it is difficult to get hold of
client extensions where they need to be used. SFC and L2GW, for example,
do release on pypi so that is not so much a problem for them. In theory
their client extensions can stay colocated within their tree but that
would make more difficult the alignment to the OSC plugin model. Since
the recommendation is to keep extensions in the python-neutronclient
tree, it is beneficial to have a consistent approach where all Stadium
client extensions are part of the python-neutronclient tree to avoid
confusion when dealing with exceptions to the rule;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;adoption of neutron-api: submission of any API change must follow the
Neutron &lt;a class="reference external" href="http://docs.openstack.org/developer/neutron/policies/blueprints.html"&gt;RFE submission process&lt;/a&gt;,
where specifications to neutron-specs may be required;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;adoption of modular interfaces to provide networking services: this means
that L2/7 services are provided in the form of ML2 mech drivers and
service plugins respectively. A service plugin can expose a driver
interface to support multiple backend technologies, and/or adopt the
flavor framework as necessary.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;The last two criteria are particularly important for the following reasons:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;To provide a consistent API experience to Neutron users/operators and assist
Neutron developers more closely. This can only be achieved when API proposals
and changes are funneled through a single initiative.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To provide composable networking solutions: the ML2/Service plugin framework
was introduced many cycles ago to enable users with freedom of choice. Many
solutions have switched to using ML2/Service plugins for high level services
over the years. Although some plugins still use the core plugin interface
to provide end-to-end solutions, the criterion to enforce the adoption
of ML2 and service plugins for Neutron Stadium projects does not invalidate,
nor does make monolithic solutions deprecated. It is simply a reflection of the
fact that the Neutron team stands behind composability as one of the promise of
open networking solutions. During code review the Neutron team will continue
to ensure that changes and design implications do not have a negative impact
on out of tree code irrespective of whether it is part of the Stadium project
or not.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;When a project is to be considered part of the Stadium, proof of compliance to
the aforementioned practices will have to be demonstrated typically for at
least two OpenStack releases. Application for inclusion is to be considered
only within the first milestone of each OpenStack cycle, which is the time when
the PTL and Neutron team do release planning, and have the most time available
to discuss governance issues.&lt;/p&gt;
&lt;p&gt;Projects part of the Neutron Stadium have typically the first milestone to get
their house in order, during which time reassessment happens; once removed, a
project cannot reapply within the same release cycle it has been evicted.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="what-if-a-project-cannot-be-considered-part-of-the-stadium"&gt;
&lt;h3&gt;What if a project cannot be considered part of the Stadium?&lt;/h3&gt;
&lt;p&gt;The aforementioned criteria imply that the Neutron PTL is unable to favorably
consider a project for inclusion, unless all the criteria are met. This in turn
imposes that new initiatives start as standalone projects hosted on the
openstack.org namespace, as outlined in the &lt;a class="reference external" href="http://docs.openstack.org/infra/manual/creators.html"&gt;creator guide&lt;/a&gt;.
Furthermore, projects that interact with Neutron purely via its REST API should
also be incentivized to seek other forms of governance, such as applying as
top-level OpenStack project and follow the new project requirements as outlined
by the &lt;a class="reference external" href="https://governance.openstack.org/tc/reference/new-projects-requirements.html"&gt;OpenStack Governance&lt;/a&gt;,
rather than going for Stadium inclusion.
Drivers that leverage proprietary software and/or hardware will also not be
considered for inclusion into the Neutron Stadium, due to the barrier on
access to the technology for dev/test and CI integration, as well as the inability
for the Neutron team to provide effective feedback during review for any aspect of
software development: from code to infrastructure and testing. This does not mean
that the Neutron team will stop collaborating with the individual teams supporting
these initiatives (as past experiences demonstrate), and in fact any team is
encouraged to seek collaboration in order to address integration issues with the
core Neutron platform. Teams for projects outside the Stadium are simply fully
responsible of dealing with the end-to-end SDLC of their solutions, and thus
empowered. The integration code to external systems can still be hosted on openstack.org
irrespective of their nature and get access to the same resources any other
OpenStack project uses. It is noteworthy that it may not be useful for them to seek
inclusion on governance.openstack.org in order to achieve ‘recognition’ in that
they are typically one layer underneath the projects that are considered for
inclusion by the TC. Besides, other programs, like the marketplace driver
certification program are more effective tools to reflect the level of quality
of a specific driver solution, as they also track the level of supportability
across the various OpenStack releases.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="what-if-a-project-within-the-neutron-stadium-decides-to-include-drivers-for-proprietary-systems"&gt;
&lt;h3&gt;What if a project within the Neutron Stadium decides to include drivers for proprietary systems?&lt;/h3&gt;
&lt;p&gt;Today’s reality is that some Neutron projects still host drivers to proprietary
systems, like vpnaas, fwaas, and lbaas/octavia; even though the decision of accepting
new drivers lies with the respective teams, it is strongly encouraged that these be
exceptions rather than the norm. This point becomes less relevant if, in the long run
some of these efforts will no longer be considered responsibility of the Neutron team.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="how-do-we-build-a-networking-community"&gt;
&lt;h3&gt;How do we build a Networking Community?&lt;/h3&gt;
&lt;p&gt;Neutron has been, since its inception, the networking project within
OpenStack. It has been &lt;em&gt;the&lt;/em&gt; place where APIs and networking abstractions
are proposed and agreed on. There have been deadlocks and stalemates as
in any other project, and one way to resolve these stalemates is to
allow individual initiatives to experiment in isolation: ultimately code
wins. Even though this might seem okay at first, Neutron still lack the
ability to reconcile all these initiatives back together in a coherent
fashion.&lt;/p&gt;
&lt;p&gt;In order to resolve this problem, the Neutron team should consider the
adoption of a neutron-api initiative where API proposals are consolidated.
The neutron-api project can be a component to be consumed by Neutron Stadium
projects, and to be started off as a spinout of the neutron api codebase such
as neutron/api, neutron/extensions, and any other project (e.g. bgp, l2gw,
sfc, etc) that is considered for Stadium inclusion. Contributions to this
module will follow the Neutron RFE process with submission of specification
documents to neutron-specs, if deemed required. The resulting code will end
up being located in the api module itself, whilst specs will be hosted on
neutron-specs. Each core team of projects belonging to the Stadium will
have +2 rights on &lt;a class="reference external" href="https://review.openstack.org/#/admin/groups/314,members"&gt;neutron-specs&lt;/a&gt;.
The neutron drivers will continue to hold +W rights on both repos. It is noteworthy that
members of the individual core teams are and will be considered for membership
of the drivers team on a regular basis. Level of participation in reviewing
RFE submissions, experience with the Neutron codebase, and commitment to the
project are factors taken into account when identifying members of this team.
From an implementation perspective, the api module can either exist on its own,
as yet another repo within the Stadium list, or be incorporated as a /api module
under neutron-lib. Whilst the former approach allows finer control of the
release model, the latter has the obvious benefit of minimizing complexity in
landing end-to-end code changes.&lt;/p&gt;
&lt;p&gt;The reason behind the existence of this effort and the requirement to go
through neutron-specs for API proposals is two-fold: a) ensure continuous
alignment across all APIs exposed from Neutron Stadium projects; b) provide
a place in the OpenStack networking community to discuss and achieve consensus
on networking abstractions; and c) as a robust foundation to build
interoperable APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="what-happens-to-the-current-list-of-neutron-stadium-projects"&gt;
&lt;h3&gt;What happens to the current list of Neutron Stadium projects?&lt;/h3&gt;
&lt;p&gt;At the time of writing the Stadium contains the projects as outlined below.
Based on all the aforementioned considerations, all of individual teams will
have to work during the Newton timeframe to make the current proposal a reality.
More precisely, to be considered for inclusion (continue to be part of the
Stadium list), the following plan must be put in place:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;neutron: the core team will have to stand up neutron-api, and transition
the api models/definitions out of the neutron repo. Developer documentation
on the &lt;a class="reference external" href="http://docs.openstack.org/developer/neutron/#neutron-stadium"&gt;Neutron Stadium&lt;/a&gt;
will be revised according to the guidelines outlined in this proposal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;neutron-fwaas: the fwaas core team will have to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;complete the transition to fwaas v2;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;adopt neutron-api, and neutron-lib;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;complete docs, end-to-end testing, and demonstrate ability to upgrade;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;neutron-lbaas: the existence of this project is now questioned by the
presence of Octavia. This is elaborated more in &lt;a class="reference external" href="https://review.openstack.org/#/c/310805/"&gt;spinout&lt;/a&gt; spec.
In a nutshell, this project will be phased out in favor of Octavia being
an OpenStack top-level project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;neutron-vpnaas: this project has seen the least amount of traction during
the last few &lt;a class="reference external" href="http://docs.openstack.org/releasenotes/neutron-vpnaas/mitaka.html"&gt;cycle&lt;/a&gt;.
Testing and documentation is not adequate therefore the vpnaas core team
will have to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;adopt neutron-api, and neutron-lib;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;complete docs, end-to-end testing, and demonstrate ability to upgrade;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;switch to OSC plugin;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;neutron-dynamic-routing: this is a spinout of BGP code that landed
in the Mitaka timeframe. Currently in progress.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;networking-l2gw: this needs to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;adopt neutron-api, and neutron-lib;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;complete docs, end-to-end testing, and demonstrate ability to upgrade;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;move client side code to python-neutronclient and switch to OSC plugin;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;networking-bagpipe: the core team will have to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;adopt neutron-api, and neutron-lib;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;complete docs, end-to-end testing, and demonstrate ability to upgrade;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;networking-bgpvpn: the core team will have to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;adopt neutron-api, and neutron-lib;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;complete docs, end-to-end testing, and demonstrate ability to upgrade;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;move client side code to python-neutronclient and switch to OSC plugin;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;networking-calico: the core team will have to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;adopt neutron-api, and neutron-lib;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;complete docs, end-to-end testing, and demonstrate ability to upgrade;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;networking-midonet: the core team will have to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;adopt neutron-api, and neutron-lib;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;complete docs, end-to-end testing, and demonstrate ability to upgrade;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;move client side code to python-neutronclient and switch to OSC plugin;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;networking-odl: the core team will have to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;adopt neutron-api, and neutron-lib;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;complete docs, end-to-end testing, and demonstrate ability to upgrade;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;networking-ofagent: this is deprecated and marked for removal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;networking-onos: the core team will have to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;adopt neutron-api, and neutron-lib;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;complete docs, end-to-end testing, and demonstrate ability to upgrade;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;networking-ovn: the OVN project will need to consider switching back to
an ML2 driver. This is beneficial for the following reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;considered as a solution for multi-hypervisor deployments: this is
currently only true if a hypervisor runs Open vSwitch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;present itself as a viable alternative to supplant the ovs mech_driver
in the OpenStack gate: this can only be done  so if we are swapping
like for like.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;do bare-metal and virtual provisioning in the context of the same
Neutron deployment; hardware vtep support only is limiting a number
of potential bare metal scenarios that leverage third party solutions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;getting access to a number of performance/reliability enhancements
that the Neutron team develops against ML2.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Composability of services across the entire L2-L7 stack.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;networking-sfc: the core team will have to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;adopt neutron-api, and neutron-lib;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;complete docs, end-to-end testing, and demonstrate ability to upgrade;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;move client side code to python-neutronclient and switch to OSC plugin;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;octavia: this is being tackled in the context of neutron-lbaas. In a
nutshell, this will eventually be considered as top-level OpenStack
project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;python-neutron-pd-driver: this is a project that depends on Neutron IPv6
support and introduces another prefix delegation driver besides the one
available in tree. With the in-tree implementation of dibbler this is
not as necessary any more. Dropping it in O-1 is an acceptable outcome
if no-one picks it up by then.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Contributing the respective API extensions of these individual projects
to neutron-api does not mean reviewing the APIs from scratch as these
APIs already have working solutions behind them. Having said that, any
revision required, as potentially identified through review, will have
to be followed up according to RFE submission process.
These projects and their respective core teams will be given time to comply
until Ocata Milestone-1, after which, if not compliant, they will be removed
from the Neutron Stadium. All things considered, a team can decide not to
adopt the aforementioned plan and ask to be removed during the Netwon
timeframe.&lt;/p&gt;
&lt;p&gt;This deadline is considered to be firm, but will be revised according to
how fast we can consolidate APIs and neutron-lib mature to a point of
effective consumption by the &lt;a class="reference external" href="https://github.com/openstack/neutron"&gt;neutron&lt;/a&gt;
project and once thorough documentation is provided to help the various
parties through the transition.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="how-can-an-existing-openstack-project-apply-for-inclusion"&gt;
&lt;h3&gt;How can an existing OpenStack project apply for inclusion?&lt;/h3&gt;
&lt;p&gt;There are projects currently hosted on OpenStack that are not part of the
Neutron governance list, for example tap-as-a-service, and there may be more
that may be created in the future. Such initiatives should consider being
part of the Neutron Stadium if and only if there is a mutual and beneficial
collaboration already established across the teams involved. As mentioned
above, the Stadium is not an elite club but simply the projects that the
PTL and the Neutron team take responsibility for. The more involvement and
mutual collaboration exist over time, the more likely it is that there
is good alignement and thus Stadium inclusion becomes a a little more than
a formality.
In order to succeed in an application, a project should first and foremost
make sure that these criteria are met:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;documentation, testing and upgrade strategy are in good order as outlined
earlier;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;client extensions available as OSC plugins;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;adoption of neutron-lib;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The request for application would then need to be submitted with an RFE and
subsequent spec submission where the following information is provided:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;pointers to user and developer documentations;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pointers to server and client side internals;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pointers to CI jobs (e.g. unit, tempest, grenade, etc) as well as Grafana
dashboards;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pointers to stable backports and release deliverables;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pointers to API specification and definitions;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once evaluated and successfully approved via RFE process, the teams will work
together to transition API and client components respectively to api module
and python-neutronclient repos. The newly added project pledge to
adopt the Neutron RFE submission process for API changes (and API changes
alone) and spec submission to neutron-specs where deemed necessary from that
point forward.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="why-is-this-stadium-arrangement-beneficial"&gt;
&lt;h3&gt;Why is this Stadium arrangement beneficial?&lt;/h3&gt;
&lt;p&gt;The Stadium creates a place for like-minded people to collaborate, innovate,
and iterate on networking solutions, and provides a degree of guarantee that
a project belonging to the Stadium behaves similarly to any other project
within the Stadium, thus inducing a more sustainable maintenance effort on
the Neutron team. On the other hand, the Neutron team takes responsibility of
the deliverables produced by Stadium project (docs, release notes, etc), and
therefore giving these initiatives higher visibility to downstream consumers.
Contributors of Neutron Stadium projects participate in the Neutron PTL election
process and have the same status of any other OpenStack Active Technical
Contributor.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="what-are-the-drawbacks-of-this-proposal"&gt;
&lt;h3&gt;What are the drawbacks of this proposal?&lt;/h3&gt;
&lt;p&gt;The cost of sanitizing the Stadium and keeping it sane over time is non
negligible, though the criteria have been designed to be lightweight and impose
minimal burden on the teams once the Stadium is up and running. This is the
trade-off to keep all the networking related efforts working in symbiosis.
Hopefully, it should be clear by now that associating a bad connotation to
projects that are not part of the Stadium is simply a misconception: some
projects can indeed apply to be top-level projects in OpenStack, and others
are simply better off by being independent initiatives.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="are-there-any-alternatives-worth-considering"&gt;
&lt;h3&gt;Are there any alternatives worth considering?&lt;/h3&gt;
&lt;p&gt;Open to suggestions.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/q/topic:stadium-implosion"&gt;https://review.openstack.org/#/q/topic:stadium-implosion&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/q/topic:stadium-redux"&gt;https://review.openstack.org/#/q/topic:stadium-redux&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2015-December/080865.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2015-December/080865.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2016-April/093561.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2016-April/093561.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 12 Jun 2018 00:00:00 </pubDate></item><item><title>Port Mirroring API for VF Mirroring</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stein/port-mirroring-sriov-vfs.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/port-mirroring-sriov-vf"&gt;https://blueprints.launchpad.net/neutron/+spec/port-mirroring-sriov-vf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Port mirroring is a common feature where specific traffic can be mirrored to
a traffic analyzer by configuring rules to identify required flows to be
mirrored and by specifying the analyzer where the traffic is mirrored to.
In addition, mirroring can be configured on VM interfaces to get all the
traffic to and from the interface to the specified analyzer.&lt;/p&gt;
&lt;p&gt;A common use case for this feature is a client requesting an analyzer or probe
for traffic that needs to be monitored for a particular VNF using SR-IOV.&lt;/p&gt;
&lt;p&gt;This spec will focus on port mirroring based on SR-IOV VF to VF. Currently this
document concentrates on tapping traffic coming in and out of VMs using SR-IOV.
This spec is based on enhancements done by Intel on i40e driver, see &lt;a class="footnote-reference brackets" href="#id19" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;9&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The current TAPaaS is implemented with OVS ports, see &lt;a class="footnote-reference brackets" href="#id11" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and &lt;a class="footnote-reference brackets" href="#id13" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, this spec
will implement the same for the SR-IOV ports.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;In virtual environments there are NICs that have capabilities to send a copy
of network packets seen on one VF port attached to VNF to another VF port
attached to a VM analyzer.&lt;/p&gt;
&lt;p&gt;This spec helps leverage the NIC capability to do the mirroring and using Tap as
Service enhancements these features can be configured on hosts and leveraged by
tenants.&lt;/p&gt;
&lt;p&gt;The tenant today can use Neutron APIs to create an SRIOV port using provider
network with VLAN 0 and physical network that is used in nova.conf passthrough_whitelist.
This VF will not have any VLAN filters configured on it. See &lt;a class="footnote-reference brackets" href="#id12" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.
The guest can be configured for multiple VLANs on the same interface. Inside the
guest, sub-interfaces can be configured and can communicate on multiple VLANs.&lt;/p&gt;
&lt;p&gt;There are two approaches that can be used for implementing this.&lt;/p&gt;
&lt;p&gt;1. The tenant can use the binding_profile value_spec e.g guest_vlans to define
which VLANs will be configured inside guest.&lt;/p&gt;
&lt;p&gt;Since the parameter is configured for a VF in the same manner as other PCI
details of a VF, this can be exposed at the same place in the API as other
SRIOV related fields in the binding profile.&lt;/p&gt;
&lt;p&gt;Since this spec only describes features available for SRIOV based implementation
and the NIC(i40e) only allows VLAN filter for filtering of the packets that
need to be mirrored on the NIC, this approach is sufficient until we have a
spec for defining multiple VLAN filters for a direct port or on a VF.&lt;/p&gt;
&lt;p&gt;This will also help operators to look at VF config at one place in system
rather than running multiple APIs to figure out VFs configuration on host.&lt;/p&gt;
&lt;p&gt;2. The second option is to change the TapFlow to include the new field,
vlan_mirror. The TapFlow is the flow classifier for the TapService, so updating
it with the new field will provide the agent with the data it needs to
configure the port.&lt;/p&gt;
&lt;section id="use-case-i-mirroring-of-specific-vlans-to-vf"&gt;
&lt;h3&gt;Use Case I. Mirroring of specific VLANs to VF&lt;/h3&gt;
&lt;p&gt;This use case will handle sending the mirror packets to tap service for a
specific VLAN configured on the monitored VF. There can be multiple VLANs
configured on the VF.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Update Tap as a Service to support VF to VF mirroring.&lt;/p&gt;
&lt;p&gt;The proposed service will allow the tenants to create a tap service instance
with SR-IOV port to which the user can add Neutron ports that need to be
mirrored by creating tap flows from other SR-IOV port/s.&lt;/p&gt;
&lt;p&gt;The user can define various port mirroring flows for the tap service, so one
tap service should be able to handle multiple tap flows.&lt;/p&gt;
&lt;img alt="../../_images/port-mirroring-vfs.png" src="../../_images/port-mirroring-vfs.png"/&gt;
&lt;section id="id5"&gt;
&lt;h3&gt;Use Case I. Mirroring of specific VLANs to VF&lt;/h3&gt;
&lt;p&gt;This spec will also take care of developing a new driver for Tap for
NicSwitchTapDriver that will perform the sysfs implementation for Intel’s
custom i40e driver.&lt;/p&gt;
&lt;img alt="../../_images/tapaas-port-mirroring-vfs.png" src="../../_images/tapaas-port-mirroring-vfs.png"/&gt;
&lt;p&gt;The VFs will be derived from source port and the probe port attached
to TapService. Example of how a user could mirror traffic based upon
VLANs 2,4,6,18-22 to VF 3 of PF p1p1&lt;/p&gt;
&lt;p&gt;# echo add 2,4,6,18-22&amp;gt;/sys/class/net/p1p1/device/sriov/3/vlan_mirror&lt;/p&gt;
&lt;p&gt;Example on how a user could remove VLAN 4, 15-17 from traffic mirroring
at destination VF&lt;/p&gt;
&lt;p&gt;# echo rem 4,15-17&amp;gt;/sys/class/net/p1p1/device/sriov/3/vlan_mirror&lt;/p&gt;
&lt;p&gt;Example on how a user could remove all VLANs from mirroring at VF 3.
# echo rem 0 - 4095&amp;gt;/sys/class/net/p1p1/device/sriov/3/vlan_mirror&lt;/p&gt;
&lt;p&gt;The limitation of this mirror is that the vlan/s monitored get traffic in
BOTH direction on probe or service port.&lt;/p&gt;
&lt;p&gt;The mirrored packets captured on the VF associated with Tap service will
have vlan tags that are specified in field vlan_filter.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;This approach will change data model for TapFlow object to include new
field vlan_filter.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;The implementation will be based on option 2. in section Problem description above.
The change will be made to the TapFlow object to add the vlan_filter field in
order for the ports to be able to filter which traffic to mirror. See &lt;a class="footnote-reference brackets" href="#id14" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;
The vlan_filter can be used to monitor a single vlan or a vlan range so
the values can be specified as a string like “171” or “161-164” or “161-164,171”.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="tap-agent-and-driver-impact"&gt;
&lt;h3&gt;Tap Agent and Driver Impact&lt;/h3&gt;
&lt;p&gt;Tap Agent and driver for direct ports will be developed as per usecases above
to configure NIC via sysfs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="effects-on-existing-tap-as-service-apis"&gt;
&lt;h3&gt;Effects on Existing Tap As Service APIs&lt;/h3&gt;
&lt;p&gt;vlan_filter will be added to TapFlow API to filter the traffic that need to be
mirrored.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="command-line-client-impact"&gt;
&lt;h3&gt;Command Line Client Impact&lt;/h3&gt;
&lt;p&gt;Openstack/Neutron client need to be updated to support TAPaaS. See &lt;a class="footnote-reference brackets" href="#id17" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="heat-support-impact"&gt;
&lt;h3&gt;Heat support Impact&lt;/h3&gt;
&lt;p&gt;The Tap as service resources do not exist in Openstack. We need to create new
heat resources to support that. See &lt;a class="footnote-reference brackets" href="#id18" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;The Tap As a Service Agents need to add support for SR-IOV ports. Need to
develop a framework to support multiple agents. Also define the taas agent for
sriov ports, taas-sriov-agent. Currently there is agent only for ovs.
As part of the implementation a new driver for Tap as a service will be developed
NicSwitchTapDriver as mentioned above in proposal. See &lt;a class="footnote-reference brackets" href="#id16" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;
Earlier an attempt to keep SRIOV params together was done in implementation by
updating the binding profile, the change was abandoned. See &lt;a class="footnote-reference brackets" href="#id15" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;section id="additional-work-to-integrate-with-neutron-stadium"&gt;
&lt;h3&gt;Additional work to integrate with Neutron Stadium&lt;/h3&gt;
&lt;p&gt;Tempest tests for the new agent and driver.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id11" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;TAP as a Service&lt;/cite&gt;:
&lt;a class="reference external" href="https://docs.openstack.org/dragonflow/latest/specs/tap_as_a_service.html"&gt;https://docs.openstack.org/dragonflow/latest/specs/tap_as_a_service.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;Networking Guide: SR-IOV&lt;/cite&gt;:
&lt;a class="reference external" href="https://docs.openstack.org/neutron/queens/admin/config-sriov.html#enable-neutron-sriov-agent-compute"&gt;https://docs.openstack.org/neutron/queens/admin/config-sriov.html#enable-neutron-sriov-agent-compute&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id13" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;Tap-as-a-service spec&lt;/cite&gt;:
&lt;a class="reference external" href="https://review.openstack.org/#/c/256210/"&gt;https://review.openstack.org/#/c/256210/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id14" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;Tap as a Service API REFERENCE&lt;/cite&gt;:
&lt;a class="reference external" href="https://github.com/openstack/tap-as-a-service/blob/master/API_REFERENCE.rst"&gt;https://github.com/openstack/tap-as-a-service/blob/master/API_REFERENCE.rst&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id15" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id10"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;(Old)Implemention of vlan filter for mirroring by changing binding profile in neutron port&lt;/cite&gt;:
&lt;a class="reference external" href="https://review.openstack.org/#/c/594310/"&gt;https://review.openstack.org/#/c/594310/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id16" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;Implementation of vlan filter for mirroing by adding vlan mirror filter to TapFlow&lt;/cite&gt;:
&lt;a class="reference external" href="https://review.openstack.org/#/c/603501/"&gt;https://review.openstack.org/#/c/603501/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id17" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;Heat resources for Tap as Service&lt;/cite&gt;:
&lt;a class="reference external" href="https://review.openstack.org/#/c/591523/"&gt;https://review.openstack.org/#/c/591523/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id18" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;Openstack Client update for support of Tap as Service vlan filter&lt;/cite&gt;
&lt;a class="reference external" href="https://review.openstack.org/#/c/589253/"&gt;https://review.openstack.org/#/c/589253/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id19" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;9&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Intel enhanced i40e driver for support of vlan mirror filtering.
&lt;a class="reference external" href="https://sourceforge.net/projects/e1000/files/i40e%20stable/2.7.12/"&gt;https://sourceforge.net/projects/e1000/files/i40e%20stable/2.7.12/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Mon, 11 Jun 2018 00:00:00 </pubDate></item><item><title>Neutron-vpnaas Scorecard</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stadium/queens/neutron-vpnaas.html</link><description>

&lt;section id="neutron-integration"&gt;
&lt;h2&gt;Neutron integration&lt;/h2&gt;
&lt;ul id="n0"&gt;
&lt;li&gt;&lt;p&gt;N0. Does the project use the Neutron REST API or relies on proprietary backends?&lt;/p&gt;
&lt;p&gt;Yes. Neutron-vpnaas implements its own set of Neutron API extensions on top of
the Neutron core framework and it does so by using the service plugin model.
The API exposed has open source implementations, and it provides a pluggable
mechanism for proprietary backends.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n1"&gt;
&lt;li&gt;&lt;p&gt;N1. Does the project integrate/use neutron-lib?&lt;/p&gt;
&lt;p&gt;Yes. The migration report shows that there are currently 621 total imports.
Neutron is imported 119 times and Neutron-lib 81 times, for a migration
percentage of 40.5000%,&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n2"&gt;
&lt;li&gt;&lt;p&gt;N2. Do project members actively contribute to help neutron-lib achieve its
goal?&lt;/p&gt;
&lt;p&gt;No. None of the project core members have merged anything meaningful into neutron-lib
(source: &lt;a class="reference external" href="https://review.openstack.org/#/q/project:openstack/neutron-lib+status:merged,75"&gt;https://review.openstack.org/#/q/project:openstack/neutron-lib+status:merged,75&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n3"&gt;
&lt;li&gt;&lt;p&gt;N3. Do project members collaborate with the core team to enable subprojects
to loosely integrate with the Neutron core platform by helping with the definition
of modular interfaces?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-vpnaas/commit/7c10c41376f10898347cbc644d8d504b8258c99c"&gt;https://github.com/openstack/neutron-vpnaas/commit/7c10c41376f10898347cbc644d8d504b8258c99c&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n4"&gt;
&lt;li&gt;&lt;p&gt;N4. How does the project provide networking services? Does it use modular interfaces
as provided by the core platform?&lt;/p&gt;
&lt;p&gt;Yes, the VPN agent has been recently re-implemented using the L3 agent extension API.
Please look at &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1692128"&gt;https://bugs.launchpad.net/neutron/+bug/1692128&lt;/a&gt; and
&lt;a class="reference external" href="https://review.openstack.org/#/c/488247/"&gt;https://review.openstack.org/#/c/488247/&lt;/a&gt;. This approach makes the VPN agent easier
to deploy along with the L3 agent.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n5"&gt;
&lt;li&gt;&lt;p&gt;N5. If the project provides new API extensions, have API extensions been discussed
and accepted by the Neutron drivers team? Please provide links to API specs, if
required.&lt;/p&gt;
&lt;p&gt;VPNaaS API was initially created by the neutron core team, and so implicitly had been
agreed upon by previous core team.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul id="d1"&gt;
&lt;li&gt;&lt;p&gt;D1. Does the project have a doc tox target, functional and continuously
working? Provide proof (links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini"&gt;https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/99/502699/125/check/build-openstack-sphinx-docs/a1c179a/html/"&gt;http://logs.openstack.org/99/502699/125/check/build-openstack-sphinx-docs/a1c179a/html/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d2"&gt;
&lt;li&gt;&lt;p&gt;D2. If the project provide API extensions, does the project have an
api-ref tox target, functional and continously working? Provide proof
(links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes. There is an API reference and is being confirmed its accuracy, see:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/447345/"&gt;https://review.openstack.org/#/c/447345/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://developer.openstack.org/api-ref/networking/"&gt;http://developer.openstack.org/api-ref/networking/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-lib/blob/master/api-ref/source/v2/vpnaas.inc"&gt;https://github.com/openstack/neutron-lib/blob/master/api-ref/source/v2/vpnaas.inc&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d3"&gt;
&lt;li&gt;&lt;p&gt;D3. Does the project have a releasenotes tox target, functional and
continously working? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini"&gt;https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/releasenotes/neutron-vpnaas/"&gt;http://docs.openstack.org/releasenotes/neutron-vpnaas/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/99/502699/125/check/build-openstack-releasenotes/6ae0166/html/"&gt;http://logs.openstack.org/99/502699/125/check/build-openstack-releasenotes/6ae0166/html/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d4"&gt;
&lt;li&gt;&lt;p&gt;D4. Describe the types of documentation available: developer, end user,
administrator, deployer.&lt;/p&gt;
&lt;p&gt;Yes. These documentations are going to be published, see:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/482510/"&gt;https://review.openstack.org/#/c/482510/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/522695/"&gt;https://review.openstack.org/#/c/522695/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/99/502699/125/check/build-openstack-sphinx-docs/a1c179a/html/"&gt;http://logs.openstack.org/99/502699/125/check/build-openstack-sphinx-docs/a1c179a/html/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/10/482510/2/check/build-openstack-sphinx-docs/e854440/html/admin/vpnaas-scenario.html"&gt;http://logs.openstack.org/10/482510/2/check/build-openstack-sphinx-docs/e854440/html/admin/vpnaas-scenario.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="continuous-integration"&gt;
&lt;h2&gt;Continuous Integration&lt;/h2&gt;
&lt;ul id="c1"&gt;
&lt;li&gt;&lt;p&gt;C1. Does the project have a Grafana dashboard showing historical trends of
all the jobs available? Provide proof (links to grafana.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://grafana.openstack.org/dashboard/db/neutron-vpnaas-failure-rates"&gt;http://grafana.openstack.org/dashboard/db/neutron-vpnaas-failure-rates&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c2"&gt;
&lt;li&gt;&lt;p&gt;C2. Does the project have CI for unit coverage? Provide proof (links to
logs.openstack.org)&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/g/project/openstack~2Fneutron-vpnaas"&gt;http://status.openstack.org/openstack-health/#/g/project/openstack~2Fneutron-vpnaas&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c3"&gt;
&lt;li&gt;&lt;p&gt;C3. Does the project have CI for functional coverage? If so, does it include
DB migration and sync validation?&lt;/p&gt;
&lt;p&gt;Yes. We have gate-neutron-vpnaas-dsvm-functional-sswan-ubuntu-xenial for
functional coverage and DB migration tests are running as a part of it.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/91/496991/23/check/legacy-neutron-vpnaas-dsvm-functional-sswan/3c51750/"&gt;http://logs.openstack.org/91/496991/23/check/legacy-neutron-vpnaas-dsvm-functional-sswan/3c51750/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c4"&gt;
&lt;li&gt;&lt;p&gt;C4. Does the project have CI for fullstack coverage?&lt;/p&gt;
&lt;p&gt;No. We consider it as lower priority and it has none at the moment.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c5"&gt;
&lt;li&gt;&lt;p&gt;C5. Does the project have CI for Tempest coverage? If so, specify nature
(API and/or Scenario).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/job/neutron-dsvm-tempest-vpnaas"&gt;http://status.openstack.org/openstack-health/#/job/neutron-dsvm-tempest-vpnaas&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c6"&gt;
&lt;li&gt;&lt;p&gt;C6. Does the project require CI for Grenade coverage?&lt;/p&gt;
&lt;p&gt;Yes. But it has none.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c7"&gt;
&lt;li&gt;&lt;p&gt;C7. Does the project provide multinode CI?&lt;/p&gt;
&lt;p&gt;No. But it is needed to support L3-HA (and/or DVR) and unnecessary until then.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c8"&gt;
&lt;li&gt;&lt;p&gt;C8. Does the project support Python 3.x? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/job/openstack-tox-py35-neutron-vpnaas"&gt;http://status.openstack.org/openstack-health/#/job/openstack-tox-py35-neutron-vpnaas&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="release-footprint"&gt;
&lt;h2&gt;Release footprint&lt;/h2&gt;
&lt;ul id="r1"&gt;
&lt;li&gt;&lt;p&gt;R1. Does the project adopt semver?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r2"&gt;
&lt;li&gt;&lt;p&gt;R2. Does the project have release deliverables? Provide proof as available
in the &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/"&gt;release repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://tarballs.openstack.org/neutron-vpnaas/neutron-vpnaas-11.0.0.tar.gz"&gt;https://tarballs.openstack.org/neutron-vpnaas/neutron-vpnaas-11.0.0.tar.gz&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://pypi.org/project/neutron-vpnaas/"&gt;https://pypi.org/project/neutron-vpnaas/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r3"&gt;
&lt;li&gt;&lt;p&gt;R3. Does the project use upper-constraints?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini#L10"&gt;https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini#L10&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="r4"&gt;
&lt;li&gt;&lt;p&gt;R4. Does the project integrate with OpenStack Proposal Bot for requirements updates?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Yes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/requirements/commit/1d545edbebfff2e8983d6cab24a92c32636dd6bf"&gt;https://github.com/openstack/requirements/commit/1d545edbebfff2e8983d6cab24a92c32636dd6bf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="stable-backports"&gt;
&lt;h2&gt;Stable backports&lt;/h2&gt;
&lt;ul id="s1"&gt;
&lt;li&gt;&lt;p&gt;S1. Does the project have stable branches and/or tags? Provide history of
backports.&lt;/p&gt;
&lt;p&gt;Yes. For example: &lt;a class="reference external" href="https://git.openstack.org/cgit/openstack/neutron-vpnaas/log/?h=stable/pike"&gt;https://git.openstack.org/cgit/openstack/neutron-vpnaas/log/?h=stable/pike&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="client-library"&gt;
&lt;h2&gt;Client library&lt;/h2&gt;
&lt;ul id="l1"&gt;
&lt;li&gt;&lt;p&gt;L1. If the project requires a client library, how does it implement CLI and
API bindings?&lt;/p&gt;
&lt;p&gt;Yes. There are Neutron CLI and API bindings. OSC is going to be done, see:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/439978/"&gt;https://review.openstack.org/#/c/439978/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="scorecard"&gt;
&lt;h2&gt;Scorecard&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Scorecard&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n0"&gt;N0&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n1"&gt;N1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n2"&gt;N2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n4"&gt;N4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n5"&gt;N5&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d1"&gt;D1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d3"&gt;D3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c2"&gt;C2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c3"&gt;C3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c4"&gt;C4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c6"&gt;C6&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c7"&gt;C7&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c8"&gt;C8&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r1"&gt;R1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r2"&gt;R2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r3"&gt;R3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r4"&gt;R4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#s1"&gt;S1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="final-remarks"&gt;
&lt;h2&gt;Final remarks&lt;/h2&gt;
&lt;p&gt;At the time of writing the project scores changed to positively if compared
with the last assessment &lt;a class="footnote-reference brackets" href="#id3" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id4" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; for following 7 criteria: &lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt;, &lt;a class="reference internal" href="#n4"&gt;N4&lt;/a&gt;, &lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt;, &lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt;,
&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt;, &lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt;, &lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt;. It makes the project score positively in 20 out of 24 criteria.
The subproject does not seem to lack the resources recently and the remaining
gaps can be focused to make timely progress when required.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata/neutron-vpnaas.html#scorecard"&gt;https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata/neutron-vpnaas.html#scorecard&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata.html#summary"&gt;https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata.html#summary&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Wed, 23 May 2018 00:00:00 </pubDate></item><item><title>Decoupling database API &amp;amp; Utilities imports/access for neutron-lib</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/rocky/neutronlib-decouple-db-apiutils.html</link><description>

&lt;p&gt;This work is not related to an enhancement request and therefore doesn’t have
a RFE. Rather the intent herein is to discuss how we decouple &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron.db&lt;/span&gt;&lt;/code&gt;
and related database imports/access as part of the overall neutron-lib effort.&lt;/p&gt;
&lt;p&gt;Current neutron database access can be broken into the following high-level
categories:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Database API &amp;amp; Utilities&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Core &amp;amp; Extension Database Mixins&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Database Resource Models&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Database Migration&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As the database access patterns span a wide range of logic/code, a set of specs
will be proposed each focusing on a single access pattern.&lt;/p&gt;
&lt;p&gt;This spec specifically addresses the Database API &amp;amp; Utilities access.&lt;/p&gt;
&lt;p&gt;For current neutron-lib related blueprints, see &lt;a class="footnote-reference brackets" href="#id19" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and &lt;a class="footnote-reference brackets" href="#id20" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;As part of our neutron-lib effort, we need to decouple out-of-tree networking
projects that depend on (e.g. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;import&lt;/span&gt;&lt;/code&gt;) neutron. However, today a large
number of neutron consumers import database related neutron modules &lt;a class="footnote-reference brackets" href="#id21" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id22" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;
&lt;a class="footnote-reference brackets" href="#id23" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. While some of these dependencies are rehomeable into neutron-lib without
significant effort, others create a large dependency chain with neutron
internals, coupling them to neutron itself.&lt;/p&gt;
&lt;p&gt;The intent of this spec is to propose how we can rehome the neutron database
API and utilities into neutron-lib breaking consumer dependencies on these
neutron modules. The access patterns herein were gathered by inspecting usages
of the respective modules using &lt;a class="footnote-reference brackets" href="#id21" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, &lt;a class="footnote-reference brackets" href="#id22" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, &lt;a class="footnote-reference brackets" href="#id23" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, &lt;a class="footnote-reference brackets" href="#id24" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This spec proposes we rehome the generic database API/utility functionality
into neutron-lib. The following considerations must be taken into account
for all applicable code:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If the functionality is private and not used outside of neutron today,
it can likely stay in neutron as private to reduce public API surface area.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the functionality is private, but used outside of neutron, it’s a
candidate for rehoming.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For code applicable to rehoming, determine the best form for the
implementation. If used by non-OVO consumers then likely it’ll be
necessary to rehome as “generic database logic”. However if applicable
to OVO, it may make sense to incorporate the logic into neutron objects
that will be rehomed in subsequent work.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When the work for this spec is done, we should no longer have any consumers
using neutron’s database API or utils &lt;a class="footnote-reference brackets" href="#id21" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, &lt;a class="footnote-reference brackets" href="#id22" id="id11" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, &lt;a class="footnote-reference brackets" href="#id23" id="id12" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, &lt;a class="footnote-reference brackets" href="#id24" id="id13" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, but rather
using them from neutron-lib.&lt;/p&gt;
&lt;p&gt;Subsequent subsections describe each module in greater detail.&lt;/p&gt;
&lt;p&gt;Note that &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;provisioning_blocks&lt;/span&gt;&lt;/code&gt; will be addressed in subsequent specs
as it requires versioned objects and thus will need access to them via
neutron-lib in order to implement.&lt;/p&gt;
&lt;section id="database-api"&gt;
&lt;h3&gt;Database API&lt;/h3&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron.db.api&lt;/span&gt;&lt;/code&gt; module is used broadly today &lt;a class="footnote-reference brackets" href="#id21" id="id14" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and has already begun
rehoming into neutron-lib &lt;a class="footnote-reference brackets" href="#id25" id="id15" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. Therefore this spec proposes we finish the
database API rehoming work by:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Rehoming the remaining externally used functions in the API. This includes
generic functions such as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;is_retriable&lt;/span&gt;&lt;/code&gt; as well as decorators like
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;retry_db_errors&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;retry_if_session_inactive&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Removing deprecated and unused functions such as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;load_one_to_manys&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get_session&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The osprofiler setup/initialization will need to be addressed to ensure
proper profiling functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests will need to be in place for the rehomed functionality; rehomed
and/or written as needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Consuming the rehomed changes once released.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="generic-utils"&gt;
&lt;h3&gt;Generic Utils&lt;/h3&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron.db._utils&lt;/span&gt;&lt;/code&gt; module contains generic logic and is thus used by
some consumers today &lt;a class="footnote-reference brackets" href="#id22" id="id16" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. This spec therefore proposes we rehome the used
functionality into neutron-lib by:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Rehoming the used functions such as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_fields&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get_marker_obj&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rehoming any functions use in the model query utils (see subsequent section)
into neutron-lib.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensuring the proper unit test coverage is in place for the rehomed code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Consuming the rehomed changes once released.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="model-query-utils"&gt;
&lt;h3&gt;Model Query Utils&lt;/h3&gt;
&lt;p&gt;While today &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron.db._model_query&lt;/span&gt;&lt;/code&gt; is private, some consumers use it &lt;a class="footnote-reference brackets" href="#id23" id="id17" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.
As this module contains generic database logic, it’s a candidate for rehoming
to neutron-lib as a generic model hook module by:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Rehoming the logic in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;_model_query&lt;/span&gt;&lt;/code&gt; module itself to neutron-lib.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensuring the generic utils are in lib that are required for this module.
See the previous section on generic utils.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rehoming the few used functions from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron.common.utils&lt;/span&gt;&lt;/code&gt; used in the
module query module. These are generic in nature and thus don’t raise any
red flags for rehoming.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rehoming &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron.objects.utils&lt;/span&gt;&lt;/code&gt; to neutron-lib as its used in the model
query logic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensuring the proper unit test coverage is in place for the rehomed code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Consuming the rehomed changes once released.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="resource-extend"&gt;
&lt;h3&gt;Resource Extend&lt;/h3&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron.db._resource_extend&lt;/span&gt;&lt;/code&gt; module is used by consumers today &lt;a class="footnote-reference brackets" href="#id24" id="id18" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and
as it contains generic functionality, can also move into neutron-lib by:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Rehoming the resource extend module into neutron-lib.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rehoming the single generic &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron.common.util&lt;/span&gt;&lt;/code&gt; function required
by the module into neutron-lib.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensuring the proper unit test coverage is in place for the rehomed code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Consuming the rehomed changes once released.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id19" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-lib-networking-ovn"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-lib-networking-ovn&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id20" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-lib-dynr"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-lib-dynr&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id21" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id3"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id6"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id10"&gt;3&lt;/a&gt;,&lt;a role="doc-backlink" href="#id14"&gt;4&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://codesearch.openstack.org/?q=from%20neutron%5C.db%20import%20api"&gt;http://codesearch.openstack.org/?q=from%20neutron%5C.db%20import%20api&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id22" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id4"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id7"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id11"&gt;3&lt;/a&gt;,&lt;a role="doc-backlink" href="#id16"&gt;4&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://codesearch.openstack.org/?q=from%20neutron%5C.db%20import%20_utils"&gt;http://codesearch.openstack.org/?q=from%20neutron%5C.db%20import%20_utils&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id23" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id5"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id8"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id12"&gt;3&lt;/a&gt;,&lt;a role="doc-backlink" href="#id17"&gt;4&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://codesearch.openstack.org/?q=from%20neutron%5C.db%20import%20_model_query"&gt;http://codesearch.openstack.org/?q=from%20neutron%5C.db%20import%20_model_query&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id24" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id9"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id13"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id18"&gt;3&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://codesearch.openstack.org/?q=from%20neutron%5C.db%20import%20_resource_extend"&gt;http://codesearch.openstack.org/?q=from%20neutron%5C.db%20import%20_resource_extend&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id25" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id15"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-lib/blob/master/neutron_lib/db/api.py"&gt;https://github.com/openstack/neutron-lib/blob/master/neutron_lib/db/api.py&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Thu, 17 May 2018 00:00:00 </pubDate></item><item><title>Decoupling database Resource Model imports/access for neutron-lib</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/rocky/neutronlib-decouple-models.html</link><description>

&lt;p&gt;This work is not related to an enhancement request and therefore doesn’t have
a RFE. Rather the intent herein is to discuss how we decouple &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron.db&lt;/span&gt;&lt;/code&gt;
and related database imports/access as part of the overall neutron-lib effort.&lt;/p&gt;
&lt;p&gt;Current neutron database access can be broken into the following high-level
categories:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Database API &amp;amp; Utilities&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Core &amp;amp; Extension Database Mixins&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Database Resource Models&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Database Migration&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As the database access patterns span a wide range of logic/code, a set of specs
will be proposed each focusing on a single access pattern.&lt;/p&gt;
&lt;p&gt;This spec specifically addresses Database Resource Model access.&lt;/p&gt;
&lt;p&gt;For current neutron-lib related blueprints, see &lt;a class="footnote-reference brackets" href="#id9" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and &lt;a class="footnote-reference brackets" href="#id10" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;As part of our neutron-lib effort, we need to decouple out-of-tree networking
projects that depend on (e.g. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;import&lt;/span&gt;&lt;/code&gt;) neutron. However, today a large
number of neutron consumers import database related neutron modules including
models &lt;a class="footnote-reference brackets" href="#id11" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id12" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Access to database models by consumers is typically used for:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Defining relationships between neutron and other project models. Note that
while string names can be used when defining a relationship, this is not
a viable solution for all cases due to &lt;a class="footnote-reference brackets" href="#id16" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Building queries using models and/or their fields. With the introduction of
versioned objects, consumers can effectively query using methods on objects.
Therefore the deliverables of this spec enable such an approach by making
versioned objects accessible via neutron-lib.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Importing models to have them available for database tools. This includes
database migration tools, so while this spec doesn’t directly solve
the migration access, it needs to lay a foundation for it (covered in a
separate spec).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The intent of this spec is to propose how we can provide access to database
models without direct neutron imports by means of a bridge in neutron-lib
thereby breaking consumer’s dependencies on neutron’s internal database
models.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;While one foreseeable solution would be to publish models using
discoverable entry points (stevedore) or register them using a factory,
these models must be versioned to allow consumers to determine compatibility.
Without versioning the underlying model can change without the consumers
knowledge, thereby breaking them.&lt;/p&gt;
&lt;p&gt;Implementing versioned models is simple enough with some new facility, however
we already have such a versioning scheme; neutron versioned objects. Neutron
objects already contain a reference to the underlying model as well as a
version number that’s incremented as the model changes &lt;a class="footnote-reference brackets" href="#id13" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. Therefore if we
can provide a way for consumers to get at neutron objects, they have access to
a version, corresponding model, etc..&lt;/p&gt;
&lt;p&gt;This spec proposes we use a simple entry point scheme whereby all versioned
objects are defined as entry points that can then be looked up and handed
out by some bridging logic in neutron-lib. More specifically:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron versioned objects can be “published” via an entry point in
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;setup.cfg&lt;/span&gt;&lt;/code&gt; where each entry point is a versioned object class. This
exposes the objects to neutron-lib that can be discovered and loaded with
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;stevedore&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A simple API in neutron-lib allowing consumers to retrieve versioned objects
at runtime. In it’s basic form a consumer asks for an object of type &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;X&lt;/span&gt;&lt;/code&gt;,
whereupon neutron-lib looks it up from the entry point and returns the
concrete object class to the consumer (e.g. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;load_class('Port')&lt;/span&gt;&lt;/code&gt; looks up
and returns the versioned object class for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Port&lt;/span&gt;&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If consumers need to create instances of the versioned object(s) returned
from neutron-lib, they can invoke it’s constructor directly to create a
new instance. Since versioned object constructor’s are based on the object’s
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;fields&lt;/span&gt;&lt;/code&gt; and the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;fields&lt;/span&gt;&lt;/code&gt; are tied to the model, consumers can query
the object’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VERSION&lt;/span&gt;&lt;/code&gt; to determine compatibility with the constructor.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The snippet below illustrates the API from a consumers point of view:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;neutron_lib.objects&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;
&lt;span class="c1"&gt;# .. other imports&lt;/span&gt;

&lt;span class="c1"&gt;# Loading the object from neutron-lib uses stevedore to find the requested&lt;/span&gt;
&lt;span class="c1"&gt;# object. Also note that under the covers the model is imported since the&lt;/span&gt;
&lt;span class="c1"&gt;# concrete versioned object must import the model to ref it.&lt;/span&gt;
&lt;span class="n"&gt;port_ovo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load_class&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;port_ovo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;VERSION&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'1.1'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;UnsupportedException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Can't use port objects greater than 1.1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# It's just an OVO class, so we can use it's static/class methods directly&lt;/span&gt;
&lt;span class="n"&gt;a_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;port_ovo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create a new versioned object; it's VERSION determines the constructor's&lt;/span&gt;
&lt;span class="c1"&gt;# supported kwargs so consumers can detect compatibility&lt;/span&gt;
&lt;span class="n"&gt;new_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;port_ovo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="o"&gt;=...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As mentioned earlier, while this solution doesn’t completely solve database
migration access, it paves the way as we now have a way to find and load
versioned objects which must import the respective model.&lt;/p&gt;
&lt;p&gt;Using this scheme, we should be able to eliminate consumers imports for:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Existing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron.objects&lt;/span&gt;&lt;/code&gt; imports &lt;a class="footnote-reference brackets" href="#id14" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. Consumers now get their object from
the neutron-lib API provided herein.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Building queries; version objects have methods allowing consumers to
effectively query and there should be no need to build direct queries in
consumers otherwise.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition, the rollout of this functionality should have minimal impact to
the main code paths; the only real change in neutron is to expose the objects
via &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;setup.cfg&lt;/span&gt;&lt;/code&gt;. The neutron-lib logic can be implemented, tested and rolled
out independently thereby reducing risk.&lt;/p&gt;
&lt;p&gt;For a sample proof of concept, see the patches on &lt;a class="footnote-reference brackets" href="#id15" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; that use this approach
to remove/use versioned objects in a few of the vmware-nsx modules.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id9" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-lib-networking-ovn"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-lib-networking-ovn&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-lib-dynr"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-lib-dynr&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id11" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://codesearch.openstack.org/?q=from%20neutron.db.model"&gt;http://codesearch.openstack.org/?q=from%20neutron.db.model&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://codesearch.openstack.org/?q=from%20neutron.db%20import%20model"&gt;http://codesearch.openstack.org/?q=from%20neutron.db%20import%20model&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id13" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/contributor/internals/objects_usage.html"&gt;https://docs.openstack.org/neutron/latest/contributor/internals/objects_usage.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id14" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://codesearch.openstack.org/?q=from%20neutron.objects"&gt;http://codesearch.openstack.org/?q=from%20neutron.objects&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id15" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/q/topic:bp/neutronlib-decouple-db"&gt;https://review.openstack.org/#/q/topic:bp/neutronlib-decouple-db&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id16" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://stackoverflow.com/questions/45534903/python-sqlalchemy-attributeerror-mapper"&gt;https://stackoverflow.com/questions/45534903/python-sqlalchemy-attributeerror-mapper&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Thu, 17 May 2018 00:00:00 </pubDate></item><item><title>Firewall as a Service API 2.0 Address Groups Support</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/rocky/fwaas-2.0-address-groups-support.html</link><description>

&lt;p&gt;&lt;strong&gt;Launchpad blueprint:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/fwaas-2.0-address-groups"&gt;https://blueprints.launchpad.net/neutron/+spec/fwaas-2.0-address-groups&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This bp introduces a enhancement to Firewall as a Service(FWaaS) API 2.0
for supporting address groups. This feature has been proposed in
fwaas-api-2.0 but still not implemented.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;In actual use of firewall groups, each IP or subnet requires a
corresponding firewall rule. When there are a large number of instances,
a large number of firewall rules are generated and it is difficult to
maintain and manage them.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Add address group functions to a firewall group. By aggregating multiple
address objects into address groups and using address groups instead of
the original cidr to generate firewall rules, the number of firewall rules
can be effectively reduced.&lt;/p&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;section id="firewall-address-groups"&gt;
&lt;h4&gt;Firewall Address Groups&lt;/h4&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the
address_group object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable name for the address
group (255 characters limit). Does not
have to be unique.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable description for the
address group (255 characters limit).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of the address group. Only
admin users can specify a project
identifier other than their own.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;addresses&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;List&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Array of key-value pairs of address
and ip version. It supports both CIDR
and IP range objects. Attributes of
CIDR and IP range objects:
“address”: &amp;lt;CIDR or IP range&amp;gt;
“ip_version”: 4 or 6(Integer value)
An example of addresses:
[{“address”: “132.168.4.12/24”,
“ip_version”: 4}]&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="firewall-rules"&gt;
&lt;h4&gt;Firewall Rules&lt;/h4&gt;
&lt;p&gt;Note that as with FWaaS 1.0, in FWaaS 2.0 firewall rules always use stateful connection
tracking.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the firewall
rule object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of the firewall rule. Only
admin users can specify a project
identifier other than their own.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable name for the firewall
rule (255 characters limit). Does
not have to be unique.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable description for the
firewall Rule (255 characters limit).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;shared&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When set to True makes this firewall
rule visible to projects other than
its owner, and can be used in
firewall policies not owned by its
project.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;protocol&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;IP Protocol.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;source_port&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;port-range&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Source port number or a range (an
int in [1, 65535] or range in a:b).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;destination_port&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;port-range&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Destination port number or a range (
an int in [1, 65535] or range in a:b).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;ip_version&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;IP Protocol Version.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;source_ip_address&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Source IP address or CIDR.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;destination_ip_address&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Destination IP address or CIDR.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;source_address
_group_ids&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;List&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;This is a list of source address
groups. When they are specified, they
are matched when the source IP address
in the packet matches one of the IP
addresses in one of the address
groups.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;destination_address
_group_ids&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;List&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;This is a list of destination address
groups. When they are specified, they
are matched when the destination IP
address in the packet matches one of
the IP addresses in one of the address
groups.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;action&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Action to be performed on the
traffic matching the rule (ALLOW,
DENY, REJECT). Default: DENY.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;enabled&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When set to False will disable this
rule in the firewall policy.
Facilitates selectively turning off
rules without having to disassociate
the rule from the firewall policy.
Default: True.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note: At most one of source_ip_address, source_address_group_ids and
source_firewall_group_id can be specified.  The rule is matched when the
source IP address in the packet matches any one of: source_ip_address,
one of the IP addresses in the address group, or an IP address of one
of the ports in the firewall group. If you want it to match any packet,
set the source or destination to 0.0.0.0/0 or ::/0. The same applies to
destination_ip_address, destination_address_group_ids, and destination
_firewall_group_id, with respect to the destination IP address in the
packet.&lt;/p&gt;
&lt;section id="list-address-groups"&gt;
&lt;h5&gt;List address groups&lt;/h5&gt;
&lt;p&gt;Lists address groups.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/fwaas/address_groups&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example List address groups: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fwaas&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;address_groups&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example List address groups: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"address_groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ADDR_GP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"addresses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.5.12-132.168.5.24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="show-address-group-details"&gt;
&lt;h5&gt;Show address group details&lt;/h5&gt;
&lt;p&gt;Shows address group details.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/fwaas/address_groups/&amp;lt;address_group_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Not Found (404)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Show address group: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fwaas&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;address_groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;8722e0&lt;/span&gt;&lt;span class="n"&gt;e0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;cc9&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4490&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9660&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;c9a5732fbb0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Show address group: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"address_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ADDR_GP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"addresses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.5.12-132.168.5.24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="create-address-group"&gt;
&lt;h5&gt;Create address group&lt;/h5&gt;
&lt;p&gt;Creates an address group.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/fwaas/address_groups/&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;201&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Bad Request(400)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Create address group: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fwaas&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;address_groups&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"address_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ADDR_GP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"addresses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.5.12-132.168.5.24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Create address group: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"address_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ADDR_GP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"addresses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.5.12-132.168.5.24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="update-address-group"&gt;
&lt;h5&gt;Update address group&lt;/h5&gt;
&lt;p&gt;Updates an address group.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/fwaas/address_groups/&amp;lt;address_group_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Bad Request(400) Not Found(404)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Update address group: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fwaas&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;address_groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;8722e0&lt;/span&gt;&lt;span class="n"&gt;e0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;cc9&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4490&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9660&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;c9a5732fbb0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"address_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"addresses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.5.12-132.168.5.24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Update address group: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"address_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ADDR_GP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"addresses"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.5.12-132.168.5.24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="delete-address-group"&gt;
&lt;h5&gt;Delete address group&lt;/h5&gt;
&lt;p&gt;Deletes an address group.&lt;/p&gt;
&lt;p&gt;This operation does not return a response body.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DELETE&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/fwaas/address_groups/&amp;lt;address_group_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;204&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Not Found(404)
Conflict(409) The Conflict error response
is returned when an operation is
performed while address group is in use.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Delete address group: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fwaas&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;address_groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;8722e0&lt;/span&gt;&lt;span class="n"&gt;e0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;cc9&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4490&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9660&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;c9a5732fbb0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Delete address group: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="list-firewall-rules"&gt;
&lt;h5&gt;List firewall rules&lt;/h5&gt;
&lt;p&gt;Lists firewall rules.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/fwaas/firewall_rules&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example List firewall rules: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fwaas&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_rules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example List firewall rules: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"56632e51-d2aa-4b79-9fd4-45f51088c4ed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"9faaf49f-dd89-4e39-a8c6-101839aa49bc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW_HTTP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"source_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"destination_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"80"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"source_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"destination_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;
            &lt;span class="s2"&gt;"source_address_group_ids"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
            &lt;span class="s2"&gt;"destination_address_group_ids"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"8315762a-f0ae-4f6b-981a-a16a6c3103c2"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="show-firewall-rule-details"&gt;
&lt;h5&gt;Show firewall rule details&lt;/h5&gt;
&lt;p&gt;Shows firewall rule details.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/fwaas/firewall_rules/&amp;lt;firewall_rule_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Not Found (404)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Show firewall rule: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fwaas&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_rules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;faaf49f&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dd89&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4e39&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a8c6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;101839&lt;/span&gt;&lt;span class="n"&gt;aa49bc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Show firewall rule: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"56632e51-d2aa-4b79-9fd4-45f51088c4ed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"9faaf49f-dd89-4e39-a8c6-101839aa49bc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW_HTTP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"80"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_address_group_ids"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_address_group_ids"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"8315762a-f0ae-4f6b-981a-a16a6c3103c2"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="create-firewall-rule"&gt;
&lt;h5&gt;Create firewall rule&lt;/h5&gt;
&lt;p&gt;Creates a firewall rule.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/fwaas/firewall_rules/&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;201&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Bad Request(400)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Create firewall rule: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fwaas&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_rules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW_HTTP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"80"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_address_group_ids"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_address_group_ids"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"8315762a-f0ae-4f6b-981a-a16a6c3103c2"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Create firewall rule: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"9faaf49f-dd89-4e39-a8c6-101839aa49bc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW_HTTP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"80"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_address_group_ids"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_address_group_ids"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"8315762a-f0ae-4f6b-981a-a16a6c3103c2"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="update-firewall-rule"&gt;
&lt;h5&gt;Update firewall rule&lt;/h5&gt;
&lt;p&gt;Updates a firewall rule.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/fwaas/firewall_rules/&amp;lt;firewall_rule_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Bad Request(400) Not Found(404)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Update firewall rule: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fwaas&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_rules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;faaf49f&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dd89&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4e39&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a8c6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;101839&lt;/span&gt;&lt;span class="n"&gt;aa49bc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"true"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Update firewall rule: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"9faaf49f-dd89-4e39-a8c6-101839aa49bc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW_HTTP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"80"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_address_group_ids"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_address_group_ids"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"8315762a-f0ae-4f6b-981a-a16a6c3103c2"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="delete-firewall-rule"&gt;
&lt;h5&gt;Delete firewall rule&lt;/h5&gt;
&lt;p&gt;Deletes a firewall rule.&lt;/p&gt;
&lt;p&gt;This operation does not return a response body.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DELETE&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v2.0/fwaas/firewall_rules/&amp;lt;firewall_rule_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;204&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Not Found(404)
Conflict(409) The Conflict error response
is returned when an operation is
performed while firewall rule is in use.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Delete firewall rule: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fwaas&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_rules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;faaf49f&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dd89&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4e39&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a8c6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;101839&lt;/span&gt;&lt;span class="n"&gt;aa49bc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Delete firewall rule: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;The following are the backend database tables for the REST API proposed above.&lt;/p&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;strong&gt;Firewall Address Groups&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the
address_group object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable name for the address
group (255 characters limit). Does not
have to be unique.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable description for the
address group (255 characters limit).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of the address group. Only
admin users can specify a project
identifier other than their own.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;strong&gt;Firewall Address Group Address associations&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the
address_group object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;firewall_address
_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID of firewall address group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;address&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Address that has to be associated to
the firewall address group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;ip_version&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;IP Protocol Version of the address.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;strong&gt;Firewall Rules&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the firewall
rule object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of the firewall rule. Only
admin users can specify a project
identifier other than their own.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable name for the firewall
rule (255 characters limit). Does
not have to be unique.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable description for the
firewall Rule (255 characters limit).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;shared&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When set to True makes this firewall
rule visible to projects other than
its owner, and can be used in
firewall policies not owned by its
project.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;protocol&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;IP Protocol.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;source_port&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;port-range&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Source port number or a range (an
int in [1, 65535] or range in a:b).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;destination_port&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;port-range&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Destination port number or a range (
an int in [1, 65535] or range in a:b).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;ip_version&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;IP Protocol Version.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;source_ip_address&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Source IP address or CIDR.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;destination_ip_address&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Destination IP address or CIDR.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;source_address
_group_ids&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;List&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When a source_address_group is
specified, it is matched when the
source IP address in the packet
matches one of the IP addresses in
the address group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;destination_address
_group_ids&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;List&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When a destination_address_group is
specified, it is matched when the
destination IP address in the packet
matches one of the IP addresses in the
address group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;action&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Action to be performed on the
traffic matching the rule (ALLOW,
DENY, REJECT). Default: DENY.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;enabled&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When set to False will disable this
rule in the firewall policy.
Facilitates selectively turning off
rules without having to disassociate
the rule from the firewall policy.
Default: True.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;strong&gt;Firewall Rules Source Address Group associations&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the
address_group object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;firewall_rule_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID of firewall rule.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;address_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID of source address group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;strong&gt;Firewall Rules Destination Address Group associations&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the
address_group object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;firewall_rule_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID of firewall rule.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;address_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID of destination address group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Wang Tao&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;REST API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB Schema&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FWaaS plugin update&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI update&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L3 agent iptables driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L2 agent ovs driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FWaaS dashboard&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DB mixin and schema tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FWaaS Plugin with mocked driver end-to-end tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New tests need to be written&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;REST API and attributes validation tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron CLI and FWaaS API documentation have to be modified.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;neutron-fwaas repo will have a devref and documentation will be written.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/newton/fwaas-api-2.0.html"&gt;https://specs.openstack.org/openstack/neutron-specs/specs/newton/fwaas-api-2.0.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[2] &lt;a class="reference external" href="https://developer.openstack.org/api-ref/network/v2/#fwaas-v2-0-current-fwaas-firewall-groups-firewall-policies-firewall-rules"&gt;https://developer.openstack.org/api-ref/network/v2/#fwaas-v2-0-current-fwaas-firewall-groups-firewall-policies-firewall-rules&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 28 Mar 2018 00:00:00 </pubDate></item><item><title>Mitaka Postmortem documentation</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/postmortem/postmortem.html</link><description>

&lt;nav class="contents" id="contents"&gt;
&lt;p class="topic-title"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#mitaka-postmortem-documentation" id="id5"&gt;Mitaka Postmortem documentation&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#release-metrics" id="id6"&gt;Release Metrics&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#blueprints" id="id7"&gt;Blueprints&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#external-dns-resolution" id="id8"&gt;External DNS Resolution&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#get-me-a-network" id="id9"&gt;Get Me a Network&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#api-for-l2-agent-extensions" id="id10"&gt;API for l2 agent extensions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#modular-l2-agent" id="id11"&gt;Modular L2 Agent&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#support-multiple-l3-backends" id="id12"&gt;Support multiple L3 backends&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#provide-better-user-facing-mechanism-to-choose-service-capabilities" id="id13"&gt;Provide better user-facing mechanism to choose service capabilities&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#split-neutron-into-base-library-and-servers-agents" id="id14"&gt;Split neutron into base library and servers/agents&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#use-push-style-notifications-for-all-server-agent-information" id="id15"&gt;Use push style notifications for all server-&amp;gt;agent information&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#restructure-l2-agent" id="id16"&gt;Restructure L2 agent&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#clean-up-resources-when-a-tenant-is-deleted" id="id17"&gt;Clean up resources when a tenant is deleted&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#add-availability-zones-for-agents" id="id18"&gt;Add availability zones for agents&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#add-tags-to-core-resources" id="id19"&gt;Add tags to core resources&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#add-timestamp-to-neutron-resources" id="id20"&gt;Add timestamp to neutron resources&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#introduce-address-scopes" id="id21"&gt;Introduce Address Scopes&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#automatically-generate-etc-neutron-conf-file" id="id22"&gt;Automatically generate etc/neutron.conf file&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#router-extension-for-dynamic-routing-using-bgp" id="id23"&gt;Router Extension for Dynamic Routing Using BGP&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#allow-for-per-subnet-dhcp-options" id="id24"&gt;Allow for per-subnet dhcp options&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#add-guru-meditation-report-functionality-to-neutron" id="id25"&gt;Add Guru Meditation Report Functionality to Neutron&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#improve-dvr-router-sheduling-mechanism-for-better-performance-scalability" id="id26"&gt;Improve DVR router sheduling mechanism for better performance/scalability&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#moving-to-keystone-v3" id="id27"&gt;Moving to Keystone v3&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#lbaas-layer-7-rules" id="id28"&gt;LBaaS Layer 7 rules&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#ml2-linuxbridge-qos-support-with-bandwidth-limiting" id="id29"&gt;ML2/LinuxBridge QoS support with bandwidth limiting&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#adds-a-network-ip-usage-api-to-fetch-network-and-subnet-ip-usage-counts" id="id30"&gt;Adds a network-ip-usage api to fetch network and subnet IP usage counts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#role-based-access-control-for-qos-policies" id="id31"&gt;Role-based Access Control for QoS policies&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#enable-vhost-user-support-with-ovs-agent" id="id32"&gt;enable vhost-user support with ovs agent&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#allow-vm-to-boot-without-l3-address-subnet" id="id33"&gt;Allow vm to boot without l3 address(subnet)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#allow-multiple-subnets-to-connect-to-vpn" id="id34"&gt;allow multiple subnets to connect to vpn&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe" id="id35"&gt;RFE&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#openstack-services-should-support-sighup-signal" id="id36"&gt;Openstack services should support SIGHUP signal&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-neutron-support-for-osprofiler" id="id37"&gt;[RFE] Neutron support for OSprofiler&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-unable-to-create-a-router-thats-both-ha-and-distributed" id="id38"&gt;[RFE] Unable to create a router thats both HA and distributed&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-lbaas-ssh-connection-timeout" id="id39"&gt;[RFE] [LBaaS] ssh connection timeout&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-openvswitch-based-firewall-driver" id="id40"&gt;[rfe] openvswitch based firewall driver&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-create-a-full-load-balancing-configuration-with-one-api-call" id="id41"&gt;[RFE] Create a full load balancing configuration with one API call&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-security-rules-should-support-vrrp-protocol" id="id42"&gt;RFE: Security Rules should support VRRP protocol&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-allow-annotations-on-neutron-resources" id="id43"&gt;[RFE] Allow annotations on Neutron resources&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-dhcp-agent-should-provide-ipv6-ras-for-isolated-networks-with-ipv6-subnets" id="id44"&gt;[RFE] DHCP agent should provide ipv6 RAs for isolated networks with ipv6 subnets&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-replace-the-existing-default-subnetpool-configuration-options-with-an-admin-only-api" id="id45"&gt;RFE Replace the existing default subnetpool configuration options with an admin-only API&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-improve-sg-performance-as-vms-containers-scale-on-compute-node" id="id46"&gt;[RFE] Improve SG performance as VMs/containers scale on compute node&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-there-is-no-facility-to-name-lbaas-v2-members-and-health-monitors" id="id47"&gt;RFE There is no facility to name LBaaS v2 Members and Health Monitors&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-ipam-migration-from-non-pluggable-to-pluggable" id="id48"&gt;[RFE] IPAM migration from non-pluggable to pluggable&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-transition-neutron-cli-from-python-neutronclient-to-python-openstackclient" id="id49"&gt;[RFE] Transition neutron CLI from python-neutronclient to python-openstackclient&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-cascading-delete-for-lbaas-objects" id="id50"&gt;RfE: Cascading delete for LBaaS Objects&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-use-oslo-versioned-objects-to-help-with-dealing-with-upgrades" id="id51"&gt;[RFE] use oslo-versioned-objects to help with dealing with upgrades&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-add-support-for-external-vxlan-encapsulation-to-neutron-router" id="id52"&gt;RFE Add support for external vxlan encapsulation to neutron router&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-security-groups-resources-are-not-extendable" id="id53"&gt;[RFE] Security groups resources are not extendable&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-add-f5-plugin-driver-to-neutron-lbaas" id="id54"&gt;RFE Add F5 plugin driver to neutron-lbaas&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/nav&gt;
&lt;section id="release-metrics"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id6" role="doc-backlink"&gt;Release Metrics&lt;/a&gt;&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Release Metrics&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Blueprints submitted&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;33&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Blueprints implemented&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;21 (63%)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Bug reports submitted&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1104&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Bug reports closed&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;678 (61%)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Fixes released&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;538&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Incomplete reports&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;59&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;RFEs submitted&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;33&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;RFEs approved&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;27 (81%)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Bug reports submitted: reports filed since Sept-23-2015 (Mitaka starts)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bug reports closed: reports marked released, committed, invalid or wontfix&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fixes released: marked released/committed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Incomplete reports: marked incomplete&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Metrics accurate at the time of writing.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="blueprints"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id7" role="doc-backlink"&gt;Blueprints&lt;/a&gt;&lt;/h2&gt;
&lt;section id="external-dns-resolution"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id8" role="doc-backlink"&gt;External DNS Resolution&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: minsel&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/external-dns-resolution"&gt;https://blueprints.launchpad.net/neutron/+spec/external-dns-resolution&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: Complete (Nova/Designate)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="get-me-a-network"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id9" role="doc-backlink"&gt;Get Me a Network&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: gessau&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/get-me-a-network"&gt;https://blueprints.launchpad.net/neutron/+spec/get-me-a-network&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: Incomplete (&lt;a class="reference external" href="https://review.openstack.org/#/c/283206/"&gt;283206&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-for-l2-agent-extensions"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id10" role="doc-backlink"&gt;API for l2 agent extensions&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: ihar-hrachyshka&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/l2-api-extensions"&gt;https://blueprints.launchpad.net/neutron/+spec/l2-api-extensions&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="modular-l2-agent"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id11" role="doc-backlink"&gt;Modular L2 Agent&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: andreas-scheuring&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/modular-l2-agent"&gt;https://blueprints.launchpad.net/neutron/+spec/modular-l2-agent&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="support-multiple-l3-backends"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id12" role="doc-backlink"&gt;Support multiple L3 backends&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: kevinbenton&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/multi-l3-backends"&gt;https://blueprints.launchpad.net/neutron/+spec/multi-l3-backends&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Denied (Some experimental code may still make the release,
but nothing production worthy)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="provide-better-user-facing-mechanism-to-choose-service-capabilities"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id13" role="doc-backlink"&gt;Provide better user-facing mechanism to choose service capabilities&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete (Undocumented)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: dougwig&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-flavor-framework"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-flavor-framework&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="split-neutron-into-base-library-and-servers-agents"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id14" role="doc-backlink"&gt;Split neutron into base library and servers/agents&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Status: Ongoing effort&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: dougwig&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-lib"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-lib&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Denied (Goal for Mitaka was for lbaas to be fully severed,
with fw/vpn to follow. We are not there. Work will be ongoing throughout
Newton as well. The limited goal in Mitaka was completely severing lbaas.
At present, the library exists and is plumbed throughout the infra. The
first rev is being used by neutron and neutron-lbaas. Patches exist for
bumping both to the second version of the lib. More patches exist to
delete a lot of cruft from lbaas that will mean less to migrate, and
plans are in place to stop the dependency on test code. The remaining
items that were aimed at Mitaka but will miss are base db model/migration
foo, and data model foo, both of which are ongoing, but neither of which
needs to land in the critical end of mitaka timeframe (they can iterate
in gerrit for now.) As soon as the Mitaka branch is baked, we can:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;turn on deprecation warnings&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;nuke lbaas v1 and v2 agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;start mass import renames in neutron&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;merge the above db/model items&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The goal of completely severing lbaas is realistically about 3-4
weeks away from Feature Freeze. The separation of the remaining subprojects
are next after that. Attempting to get patches in gerrit for the lbaas
separation goal before the summit.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: See FFE notes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: See FFE notes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: See FFE notes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: See FFE notes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-push-style-notifications-for-all-server-agent-information"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id15" role="doc-backlink"&gt;Use push style notifications for all server-&amp;gt;agent information&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: kevinbenton&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/push-notifications"&gt;https://blueprints.launchpad.net/neutron/+spec/push-notifications&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Denied (minor enhancemetns may be allowed as RC bugs, e.g.
&lt;a class="reference external" href="https://review.openstack.org/#/c/280595/"&gt;280595&lt;/a&gt;).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="restructure-l2-agent"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id16" role="doc-backlink"&gt;Restructure L2 agent&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: rossella-o&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/restructure-l2-agent"&gt;https://blueprints.launchpad.net/neutron/+spec/restructure-l2-agent&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="clean-up-resources-when-a-tenant-is-deleted"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id17" role="doc-backlink"&gt;Clean up resources when a tenant is deleted&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: john-davidge&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/tenant-delete"&gt;https://blueprints.launchpad.net/neutron/+spec/tenant-delete&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Granted&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="add-availability-zones-for-agents"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id18" role="doc-backlink"&gt;Add availability zones for agents&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: ichihara-hirofumi&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/add-availability-zone"&gt;https://blueprints.launchpad.net/neutron/+spec/add-availability-zone&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="add-tags-to-core-resources"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id19" role="doc-backlink"&gt;Add tags to core resources&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: ichihara-hirofumi&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/add-tags-to-core-resources"&gt;https://blueprints.launchpad.net/neutron/+spec/add-tags-to-core-resources&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Granted (docs pending)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="add-timestamp-to-neutron-resources"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id20" role="doc-backlink"&gt;Add timestamp to neutron resources&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: zhaobo6&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/add-timestamp-attr"&gt;https://blueprints.launchpad.net/neutron/+spec/add-timestamp-attr&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Granted&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="introduce-address-scopes"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id21" role="doc-backlink"&gt;Introduce Address Scopes&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: carl-baldwin&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/address-scopes"&gt;https://blueprints.launchpad.net/neutron/+spec/address-scopes&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Granted (docs pending)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/286294/"&gt;https://review.openstack.org/#/c/286294/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="automatically-generate-etc-neutron-conf-file"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id22" role="doc-backlink"&gt;Automatically generate etc/neutron.conf file&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: martin-hickey&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/autogen-neutron-conf-file"&gt;https://blueprints.launchpad.net/neutron/+spec/autogen-neutron-conf-file&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/draft/config-reference/networking/samples/"&gt;http://docs.openstack.org/draft/config-reference/networking/samples/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/neutron/devref/contribute.html#configuration-files"&gt;http://docs.openstack.org/developer/neutron/devref/contribute.html#configuration-files&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="router-extension-for-dynamic-routing-using-bgp"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id23" role="doc-backlink"&gt;Router Extension for Dynamic Routing Using BGP&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: ryan-tidwell&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/bgp-dynamic-routing"&gt;https://blueprints.launchpad.net/neutron/+spec/bgp-dynamic-routing&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Granted&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/288856/"&gt;https://review.openstack.org/#/c/288856/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/q/topic:bp/bgp-dynamic-routing"&gt;https://review.openstack.org/#/q/topic:bp/bgp-dynamic-routing&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/268726/"&gt;https://review.openstack.org/#/c/268726/&lt;/a&gt; (to be spun out)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="allow-for-per-subnet-dhcp-options"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id24" role="doc-backlink"&gt;Allow for per-subnet dhcp options&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: sambetts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/dhcp-options-per-subnet"&gt;https://blueprints.launchpad.net/neutron/+spec/dhcp-options-per-subnet&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Denied (Unable to determine status)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="add-guru-meditation-report-functionality-to-neutron"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id25" role="doc-backlink"&gt;Add Guru Meditation Report Functionality to Neutron&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: ihar-hrachyshka&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/guru-meditation-report"&gt;https://blueprints.launchpad.net/neutron/+spec/guru-meditation-report&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Granted (to provide guru support to vpn/lb/fwass)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: Incomplete (&lt;a class="reference external" href="https://review.openstack.org/#/c/279035/"&gt;279035&lt;/a&gt; needs review)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/287795/"&gt;https://review.openstack.org/#/c/287795/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/287801/"&gt;https://review.openstack.org/#/c/287801/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="improve-dvr-router-sheduling-mechanism-for-better-performance-scalability"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id26" role="doc-backlink"&gt;Improve DVR router sheduling mechanism for better performance/scalability&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: obondarev&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/improve-dvr-l3-agent-binding"&gt;https://blueprints.launchpad.net/neutron/+spec/improve-dvr-l3-agent-binding&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="moving-to-keystone-v3"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id27" role="doc-backlink"&gt;Moving to Keystone v3&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: smigiel-dariusz&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/keystone-v3"&gt;https://blueprints.launchpad.net/neutron/+spec/keystone-v3&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Denied (Neutron Server supports v3, but schema and API
migration is still undergoing).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete (&lt;a class="reference external" href="https://review.openstack.org/#/c/281357/"&gt;281357&lt;/a&gt; needs work).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="lbaas-layer-7-rules"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id28" role="doc-backlink"&gt;LBaaS Layer 7 rules&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete (Undocumented)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: avishayb&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-l7-rules"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-l7-rules&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Granted (docs pending)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:  Complete (Octavia)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="ml2-linuxbridge-qos-support-with-bandwidth-limiting"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id29" role="doc-backlink"&gt;ML2/LinuxBridge QoS support with bandwidth limiting&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: slaweq&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ml2-lb-ratelimit-support"&gt;https://blueprints.launchpad.net/neutron/+spec/ml2-lb-ratelimit-support&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="adds-a-network-ip-usage-api-to-fetch-network-and-subnet-ip-usage-counts"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id30" role="doc-backlink"&gt;Adds a network-ip-usage api to fetch network and subnet IP usage counts&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: mdorman-m&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/network-ip-usage-api"&gt;https://blueprints.launchpad.net/neutron/+spec/network-ip-usage-api&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Granted&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="role-based-access-control-for-qos-policies"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id31" role="doc-backlink"&gt;Role-based Access Control for QoS policies&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: hdaniel&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/rbac-qos"&gt;https://blueprints.launchpad.net/neutron/+spec/rbac-qos&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Granted&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="enable-vhost-user-support-with-ovs-agent"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id32" role="doc-backlink"&gt;enable vhost-user support with ovs agent&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: sean-k-mooney&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/vhost-ovs"&gt;https://blueprints.launchpad.net/neutron/+spec/vhost-ovs&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete (user guide desirable)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/neutron/devref/ovs_vhostuser.html"&gt;http://docs.openstack.org/developer/neutron/devref/ovs_vhostuser.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="allow-vm-to-boot-without-l3-address-subnet"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id33" role="doc-backlink"&gt;Allow vm to boot without l3 address(subnet)&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: yalei-wang&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/vm-without-l3-address"&gt;https://blueprints.launchpad.net/neutron/+spec/vm-without-l3-address&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Denied (&lt;a class="reference external" href="https://review.openstack.org/#/q/topic:bp/vm-without-l3-address"&gt;vm-without-l3-address&lt;/a&gt;
shows a post-nuclear landscape).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: Incomplete (Nova)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/239276/"&gt;https://review.openstack.org/#/c/239276/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/q/topic:bp/vm-without-l3-address"&gt;https://review.openstack.org/#/q/topic:bp/vm-without-l3-address&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="allow-multiple-subnets-to-connect-to-vpn"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id34" role="doc-backlink"&gt;allow multiple subnets to connect to vpn&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: pcm&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/vpn-multiple-subnet"&gt;https://blueprints.launchpad.net/neutron/+spec/vpn-multiple-subnet&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="rfe"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id35" role="doc-backlink"&gt;RFE&lt;/a&gt;&lt;/h2&gt;
&lt;section id="openstack-services-should-support-sighup-signal"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id36" role="doc-backlink"&gt;Openstack services should support SIGHUP signal&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: eezhova&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1276694"&gt;https://bugs.launchpad.net/neutron/+bug/1276694&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-neutron-support-for-osprofiler"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id37" role="doc-backlink"&gt;[RFE] Neutron support for OSprofiler&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: salvatore-orlando&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1335640"&gt;https://bugs.launchpad.net/neutron/+bug/1335640&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/273951/"&gt;https://review.openstack.org/#/c/273951/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-unable-to-create-a-router-thats-both-ha-and-distributed"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id38" role="doc-backlink"&gt;[RFE] Unable to create a router thats both HA and distributed&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: carl-baldwin&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1365473"&gt;https://bugs.launchpad.net/neutron/+bug/1365473&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Granted (needs docs)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/296711/"&gt;https://review.openstack.org/#/c/296711/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/296836/"&gt;https://review.openstack.org/#/c/296836/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-lbaas-ssh-connection-timeout"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id39" role="doc-backlink"&gt;[RFE] [LBaaS] ssh connection timeout&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: reedip-banerjee&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1457556"&gt;https://bugs.launchpad.net/neutron/+bug/1457556&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Denied (no tangible progress)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-openvswitch-based-firewall-driver"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id40" role="doc-backlink"&gt;[rfe] openvswitch based firewall driver&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete (partially documented)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: libosvar&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1461000"&gt;https://bugs.launchpad.net/neutron/+bug/1461000&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Granted&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete (user guide docs desirable)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/neutron/devref/openvswitch_firewall.html"&gt;http://docs.openstack.org/developer/neutron/devref/openvswitch_firewall.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/284259"&gt;https://review.openstack.org/#/c/284259&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/283137"&gt;https://review.openstack.org/#/c/283137&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-create-a-full-load-balancing-configuration-with-one-api-call"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id41" role="doc-backlink"&gt;[RFE] Create a full load balancing configuration with one API call&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: trevor-vardeman&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1463202"&gt;https://bugs.launchpad.net/neutron/+bug/1463202&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Denied (too many missing pieces).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-security-rules-should-support-vrrp-protocol"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id42" role="doc-backlink"&gt;RFE: Security Rules should support VRRP protocol&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: sreesiv&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1475717"&gt;https://bugs.launchpad.net/neutron/+bug/1475717&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-allow-annotations-on-neutron-resources"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id43" role="doc-backlink"&gt;[RFE] Allow annotations on Neutron resources&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: kevinbenton&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1483480"&gt;https://bugs.launchpad.net/neutron/+bug/1483480&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Granted&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-dhcp-agent-should-provide-ipv6-ras-for-isolated-networks-with-ipv6-subnets"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id44" role="doc-backlink"&gt;[RFE] DHCP agent should provide ipv6 RAs for isolated networks with ipv6 subnets&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: ihar-hrachyshka&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1498987"&gt;https://bugs.launchpad.net/neutron/+bug/1498987&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-replace-the-existing-default-subnetpool-configuration-options-with-an-admin-only-api"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id45" role="doc-backlink"&gt;RFE Replace the existing default subnetpool configuration options with an admin-only API&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: john-davidge&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1501328"&gt;https://bugs.launchpad.net/neutron/+bug/1501328&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Granted (docs pending)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/286293/"&gt;https://review.openstack.org/#/c/286293/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-improve-sg-performance-as-vms-containers-scale-on-compute-node"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id46" role="doc-backlink"&gt;[RFE] Improve SG performance as VMs/containers scale on compute node&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: kevinbenton&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1502297"&gt;https://bugs.launchpad.net/neutron/+bug/1502297&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-there-is-no-facility-to-name-lbaas-v2-members-and-health-monitors"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id47" role="doc-backlink"&gt;RFE There is no facility to name LBaaS v2 Members and Health Monitors&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete (undocumented)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: reedip-banerjee&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1515506"&gt;https://bugs.launchpad.net/neutron/+bug/1515506&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-ipam-migration-from-non-pluggable-to-pluggable"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id48" role="doc-backlink"&gt;[RFE] IPAM migration from non-pluggable to pluggable&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: pasha117&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1516156"&gt;https://bugs.launchpad.net/neutron/+bug/1516156&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A (server side entry point)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/277767"&gt;https://review.openstack.org/#/c/277767&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="rfe-transition-neutron-cli-from-python-neutronclient-to-python-openstackclient"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id49" role="doc-backlink"&gt;[RFE] Transition neutron CLI from python-neutronclient to python-openstackclient&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: rtheis&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1521291"&gt;https://bugs.launchpad.net/neutron/+bug/1521291&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Denied (even though &lt;a class="reference external" href="https://review.openstack.org/#/c/282555/"&gt;Devref patch&lt;/a&gt;
will likely merge, the actual work will need to move to Newton. OSC in Mitaka will have a
significant increase in support for core neutron resources Detailed status available at
&lt;a class="reference external" href="https://etherpad.openstack.org/p/osc-neutron-support"&gt;https://etherpad.openstack.org/p/osc-neutron-support&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-cascading-delete-for-lbaas-objects"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id50" role="doc-backlink"&gt;RfE: Cascading delete for LBaaS Objects&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: german-eichberger&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1521783"&gt;https://bugs.launchpad.net/neutron/+bug/1521783&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Denied&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/287593/"&gt;https://review.openstack.org/#/c/287593/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/288187/"&gt;https://review.openstack.org/#/c/288187/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-use-oslo-versioned-objects-to-help-with-dealing-with-upgrades"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id51" role="doc-backlink"&gt;[RFE] use oslo-versioned-objects to help with dealing with upgrades&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: justin-hammond&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1522102"&gt;https://bugs.launchpad.net/neutron/+bug/1522102&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Denied (Wont happen in Mitaka. Should be moved to Newton.
Was not expected to land in Mitaka, the bug is just a placeholder for a
large effort).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-add-support-for-external-vxlan-encapsulation-to-neutron-router"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id52" role="doc-backlink"&gt;RFE Add support for external vxlan encapsulation to neutron router&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: ruansx&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1525059"&gt;https://bugs.launchpad.net/neutron/+bug/1525059&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Denied (too many parts lacking exhaustive review)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project supprt: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/q/topic:bug/1525059"&gt;https://review.openstack.org/#/q/topic:bug/1525059&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-security-groups-resources-are-not-extendable"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id53" role="doc-backlink"&gt;[RFE] Security groups resources are not extendable&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: roeyc&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1529109"&gt;https://bugs.launchpad.net/neutron/+bug/1529109&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-add-f5-plugin-driver-to-neutron-lbaas"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id54" role="doc-backlink"&gt;RFE Add F5 plugin driver to neutron-lbaas&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: j-longstaff&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1539717"&gt;https://bugs.launchpad.net/neutron/+bug/1539717&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Denied (no met requirements for inclusion)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack/Grenade support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 01 Mar 2018 00:00:00 </pubDate></item><item><title>Newton Postmortem documentation</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/newton/postmortem/postmortem.html</link><description>

&lt;nav class="contents" id="contents"&gt;
&lt;p class="topic-title"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#newton-postmortem-documentation" id="id1"&gt;Newton Postmortem documentation&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#release-metrics" id="id2"&gt;Release Metrics&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#blueprints" id="id3"&gt;Blueprints&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#firewall-as-a-service-api-2-0" id="id4"&gt;Firewall as a Service API 2.0&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#api-for-l2-agent-extensions" id="id5"&gt;API for l2 agent extensions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#support-multiple-l3-backends" id="id6"&gt;Support multiple L3 backends&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#split-neutron-into-base-library-and-servers-agents" id="id7"&gt;Split neutron into base library and servers/agents&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#upgrade-controllers-with-no-api-downtime" id="id8"&gt;Upgrade controllers with no API downtime&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#use-push-style-notifications-for-all-server-agent-information" id="id9"&gt;Use push style notifications for all server-&amp;gt;agent information&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#support-routed-networks-in-neutron" id="id10"&gt;Support Routed Networks in Neutron&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#diagnostics-of-neutron-components" id="id11"&gt;Diagnostics of Neutron components&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#vlan-aware-vms" id="id12"&gt;VLAN aware VMs&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#adopt-oslo-versionedobjects-for-database-interactions" id="id13"&gt;Adopt oslo.versionedobjects for database interactions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#bgp-dynamic-routing-spin-out" id="id14"&gt;BGP Dynamic Routing spin out&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#allow-for-per-subnet-dhcp-options" id="id15"&gt;Allow for per-subnet dhcp options&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#use-the-new-enginefacade-from-oslo-db" id="id16"&gt;Use the new enginefacade from oslo_db&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#allow-instance-ingress-bandwidth-limiting" id="id17"&gt;Allow instance-ingress bandwidth limiting&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#moving-to-keystone-v3" id="id18"&gt;Moving to Keystone v3&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#add-agent-extension-framework-for-l3-agent" id="id19"&gt;Add agent extension framework for L3 agent&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#qos-support-with-dscp-marking" id="id20"&gt;QoS support with dscp marking&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#neutron-in-tree-api-reference" id="id21"&gt;Neutron in-tree API reference&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#qos-minimum-egrees-bandwidth" id="id22"&gt;QoS minimum egrees bandwidth&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#improved-validation-mechanism-for-qos-rules-with-port-types" id="id23"&gt;Improved validation mechanism for QoS rules with port types&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#security-group-logging" id="id24"&gt;Security-group Logging&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#differentiate-between-service-and-floating-subnets" id="id25"&gt;Differentiate between service and floating subnets&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#enable-adoption-of-an-existing-subnet-into-a-subnetpool" id="id26"&gt;Enable adoption of an existing subnet into a subnetpool&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#allow-vm-to-boot-without-l3-address-subnet" id="id27"&gt;Allow vm to boot without l3 address(subnet)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#add-neutron-extension-resource-timestamp" id="id28"&gt;add-neutron-extension-resource-timestamp&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfes" id="id29"&gt;RFEs&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#openstack-services-should-support-sighup-signal" id="id30"&gt;Openstack services should support SIGHUP signal&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-neutron-support-for-osprofiler" id="id31"&gt;[RFE] Neutron support for OSprofiler&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-lbaas-ssh-connection-timeout" id="id32"&gt;[RFE] [LBaaS] ssh connection timeout&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-add-api-to-set-ipv6-gateway" id="id33"&gt;[RFE] Add API to set ipv6 gateway&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-create-a-full-load-balancing-configuration-with-one-api-call" id="id34"&gt;[RFE] Create a full load balancing configuration with one API call&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-add-the-ability-to-create-lb-vip-and-member-with-network-id" id="id35"&gt;[RFE] Add the ability to create lb vip and member with network_id&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-pure-python-driven-linux-network-configuration" id="id36"&gt;RFE: Pure Python driven Linux network configuration&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-dhcp-agent-should-provide-ipv6-ras-for-isolated-networks-with-ipv6-subnets" id="id37"&gt;[RFE] DHCP agent should provide ipv6 RAs for isolated networks with ipv6 subnets&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-ipam-migration-from-non-pluggable-to-pluggable" id="id38"&gt;[RFE] IPAM migration from non-pluggable to pluggable&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-transition-neutron-cli-from-python-neutronclient-to-python-openstackclient" id="id39"&gt;[RFE] Transition neutron CLI from python-neutronclient to python-openstackclient&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-cascading-delete-for-lbaas-objects" id="id40"&gt;[RFE] Cascading delete for LBaaS Objects&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-add-support-for-external-vxlan-encapsulation-to-neutron-router" id="id41"&gt;[RFE] Add support for external vxlan encapsulation to neutron router&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#ml2-openvswitch-agent-gre-vxlan-tunnel-code-does-not-support-ipv6-addresses-as-tunnel-endpoints" id="id42"&gt;ML2 OpenvSwitch Agent GRE/VXLAN tunnel code does not support IPv6 addresses as tunnel endpoints&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-add-f5-plugin-driver-to-neutron-lbaas" id="id43"&gt;[RFE] Add F5 plugin driver to neutron-lbaas&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#miscellaneous" id="id44"&gt;Miscellaneous&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/nav&gt;
&lt;section id="release-metrics"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2" role="doc-backlink"&gt;Release Metrics&lt;/a&gt;&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Release Metrics&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Blueprints targeted&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;25&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Blueprints/RFE implemented&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;14 (56%)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Bug reports submitted&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;789&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Bug reports closed&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;428 (54%)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Fixes released&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;315 (40%)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Incomplete reports&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;51&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;RFEs submitted&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;49&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Bug reports submitted: reports filed since Mar-16-2016 (Newton starts)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bug reports closed: reports marked released, committed, invalid or wontfix&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fixes released: marked released/committed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Incomplete reports: marked incomplete&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Metrics accurate at the time of writing.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="blueprints"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3" role="doc-backlink"&gt;Blueprints&lt;/a&gt;&lt;/h2&gt;
&lt;section id="firewall-as-a-service-api-2-0"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id4" role="doc-backlink"&gt;Firewall as a Service API 2.0&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: skandasw&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/fwaas-api-2.0"&gt;https://blueprints.launchpad.net/neutron/+spec/fwaas-api-2.0&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Granted (testing and documentation lacking)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete (see release notes for more details)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete (unit testing only)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/351582/"&gt;https://review.openstack.org/#/c/351582/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/355576/"&gt;https://review.openstack.org/#/c/355576/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/359320/"&gt;https://review.openstack.org/#/c/359320/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/366916/"&gt;https://review.openstack.org/#/c/366916/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-for-l2-agent-extensions"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id5" role="doc-backlink"&gt;API for l2 agent extensions&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: mangelajo&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/l2-api-extensions"&gt;https://blueprints.launchpad.net/neutron/+spec/l2-api-extensions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Denied (still at specification stage)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Spec: &lt;a class="reference external" href="https://review.openstack.org/#/c/320439/"&gt;https://review.openstack.org/#/c/320439/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="support-multiple-l3-backends"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id6" role="doc-backlink"&gt;Support multiple L3 backends&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete (pending documentation)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: kevinbenton&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/multi-l3-backends"&gt;https://blueprints.launchpad.net/neutron/+spec/multi-l3-backends&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Granted (small testing/devref gaps are being filled)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete (Init, API)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: In progress&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/364001/"&gt;https://review.openstack.org/#/c/364001/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/358866/"&gt;https://review.openstack.org/#/c/358866/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="split-neutron-into-base-library-and-servers-agents"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id7" role="doc-backlink"&gt;Split neutron into base library and servers/agents&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Ongoing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: dougwig&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-lib"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-lib&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: N/A&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Ongoing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/neutron-lib/"&gt;http://docs.openstack.org/developer/neutron-lib/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="upgrade-controllers-with-no-api-downtime"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id8" role="doc-backlink"&gt;Upgrade controllers with no API downtime&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: ihar-hrachyshka&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/online-upgrades"&gt;https://blueprints.launchpad.net/neutron/+spec/online-upgrades&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Denied: no work happened, will be more active in Ocata; has a
dependency on adopt-oslo-versioned-objects-for-db.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-push-style-notifications-for-all-server-agent-information"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id9" role="doc-backlink"&gt;Use push style notifications for all server-&amp;gt;agent information&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete (&amp;gt;50% complete - to land early in Ocata-1)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: kevinbenton&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/push-notifications"&gt;https://blueprints.launchpad.net/neutron/+spec/push-notifications&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Denied (due to incomplete OVO refactoring).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="support-routed-networks-in-neutron"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id10" role="doc-backlink"&gt;Support Routed Networks in Neutron&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete (pending client and Nova support).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: carl-baldwin&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/routed-networks"&gt;https://blueprints.launchpad.net/neutron/+spec/routed-networks&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Granted&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: OSC bindings incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: (unit, more in progress)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: In progress&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: Nova scheduler support is incomplete.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/302395/"&gt;https://review.openstack.org/#/c/302395/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/302223/"&gt;https://review.openstack.org/#/c/302223/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/347188/"&gt;https://review.openstack.org/#/c/347188/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/353115/"&gt;https://review.openstack.org/#/c/353115/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/356013/"&gt;https://review.openstack.org/#/c/356013/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="diagnostics-of-neutron-components"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id11" role="doc-backlink"&gt;Diagnostics of Neutron components&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: hmlnarik-s&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/troubleshooting"&gt;https://blueprints.launchpad.net/neutron/+spec/troubleshooting&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Denied (still at specification stage)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/308973/"&gt;https://review.openstack.org/#/c/308973/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="vlan-aware-vms"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id12" role="doc-backlink"&gt;VLAN aware VMs&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete (pending documentation)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: rossella-o&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/vlan-aware-vms"&gt;https://blueprints.launchpad.net/neutron/+spec/vlan-aware-vms&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Granted (OVS and Linuxbridge agent-side patches need merging but
are moving at fast pace, and the bulk has already merged in a while;
small gaps to fill after that).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete (pending LB+OVS agent patches)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete (unit, functional, API)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: In progress&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/347466/"&gt;https://review.openstack.org/#/c/347466/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/346377/"&gt;https://review.openstack.org/#/c/346377/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/361776/"&gt;https://review.openstack.org/#/c/361776/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="adopt-oslo-versionedobjects-for-database-interactions"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id13" role="doc-backlink"&gt;Adopt oslo.versionedobjects for database interactions&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: ihar-hrachyshka&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/adopt-oslo-versioned-objects-for-db"&gt;https://blueprints.launchpad.net/neutron/+spec/adopt-oslo-versioned-objects-for-db&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Granted (Slipping into Ocata)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="bgp-dynamic-routing-spin-out"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id14" role="doc-backlink"&gt;BGP Dynamic Routing spin out&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: vikschw&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/bgp-spinout"&gt;https://blueprints.launchpad.net/neutron/+spec/bgp-spinout&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Granted&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete (OSC bindings incomplete)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete (unit, API, functional)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/340763/"&gt;https://review.openstack.org/#/c/340763/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="allow-for-per-subnet-dhcp-options"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id15" role="doc-backlink"&gt;Allow for per-subnet dhcp options&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: sambetts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/dhcp-options-per-subnet"&gt;https://blueprints.launchpad.net/neutron/+spec/dhcp-options-per-subnet&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Denied&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-the-new-enginefacade-from-oslo-db"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id16" role="doc-backlink"&gt;Use the new enginefacade from oslo_db&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete (&amp;gt;50% complete)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: akamyshnikova&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/enginefacade-switch"&gt;https://blueprints.launchpad.net/neutron/+spec/enginefacade-switch&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Granted (bulk of the code to enable adoption of new engine facade merged.
There are more follow ups to go in Ocata).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete (unit, functional)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="allow-instance-ingress-bandwidth-limiting"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id17" role="doc-backlink"&gt;Allow instance-ingress bandwidth limiting&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: slaweq&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/instance-ingress-bw-limit"&gt;https://blueprints.launchpad.net/neutron/+spec/instance-ingress-bw-limit&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Denied (a few patches in conflict/stale).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/356690/"&gt;https://review.openstack.org/#/c/356690/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/357055/"&gt;https://review.openstack.org/#/c/357055/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/303626/"&gt;https://review.openstack.org/#/c/303626/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/341186/"&gt;https://review.openstack.org/#/c/341186/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="moving-to-keystone-v3"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id18" role="doc-backlink"&gt;Moving to Keystone v3&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete (pending documentation and codebase cleanup)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: smigiel-dariusz&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/keystone-v3"&gt;https://blueprints.launchpad.net/neutron/+spec/keystone-v3&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Granted (to provide API support).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete (Unit, functional, API)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete (api-ref to be updated)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Complete (deprecation warnings emitted)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/357977/"&gt;https://review.openstack.org/#/c/357977/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/372857/"&gt;https://review.openstack.org/#/c/372857/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="add-agent-extension-framework-for-l3-agent"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id19" role="doc-backlink"&gt;Add agent extension framework for L3 agent&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: njohnston&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/l3-agent-extensions"&gt;https://blueprints.launchpad.net/neutron/+spec/l3-agent-extensions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Granted (bulk of functionality is merged, increased coverage, or
more documentation should be allowed to go in).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete (unit)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:  Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/neutron/devref/agent_extensions.html"&gt;http://docs.openstack.org/developer/neutron/devref/agent_extensions.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="qos-support-with-dscp-marking"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id20" role="doc-backlink"&gt;QoS support with dscp marking&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: victor-r-howard&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ml2-ovs-qos-with-dscp"&gt;https://blueprints.launchpad.net/neutron/+spec/ml2-ovs-qos-with-dscp&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete (from python-neutronclient 4.2.0)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete (unit, API, functional, fullstack)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/draft/networking-guide/config-qos.html"&gt;http://docs.openstack.org/draft/networking-guide/config-qos.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/cli-reference/neutron.html"&gt;http://docs.openstack.org/cli-reference/neutron.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/security-guide/networking/services.html"&gt;http://docs.openstack.org/security-guide/networking/services.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="neutron-in-tree-api-reference"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id21" role="doc-backlink"&gt;Neutron in-tree API reference&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Ongoing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: amotoki&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-in-tree-api-ref"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-in-tree-api-ref&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: In progress&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://developer.openstack.org/api-ref/networking/"&gt;http://developer.openstack.org/api-ref/networking/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="qos-minimum-egrees-bandwidth"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id22" role="doc-backlink"&gt;QoS minimum egrees bandwidth&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete (pending documentation)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: rodolfo-alonso-hernandez&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/qos-min-egress-bw"&gt;https://blueprints.launchpad.net/neutron/+spec/qos-min-egress-bw&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Granted (close to being complete, OVS and Linuxbridge missing
the implementation).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete (no fullstack testing)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reference&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/344145/"&gt;https://review.openstack.org/#/c/344145/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/347302/"&gt;https://review.openstack.org/#/c/347302/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/351833/"&gt;https://review.openstack.org/#/c/351833/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="improved-validation-mechanism-for-qos-rules-with-port-types"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id23" role="doc-backlink"&gt;Improved validation mechanism for QoS rules with port types&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: slaweq&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/qos-rules-validation"&gt;https://blueprints.launchpad.net/neutron/+spec/qos-rules-validation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Denied (requires more work that will slip into Ocata)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rerefences&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/319694/"&gt;https://review.openstack.org/#/c/319694/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/351858/"&gt;https://review.openstack.org/#/c/351858/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-group-logging"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id24" role="doc-backlink"&gt;Security-group Logging&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: y-furukawa-2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/security-group-logging"&gt;https://blueprints.launchpad.net/neutron/+spec/security-group-logging&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Denied (still at specification stage)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/203509/"&gt;https://review.openstack.org/#/c/203509/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="differentiate-between-service-and-floating-subnets"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id25" role="doc-backlink"&gt;Differentiate between service and floating subnets&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete (pending client support)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: john-davidge&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/service-subnets"&gt;https://blueprints.launchpad.net/neutron/+spec/service-subnets&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Granted (nearly complete, pending CLI)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete (unit)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/draft/networking-guide/config-service-subnets.html"&gt;http://docs.openstack.org/draft/networking-guide/config-service-subnets.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/360526/"&gt;https://review.openstack.org/#/c/360526/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="enable-adoption-of-an-existing-subnet-into-a-subnetpool"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id26" role="doc-backlink"&gt;Enable adoption of an existing subnet into a subnetpool&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: ryan-tidwell&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/subnet-onboard"&gt;https://blueprints.launchpad.net/neutron/+spec/subnet-onboard&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Denied (server side patch needs some love).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: In progress&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: In progress&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/348080/"&gt;https://review.openstack.org/#/c/348080/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="allow-vm-to-boot-without-l3-address-subnet"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id27" role="doc-backlink"&gt;Allow vm to boot without l3 address(subnet)&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete (&amp;gt;50% complete)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: carl-baldwin&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/vm-without-l3-address"&gt;https://blueprints.launchpad.net/neutron/+spec/vm-without-l3-address&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Granted (patch actively under review)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Incomplete (allow creation of ports with no fixed IPs)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete (test how security groups behave with an unaddressed ports)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: In progress&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/361455"&gt;https://review.openstack.org/#/c/361455&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="add-neutron-extension-resource-timestamp"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id28" role="doc-backlink"&gt;add-neutron-extension-resource-timestamp&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: zhaobo&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/add-neutron-extension-resource-timestamp"&gt;https://blueprints.launchpad.net/neutron/+spec/add-neutron-extension-resource-timestamp&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Granted (cleanup/refactoring patches from kevinbenton)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="rfes"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id29" role="doc-backlink"&gt;RFEs&lt;/a&gt;&lt;/h2&gt;
&lt;section id="openstack-services-should-support-sighup-signal"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id30" role="doc-backlink"&gt;Openstack services should support SIGHUP signal&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: eezhova&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1276694"&gt;https://bugs.launchpad.net/neutron/+bug/1276694&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Denied&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-neutron-support-for-osprofiler"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id31" role="doc-backlink"&gt;[RFE] Neutron support for OSprofiler&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: dbelova&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1335640"&gt;https://bugs.launchpad.net/neutron/+bug/1335640&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete (release notes)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-lbaas-ssh-connection-timeout"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id32" role="doc-backlink"&gt;[RFE] [LBaaS] ssh connection timeout&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: reedip-banerjee&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1457556"&gt;https://bugs.launchpad.net/neutron/+bug/1457556&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Denied (not progress, not worked on)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-add-api-to-set-ipv6-gateway"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id33" role="doc-backlink"&gt;[RFE] Add API to set ipv6 gateway&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: scollins&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1460720"&gt;https://bugs.launchpad.net/neutron/+bug/1460720&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Denied (not progress, not worked on)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-create-a-full-load-balancing-configuration-with-one-api-call"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id34" role="doc-backlink"&gt;[RFE] Create a full load balancing configuration with one API call&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: trevor-vardeman&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1463202"&gt;https://bugs.launchpad.net/neutron/+bug/1463202&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Granted (to fill testing/documentation gaps).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete (unit)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-add-the-ability-to-create-lb-vip-and-member-with-network-id"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id35" role="doc-backlink"&gt;[RFE] Add the ability to create lb vip and member with network_id&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: dougwig&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1465758"&gt;https://bugs.launchpad.net/neutron/+bug/1465758&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Granted&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/363302/"&gt;https://review.openstack.org/#/c/363302/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-pure-python-driven-linux-network-configuration"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id36" role="doc-backlink"&gt;RFE: Pure Python driven Linux network configuration&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: gus&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1492714"&gt;https://bugs.launchpad.net/neutron/+bug/1492714&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Denied (not progress, not worked on).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-dhcp-agent-should-provide-ipv6-ras-for-isolated-networks-with-ipv6-subnets"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id37" role="doc-backlink"&gt;[RFE] DHCP agent should provide ipv6 RAs for isolated networks with ipv6 subnets&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: None&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1498987"&gt;https://bugs.launchpad.net/neutron/+bug/1498987&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Denied (not progress, not worked on).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-ipam-migration-from-non-pluggable-to-pluggable"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id38" role="doc-backlink"&gt;[RFE] IPAM migration from non-pluggable to pluggable&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete (pending documentation)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: carl-baldwin&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1516156"&gt;https://bugs.launchpad.net/neutron/+bug/1516156&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1588984"&gt;https://bugs.launchpad.net/neutron/+bug/1588984&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-transition-neutron-cli-from-python-neutronclient-to-python-openstackclient"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id39" role="doc-backlink"&gt;[RFE] Transition neutron CLI from python-neutronclient to python-openstackclient&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Ongoing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: rtheis&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1521291"&gt;https://bugs.launchpad.net/neutron/+bug/1521291&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: N/A (OSC in Mitaka has a significant increase in support for core Neutron
resources. In addition, there is now an OSC plugin for some advanced neutron
features and services. The overall status is available in the &lt;a class="reference external" href="http://docs.openstack.org/developer/python-neutronclient/devref/transition_to_osc.html"&gt;docs&lt;/a&gt;
with a detailed status available on &lt;a class="reference external" href="https://etherpad.openstack.org/p/osc-neutron-support"&gt;etherpad&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-cascading-delete-for-lbaas-objects"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id40" role="doc-backlink"&gt;[RFE] Cascading delete for LBaaS Objects&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: brandon-logan&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1521783"&gt;https://bugs.launchpad.net/neutron/+bug/1521783&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Denied (not currently worked on).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-add-support-for-external-vxlan-encapsulation-to-neutron-router"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id41" role="doc-backlink"&gt;[RFE] Add support for external vxlan encapsulation to neutron router&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: ruansx&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1525059"&gt;https://bugs.launchpad.net/neutron/+bug/1525059&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Denied&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="ml2-openvswitch-agent-gre-vxlan-tunnel-code-does-not-support-ipv6-addresses-as-tunnel-endpoints"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id42" role="doc-backlink"&gt;ML2 OpenvSwitch Agent GRE/VXLAN tunnel code does not support IPv6 addresses as tunnel endpoints&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: brian-haley&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1525895"&gt;https://bugs.launchpad.net/neutron/+bug/1525895&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: Complete (dsvm-neutron-serviceipv6 experimental job)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/draft/networking-guide/config-ipv6.html"&gt;http://docs.openstack.org/draft/networking-guide/config-ipv6.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/devstack/+bug/1619476"&gt;https://bugs.launchpad.net/devstack/+bug/1619476&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-add-f5-plugin-driver-to-neutron-lbaas"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id43" role="doc-backlink"&gt;[RFE] Add F5 plugin driver to neutron-lbaas&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: None&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1539717"&gt;https://bugs.launchpad.net/neutron/+bug/1539717&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE: Denied (no active progress)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="miscellaneous"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id44" role="doc-backlink"&gt;Miscellaneous&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Switch to OVSDB and OpenFlow native interfaces.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: Terry Wilson, IWAMOTO Toshihiro&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/299655/"&gt;https://review.openstack.org/#/c/299655/&lt;/a&gt; (ovsdb)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/319770/"&gt;https://review.openstack.org/#/c/319770/&lt;/a&gt; (openflow)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete (Functional tests show parity,
Tempest API and scenario tests use the new default)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: config options being documented.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 01 Mar 2018 00:00:00 </pubDate></item><item><title>Ocata Postmortem documentation</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/ocata/postmortem/postmortem.html</link><description>

&lt;nav class="contents" id="contents"&gt;
&lt;p class="topic-title"&gt;Contents&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#ocata-postmortem-documentation" id="id1"&gt;Ocata Postmortem documentation&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#release-metrics" id="id2"&gt;Release Metrics&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#blueprints" id="id3"&gt;Blueprints&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#adopt-oslo-versionedobjects-for-database-interactions" id="id4"&gt;Adopt oslo.versionedobjects for database interactions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#split-neutron-into-base-library-and-servers-agents" id="id5"&gt;Split neutron into base library and servers/agents&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#upgrade-controllers-with-no-api-downtime" id="id6"&gt;Upgrade controllers with no API downtime&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#use-push-style-notifications-for-all-server-agent-information" id="id7"&gt;Use push style notifications for all server-&amp;gt;agent information&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#support-routed-networks-in-neutron" id="id8"&gt;Support Routed Networks in Neutron&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#support-agentless-driver-in-neutron-dynamic-routing" id="id9"&gt;Support agentless driver in neutron-dynamic-routing&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#use-the-new-enginefacade-from-oslo-db" id="id10"&gt;Use the new enginefacade from oslo_db&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#firewall-as-a-service-api-2-0" id="id11"&gt;Firewall as a Service API 2.0&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#moving-to-keystone-v3" id="id12"&gt;Moving to Keystone v3&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#api-for-l2-agent-extensions-ovs-flow-management" id="id13"&gt;API for l2 agent extensions (+ovs flow management)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#nova-portbinding-information-for-live-migration" id="id14"&gt;nova portbinding information for live migration&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#neutron-in-tree-api-reference" id="id15"&gt;Neutron in-tree API reference&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#port-data-plane-status" id="id16"&gt;Port data plane status&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#security-group-logging" id="id17"&gt;Security-group Logging&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#diagnostics-of-neutron-components" id="id18"&gt;Diagnostics of Neutron components&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfes" id="id19"&gt;RFEs&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-pure-python-driven-linux-network-configuration" id="id20"&gt;RFE: Pure Python driven Linux network configuration&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-transition-neutron-cli-from-python-neutronclient-to-python-openstackclient" id="id21"&gt;[RFE] Transition neutron CLI from python-neutronclient to python-openstackclient&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#rfe-no-notification-on-floating-ip-status-change" id="id22"&gt;[RFE] No notification on floating ip status change&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#relocate-model-definitions" id="id23"&gt;relocate model definitions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#support-for-dscp-marking-in-linuxbridge-l2-agent" id="id24"&gt;Support for DSCP marking in Linuxbridge L2 agent&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/nav&gt;
&lt;section id="release-metrics"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id2" role="doc-backlink"&gt;Release Metrics&lt;/a&gt;&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Release Metrics&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Blueprints targeted&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;15&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Blueprints/RFE implemented&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Bug reports submitted&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;556&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Bug reports closed&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;334&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Fixes released&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;225&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Incomplete reports&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;29&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;RFEs submitted&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;22&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Bug reports submitted: reports filed since Sep-16-2016 (Ocata starts)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bug reports closed: reports marked released, committed, invalid or wontfix&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fixes released: marked released/committed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Incomplete reports: marked incomplete&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Metrics accurate at the time of writing.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="blueprints"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id3" role="doc-backlink"&gt;Blueprints&lt;/a&gt;&lt;/h2&gt;
&lt;section id="adopt-oslo-versionedobjects-for-database-interactions"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id4" role="doc-backlink"&gt;Adopt oslo.versionedobjects for database interactions&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: ihar-hrachyshka&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/adopt-oslo-versioned-objects-for-db"&gt;https://blueprints.launchpad.net/neutron/+spec/adopt-oslo-versioned-objects-for-db&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Partially implemented&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: unit, API, functional coverage&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: developer documentation (&lt;a class="reference external" href="https://review.openstack.org/#/c/336518/"&gt;https://review.openstack.org/#/c/336518/&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: out of scope&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="split-neutron-into-base-library-and-servers-agents"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id5" role="doc-backlink"&gt;Split neutron into base library and servers/agents&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete (the process to develop and consume neutron-lib).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: boden&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-lib"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-lib&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="upgrade-controllers-with-no-api-downtime"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id6" role="doc-backlink"&gt;Upgrade controllers with no API downtime&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: ihar-hrachyshka&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/online-upgrades"&gt;https://blueprints.launchpad.net/neutron/+spec/online-upgrades&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-push-style-notifications-for-all-server-agent-information"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id7" role="doc-backlink"&gt;Use push style notifications for all server-&amp;gt;agent information&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: kevinbenton&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/push-notifications"&gt;https://blueprints.launchpad.net/neutron/+spec/push-notifications&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE Status: Granted&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Server support partially merged. L2 agent
support pending reviews. In particular, server generates
notifications for all L2 components (port, networks, etc) and
security groups. The only remaining server component waiting to merge
is a way to query for multiple OVO objects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: code has UTs and is executed as part of tempest runs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="support-routed-networks-in-neutron"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id8" role="doc-backlink"&gt;Support Routed Networks in Neutron&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: minsel&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/routed-networks"&gt;https://blueprints.launchpad.net/neutron/+spec/routed-networks&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FFE status: Granted&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Coverage, except scenario coverage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: We got all the functionality we needed from
Nova to implement the updating of routed networks segments IPv4
addresses inventories in the placement API. The Nova scheduler
will not be able to use that information yet to place instances.
Nova will implement that during Pike.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="support-agentless-driver-in-neutron-dynamic-routing"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id9" role="doc-backlink"&gt;Support agentless driver in neutron-dynamic-routing&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: yuyangbj&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/agentless-driver"&gt;https://blueprints.launchpad.net/neutron/+spec/agentless-driver&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="use-the-new-enginefacade-from-oslo-db"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id10" role="doc-backlink"&gt;Use the new enginefacade from oslo_db&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Ongoing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: akamyshnikova&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/enginefacade-switch"&gt;https://blueprints.launchpad.net/neutron/+spec/enginefacade-switch&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="firewall-as-a-service-api-2-0"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id11" role="doc-backlink"&gt;Firewall as a Service API 2.0&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: nate-johnston&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/fwaas-api-2.0"&gt;https://blueprints.launchpad.net/neutron/+spec/fwaas-api-2.0&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: missing two neutron server side patches&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="moving-to-keystone-v3"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id12" role="doc-backlink"&gt;Moving to Keystone v3&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: smigiel-dariusz&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/keystone-v3"&gt;https://blueprints.launchpad.net/neutron/+spec/keystone-v3&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-for-l2-agent-extensions-ovs-flow-management"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id13" role="doc-backlink"&gt;API for l2 agent extensions (+ovs flow management)&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred (spec under discussion)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: david-shaughnessy&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/l2-api-extensions"&gt;https://blueprints.launchpad.net/neutron/+spec/l2-api-extensions&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="nova-portbinding-information-for-live-migration"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id14" role="doc-backlink"&gt;nova portbinding information for live migration&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred (spec merged).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: anindita-das&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/live-migration-portbinding"&gt;https://blueprints.launchpad.net/neutron/+spec/live-migration-portbinding&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="neutron-in-tree-api-reference"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id15" role="doc-backlink"&gt;Neutron in-tree API reference&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Ongoing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: amotoki&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-in-tree-api-ref"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-in-tree-api-ref&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="port-data-plane-status"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id16" role="doc-backlink"&gt;Port data plane status&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred (spec approved).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: cgoncalves&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/port-data-plane-status"&gt;https://blueprints.launchpad.net/neutron/+spec/port-data-plane-status&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-group-logging"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id17" role="doc-backlink"&gt;Security-group Logging&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred (spec in progress).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: y-furukawa-2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/security-group-logging"&gt;https://blueprints.launchpad.net/neutron/+spec/security-group-logging&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="diagnostics-of-neutron-components"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id18" role="doc-backlink"&gt;Diagnostics of Neutron components&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Deferred&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: boden&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/troubleshooting"&gt;https://blueprints.launchpad.net/neutron/+spec/troubleshooting&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="rfes"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id19" role="doc-backlink"&gt;RFEs&lt;/a&gt;&lt;/h2&gt;
&lt;section id="rfe-pure-python-driven-linux-network-configuration"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id20" role="doc-backlink"&gt;RFE: Pure Python driven Linux network configuration&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: omer-anson&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1492714"&gt;https://bugs.launchpad.net/neutron/+bug/1492714&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: Only partially complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-transition-neutron-cli-from-python-neutronclient-to-python-openstackclient"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id21" role="doc-backlink"&gt;[RFE] Transition neutron CLI from python-neutronclient to python-openstackclient&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: amotoki&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1521291"&gt;https://bugs.launchpad.net/neutron/+bug/1521291&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rfe-no-notification-on-floating-ip-status-change"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id22" role="doc-backlink"&gt;[RFE] No notification on floating ip status change&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Incomplete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: boden&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1593793"&gt;https://bugs.launchpad.net/neutron/+bug/1593793&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="relocate-model-definitions"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id23" role="doc-backlink"&gt;relocate model definitions&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status: Complete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: manjeet-s-bhatia&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1597913"&gt;https://bugs.launchpad.net/neutron/+bug/1597913&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation: &lt;a class="reference external" href="https://github.com/openstack/neutron/blob/master/doc/source/devref/db_models.rst"&gt;https://github.com/openstack/neutron/blob/master/doc/source/devref/db_models.rst&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support: N/A&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="support-for-dscp-marking-in-linuxbridge-l2-agent"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id24" role="doc-backlink"&gt;Support for DSCP marking in Linuxbridge L2 agent&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Status:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assignee: slaweq&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1644369"&gt;https://bugs.launchpad.net/neutron/+bug/1644369&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server/Agent support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing coverage:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced/Sub-project support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other Projects support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack support:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizon Support:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 01 Mar 2018 00:00:00 </pubDate></item><item><title>Floating IP rate limit</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/queens/layer-3-rate-limit.html</link><description>

&lt;p&gt;RFE: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1596611"&gt;https://bugs.launchpad.net/neutron/+bug/1596611&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Floating IP bandwidth is unrestricted now. But the NIC and the export of data
center may have a limitation for a cloud deployment. Then floating IP rate
limit is needed.&lt;/p&gt;
&lt;p&gt;This spec describes how to add a built-in extension to limit the floating IP
bandwidth.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Neutron now has floating IP whose bandwidth is not restricted, then there are
several reasons for adding rate limit to floating IP:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;a) Currently, neutron QoS implementation only affects neutron ports, more
detail is that the bandwidth restriction is based on the neutron port, so all
the VM traffic will be limited under that restriction, including L3 traffic.
L3 needs its IP based implementation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;ol class="loweralpha simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;North/South traffic always rely on infrastructure networking capacity.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;c) In case of Floating IP Traffic, cloud deployment do not have enough
bandwidth to meet the total bandwidth requirement of all tenants at the
same time. Due to this, the SLA of user’s network traffic cannot be
guaranteed. For example, if the VM NICs are given a high QoS value, then
to meet the requirement of each tenant, the DC network would have a heavy
load, thus it may be unable to facilitate additional requests and affect
not only the tenant network bandwidth from North-South, but also East-West
traffic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;d) SNAT traffic in centralized network node will not meet the needs of all
tenant bandwidth either. Because a NIC has limited bandwidth.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="overview"&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
&lt;p&gt;We want to limit the bandwidth of floating IP. At the same time, the east/west
traffic should have no effect.&lt;/p&gt;
&lt;p&gt;Some agreements:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Allow binding QoS policy to floating IP.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each floating IP should have only one QoS policy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L3 agent needs a QoS extension to process L3 IP related QoS rules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;QoS policy parameter is nullable. Floating IP can have no QoS policy
assigned.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How the change works:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Linux TC (Traffic Control) &lt;a class="footnote-reference brackets" href="#id3" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; will be used to implement such functionality.
And for egress traffic a HTB &lt;a class="footnote-reference brackets" href="#id4" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; qdisc will be used to limit the floating
IP outgoing bandwidth.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="solution-proposed"&gt;
&lt;h3&gt;Solution Proposed&lt;/h3&gt;
&lt;section id="server-side-changes"&gt;
&lt;h4&gt;Server side changes&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New floating IP extension for QoS attribute (qos_policy_id).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adding a new relationship table between floating IP and QoS
policy &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;QoSFIPPolicyBinding&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L3 plugin will return the floating IP list with its bonding QoS policy
during router sync RPC.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="l3-agent-side-tc-rules"&gt;
&lt;h4&gt;L3 agent side TC rules&lt;/h4&gt;
&lt;p&gt;Where to install the TC rules:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;For HA/legacy routers, rules for floating IP will be installed into network
node qrouter namespace, and the traffic control device will be qg-device.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For DVR routers, it’s compute node qrouter namespace, but the floating IP
traffic control device will be rfp-device (one of qrouter-namespace to
fip-namespace pair).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For all IPs, in the corresponding namespace, the egress and ingress qdisc
rules are basically the same. The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;{qdisc_id}&lt;/span&gt;&lt;/code&gt; will be used to create the
IPs’ tc filter. Some tips:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Remember all the following commands will be executed in a namespace.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[a-device] represents the qg-device or rfp-device in a namespace.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;{egress/ingress_qdisc_id} is the qdisc handle id.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Create qdisc commands:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;# egress&lt;/span&gt;
&lt;span class="n"&gt;tc&lt;/span&gt; &lt;span class="n"&gt;qdisc&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="n"&gt;htb&lt;/span&gt;

&lt;span class="c1"&gt;# ingress&lt;/span&gt;
&lt;span class="n"&gt;tc&lt;/span&gt; &lt;span class="n"&gt;qdisc&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;ingress&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Actual qdisc rules:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ tc qdisc show dev [a-device]
# egress
qdisc htb {egress_qdisc_id} root refcnt 2 r2q 10 default 0 direct_packets_stat 400

# ingress
qdisc ingress {ingress_qdisc_id} parent ffff:fff1 ----------------
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Then we can use that {ingress_qdisc_id} and {egress_qdisc_id} to create the
L3 IPs filters. Assuming we have a L3 IP 172.16.6.161, and it has a QoS policy
with rule {qos_rate_value: 1000Kbit, qos_burst_value: 1Mb}. The ingress and
egress tc filter create commands will be:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;# ingress
$ tc filter add dev [a-device] parent {ingress_qdisc_id} protocol ip prio 1 \
  u32 match ip dst 172.16.6.161 police \
  rate 1000Kbit burst 1Mb drop flowid :1

# egress
$ tc filter add dev [a-device] parent {egress_qdisc_id} protocol ip prio 1 \
  u32 match ip src 172.16.6.161 police \
  rate 1000Kbit burst 1Mb drop flowid :1
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Actual filter rules:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;# ingress
$ tc -s -d -p filter show dev [a-device] parent {ingress_qdisc_id}
...
filter protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid :1  (rule hit 0 success 0)
  match IP dst 172.16.6.161/32 (success 0 )
 police 0x67 rate 1000Kbit burst 1Mb mtu 64Kb action drop overhead 0b
...

# egress
$ tc -s -d -p filter show dev [a-device] parent {egress_qdisc_id}
...
filter protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid :1  (rule hit 0 success 0)
  match IP src 172.16.6.161/32 (success 0 )
 police 0x68 rate 1000Kbit burst 1Mb mtu 64Kb action drop overhead 0b
...
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="the-neutron-basic-workflow"&gt;
&lt;h3&gt;The neutron basic workflow&lt;/h3&gt;
&lt;section id="floating-ip"&gt;
&lt;h4&gt;Floating IP&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;User create a floating IP.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;Floating IP was associated with a port.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol class="arabic simple" start="3"&gt;
&lt;li&gt;&lt;p&gt;Create/find QoS policy and rule for floating IP.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol class="arabic simple" start="4"&gt;
&lt;li&gt;&lt;p&gt;Bind QoS policy to floating IP (floating IP update API).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol class="arabic simple" start="5"&gt;
&lt;li&gt;&lt;p&gt;L3 agent processes the router and its floating IP.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;ol class="arabic simple" start="6"&gt;
&lt;li&gt;&lt;p&gt;L3 agent sets the TC rules to the qrouter-namespace relevant device.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After this the floating IP will be set under a bandwidth restriction.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="example-l3-agent-side-tc-rules"&gt;
&lt;h3&gt;Example L3 agent side TC rules&lt;/h3&gt;
&lt;p&gt;Assuming that we have a legacy router: cf6951cb-b050-4543-9742-c63a4989edae,
gateway ip: 172.16.6.167, 1Mbps, floating IP: 172.16.10.69, 1Mbps, then in
its scheduled network node you can get the following rules:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;# ip netns exec qrouter-cf6951cb-b050-4543-9742-c63a4989edae ip a&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;lo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LOOPBACK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;UP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;LOWER_UP&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mtu&lt;/span&gt; &lt;span class="mi"&gt;65536&lt;/span&gt; &lt;span class="n"&gt;qdisc&lt;/span&gt; &lt;span class="n"&gt;noqueue&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="n"&gt;UNKNOWN&lt;/span&gt;
    &lt;span class="n"&gt;inet&lt;/span&gt; &lt;span class="mf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="n"&gt;lo&lt;/span&gt;
&lt;span class="mi"&gt;140&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;aba9b05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BROADCAST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MULTICAST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;UP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;LOWER_UP&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mtu&lt;/span&gt; &lt;span class="mi"&gt;1450&lt;/span&gt; &lt;span class="n"&gt;qdisc&lt;/span&gt; &lt;span class="n"&gt;noqueue&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="n"&gt;UNKNOWN&lt;/span&gt;
    &lt;span class="n"&gt;inet&lt;/span&gt; &lt;span class="mf"&gt;192.168.233.1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="n"&gt;brd&lt;/span&gt; &lt;span class="mf"&gt;192.168.233.255&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;aba9b05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;
&lt;span class="mi"&gt;141&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;aef0d42d&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;f9&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BROADCAST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MULTICAST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;UP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;LOWER_UP&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mtu&lt;/span&gt; &lt;span class="mi"&gt;1450&lt;/span&gt; &lt;span class="n"&gt;qdisc&lt;/span&gt; &lt;span class="n"&gt;noqueue&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="n"&gt;UNKNOWN&lt;/span&gt;
    &lt;span class="n"&gt;inet&lt;/span&gt; &lt;span class="mf"&gt;192.168.232.1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="n"&gt;brd&lt;/span&gt; &lt;span class="mf"&gt;192.168.232.255&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;aef0d42d&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;f9&lt;/span&gt;
&lt;span class="mi"&gt;143&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;qg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c99a5832&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BROADCAST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MULTICAST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;UP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;LOWER_UP&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mtu&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt; &lt;span class="n"&gt;qdisc&lt;/span&gt; &lt;span class="n"&gt;htb&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="n"&gt;UNKNOWN&lt;/span&gt;
    &lt;span class="n"&gt;inet&lt;/span&gt; &lt;span class="mf"&gt;172.16.6.167&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="n"&gt;brd&lt;/span&gt; &lt;span class="mf"&gt;172.16.255.255&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;qg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c99a5832&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;
    &lt;span class="n"&gt;inet&lt;/span&gt; &lt;span class="mf"&gt;172.16.10.69&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt; &lt;span class="n"&gt;brd&lt;/span&gt; &lt;span class="mf"&gt;172.16.10.69&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;qg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c99a5832&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;
       &lt;span class="n"&gt;valid_lft&lt;/span&gt; &lt;span class="n"&gt;forever&lt;/span&gt; &lt;span class="n"&gt;preferred_lft&lt;/span&gt; &lt;span class="n"&gt;forever&lt;/span&gt;

&lt;span class="c1"&gt;# ip netns exec qrouter-cf6951cb-b050-4543-9742-c63a4989edae tc qdisc show dev qg-c99a5832-7f&lt;/span&gt;
&lt;span class="n"&gt;qdisc&lt;/span&gt; &lt;span class="n"&gt;htb&lt;/span&gt; &lt;span class="mi"&gt;801&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="n"&gt;refcnt&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;r2q&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;direct_packets_stat&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;
&lt;span class="n"&gt;qdisc&lt;/span&gt; &lt;span class="n"&gt;ingress&lt;/span&gt; &lt;span class="n"&gt;ffff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt; &lt;span class="n"&gt;ffff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fff1&lt;/span&gt; &lt;span class="o"&gt;----------------&lt;/span&gt;

&lt;span class="c1"&gt;# ip netns exec qrouter-cf6951cb-b050-4543-9742-c63a4989edae tc -s -d -p filter show dev qg-c99a5832-7f parent 801b:&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="nb"&gt;filter&lt;/span&gt; &lt;span class="n"&gt;protocol&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="n"&gt;pref&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;u32&lt;/span&gt; &lt;span class="n"&gt;fh&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="mi"&gt;2048&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="n"&gt;ht&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="n"&gt;bkt&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;flowid&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="mf"&gt;172.16.6.167&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;police&lt;/span&gt; &lt;span class="mh"&gt;0xa74&lt;/span&gt; &lt;span class="n"&gt;rate&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="n"&gt;Kbit&lt;/span&gt; &lt;span class="n"&gt;burst&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;Mb&lt;/span&gt; &lt;span class="n"&gt;mtu&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="n"&gt;Kb&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="n"&gt;drop&lt;/span&gt; &lt;span class="n"&gt;overhead&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;bind&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

 &lt;span class="n"&gt;Sent&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;pkts&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dropped&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;overlimits&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;filter&lt;/span&gt; &lt;span class="n"&gt;protocol&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="n"&gt;pref&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;u32&lt;/span&gt; &lt;span class="n"&gt;fh&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;801&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="mi"&gt;2049&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="n"&gt;ht&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="n"&gt;bkt&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;flowid&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="mf"&gt;172.16.10.69&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;police&lt;/span&gt; &lt;span class="mh"&gt;0xa76&lt;/span&gt; &lt;span class="n"&gt;rate&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="n"&gt;Kbit&lt;/span&gt; &lt;span class="n"&gt;burst&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;Mb&lt;/span&gt; &lt;span class="n"&gt;mtu&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="n"&gt;Kb&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="n"&gt;drop&lt;/span&gt; &lt;span class="n"&gt;overhead&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;bind&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

 &lt;span class="n"&gt;Sent&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;pkts&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dropped&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;overlimits&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# ip netns exec qrouter-cf6951cb-b050-4543-9742-c63a4989edae tc -s -d -p filter show dev qg-c99a5832-7f parent ffff:&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="nb"&gt;filter&lt;/span&gt; &lt;span class="n"&gt;protocol&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="n"&gt;pref&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;u32&lt;/span&gt; &lt;span class="n"&gt;fh&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="mi"&gt;2048&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="n"&gt;ht&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="n"&gt;bkt&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;flowid&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;dst&lt;/span&gt; &lt;span class="mf"&gt;172.16.6.167&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;police&lt;/span&gt; &lt;span class="mh"&gt;0xa73&lt;/span&gt; &lt;span class="n"&gt;rate&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="n"&gt;Kbit&lt;/span&gt; &lt;span class="n"&gt;burst&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;Mb&lt;/span&gt; &lt;span class="n"&gt;mtu&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="n"&gt;Kb&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="n"&gt;drop&lt;/span&gt; &lt;span class="n"&gt;overhead&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;bind&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

 &lt;span class="n"&gt;Sent&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;pkts&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dropped&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;overlimits&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;filter&lt;/span&gt; &lt;span class="n"&gt;protocol&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="n"&gt;pref&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;u32&lt;/span&gt; &lt;span class="n"&gt;fh&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;801&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="mi"&gt;2049&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="n"&gt;ht&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="n"&gt;bkt&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;flowid&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;dst&lt;/span&gt; &lt;span class="mf"&gt;172.16.10.69&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;police&lt;/span&gt; &lt;span class="mh"&gt;0xa75&lt;/span&gt; &lt;span class="n"&gt;rate&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="n"&gt;Kbit&lt;/span&gt; &lt;span class="n"&gt;burst&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;Mb&lt;/span&gt; &lt;span class="n"&gt;mtu&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="n"&gt;Kb&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="n"&gt;drop&lt;/span&gt; &lt;span class="n"&gt;overhead&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;bind&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

 &lt;span class="n"&gt;Sent&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;pkts&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dropped&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;overlimits&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And DVR router 0580788c-c919-447c-aea1-87d415aa173a with floating IP
172.16.6.161 1Mbps in a compute node:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;# ip netns exec qrouter-0580788c-c919-447c-aea1-87d415aa173a ip a&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;lo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LOOPBACK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;UP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;LOWER_UP&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mtu&lt;/span&gt; &lt;span class="mi"&gt;65536&lt;/span&gt; &lt;span class="n"&gt;qdisc&lt;/span&gt; &lt;span class="n"&gt;noqueue&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="n"&gt;UNKNOWN&lt;/span&gt;
    &lt;span class="n"&gt;inet&lt;/span&gt; &lt;span class="mf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="n"&gt;lo&lt;/span&gt;
&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rfp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0580788&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BROADCAST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MULTICAST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;UP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;LOWER_UP&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mtu&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt; &lt;span class="n"&gt;qdisc&lt;/span&gt; &lt;span class="n"&gt;htb&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="n"&gt;UP&lt;/span&gt; &lt;span class="n"&gt;qlen&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
    &lt;span class="n"&gt;inet&lt;/span&gt; &lt;span class="mf"&gt;169.254.106.114&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;rfp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0580788&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;
    &lt;span class="n"&gt;inet&lt;/span&gt; &lt;span class="mf"&gt;172.16.6.161&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt; &lt;span class="n"&gt;brd&lt;/span&gt; &lt;span class="mf"&gt;172.16.6.161&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;rfp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0580788&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="mi"&gt;102&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;43185e93&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;af&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BROADCAST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MULTICAST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;UP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;LOWER_UP&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mtu&lt;/span&gt; &lt;span class="mi"&gt;1450&lt;/span&gt; &lt;span class="n"&gt;qdisc&lt;/span&gt; &lt;span class="n"&gt;noqueue&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="n"&gt;UNKNOWN&lt;/span&gt;
    &lt;span class="n"&gt;inet&lt;/span&gt; &lt;span class="mf"&gt;192.168.199.1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="n"&gt;brd&lt;/span&gt; &lt;span class="mf"&gt;192.168.199.255&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;43185e93&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;af&lt;/span&gt;
&lt;span class="mi"&gt;104&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;51635&lt;/span&gt;&lt;span class="n"&gt;a61&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BROADCAST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MULTICAST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;UP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;LOWER_UP&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mtu&lt;/span&gt; &lt;span class="mi"&gt;1450&lt;/span&gt; &lt;span class="n"&gt;qdisc&lt;/span&gt; &lt;span class="n"&gt;noqueue&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="n"&gt;UNKNOWN&lt;/span&gt;
    &lt;span class="n"&gt;inet&lt;/span&gt; &lt;span class="mf"&gt;192.168.198.1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="n"&gt;brd&lt;/span&gt; &lt;span class="mf"&gt;192.168.198.255&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;51635&lt;/span&gt;&lt;span class="n"&gt;a61&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;46&lt;/span&gt;

&lt;span class="c1"&gt;# ip netns exec qrouter-0580788c-c919-447c-aea1-87d415aa173a tc qdisc show dev rfp-0580788c-c&lt;/span&gt;
&lt;span class="n"&gt;qdisc&lt;/span&gt; &lt;span class="n"&gt;htb&lt;/span&gt; &lt;span class="mi"&gt;801&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="n"&gt;refcnt&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;r2q&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;direct_packets_stat&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="n"&gt;qdisc&lt;/span&gt; &lt;span class="n"&gt;ingress&lt;/span&gt; &lt;span class="n"&gt;ffff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt; &lt;span class="n"&gt;ffff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fff1&lt;/span&gt; &lt;span class="o"&gt;----------------&lt;/span&gt;

&lt;span class="c1"&gt;# ip netns exec qrouter-0580788c-c919-447c-aea1-87d415aa173a tc -s -d -p filter show dev rfp-0580788c-c parent 801e:&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="nb"&gt;filter&lt;/span&gt; &lt;span class="n"&gt;protocol&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="n"&gt;pref&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;u32&lt;/span&gt; &lt;span class="n"&gt;fh&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="mi"&gt;2048&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="n"&gt;ht&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="n"&gt;bkt&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;flowid&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="mf"&gt;172.16.6.161&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;police&lt;/span&gt; &lt;span class="mh"&gt;0x68&lt;/span&gt; &lt;span class="n"&gt;rate&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="n"&gt;Kbit&lt;/span&gt; &lt;span class="n"&gt;burst&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;Mb&lt;/span&gt; &lt;span class="n"&gt;mtu&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="n"&gt;Kb&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="n"&gt;drop&lt;/span&gt; &lt;span class="n"&gt;overhead&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;bind&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

 &lt;span class="n"&gt;Sent&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;pkts&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dropped&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;overlimits&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# ip netns exec qrouter-0580788c-c919-447c-aea1-87d415aa173a tc -s -d -p filter show dev rfp-0580788c-c parent ffff:&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="nb"&gt;filter&lt;/span&gt; &lt;span class="n"&gt;protocol&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="n"&gt;pref&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;u32&lt;/span&gt; &lt;span class="n"&gt;fh&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="mi"&gt;2048&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="n"&gt;ht&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="n"&gt;bkt&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;flowid&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;dst&lt;/span&gt; &lt;span class="mf"&gt;172.16.6.161&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;police&lt;/span&gt; &lt;span class="mh"&gt;0x67&lt;/span&gt; &lt;span class="n"&gt;rate&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="n"&gt;Kbit&lt;/span&gt; &lt;span class="n"&gt;burst&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;Mb&lt;/span&gt; &lt;span class="n"&gt;mtu&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="n"&gt;Kb&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="n"&gt;drop&lt;/span&gt; &lt;span class="n"&gt;overhead&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;bind&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

 &lt;span class="n"&gt;Sent&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;pkts&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dropped&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;overlimits&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;Only IPv4 has the concept of floating IP.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;For floating IP:
A new table, QoSFIPPolicyBinding, will be created to represent the 1-1
association between floating IP and QoS policy, each policy has rules in both
ingress and egress direction.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;New floating IP API extension:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;floatingip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="o"&gt;...&lt;/span&gt;
       &lt;span class="s1"&gt;'qos_policy_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                         &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;New floating IP commands for creation, deletion and update elements with
QoS property:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;floating&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="n"&gt;policy_id&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;floating&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="n"&gt;policy_id&lt;/span&gt; &lt;span class="n"&gt;floating_ip_id&lt;/span&gt;
&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;floating&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="n"&gt;unset&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="n"&gt;floating_ip_id&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;LIU Yulong &amp;lt;&lt;a class="reference external" href="mailto:i%40liuyulong.me"&gt;i&lt;span&gt;@&lt;/span&gt;liuyulong&lt;span&gt;.&lt;/span&gt;me&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create model tables and API extensions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New TC command wrapper for floating IP rate limit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L3 agent extension for QoS rule installation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="functionality"&gt;
&lt;h3&gt;Functionality&lt;/h3&gt;
&lt;p&gt;The bandwidth of floating IP should be restricted properly. Adding new
fullstack and tempest scenarios to test the bandwidth of ingress and egress.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.tldp.org/HOWTO/Traffic-Control-HOWTO"&gt;Linux Traffic Control&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.linuxjournal.com/article/7562"&gt;Linux HTB Queuing&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;section id="related-information"&gt;
&lt;h3&gt;Related Information&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/424466/"&gt;Floating IP rate limit&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/424468/"&gt;Router gateway rate limit (abandoned)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/453458/"&gt;Adding L3 rate limit TC lib&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 01 Mar 2018 00:00:00 </pubDate></item><item><title>Logging API for security-group-rules</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/queens/logging-API-for-security-group-rules.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1468366"&gt;https://bugs.launchpad.net/neutron/+bug/1468366&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec implements a way to capture and store events related to security
groups.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Operators&lt;/em&gt; (including cloud admin and developers) or projects want to store
logs of network traffic of:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;North-south network traffic travels between an instance and external network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;East-west network traffic travels between instances.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To detect illegal communication or attack patterns, alert abnormal activities
for compliance reason.&lt;/p&gt;
&lt;p&gt;In addition, these logs can also be used for debugging security groups (help
project make sure security group rules work as expected or not). However
this is not the main goal since other approaches present (e.g TaaS, tcpdump)
to fix the same problem.&lt;/p&gt;
&lt;p&gt;In Neutron, all traffic allowed/dropped on instances are managed by security
groups. However, logging is currently a missing feature in security groups.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;To address this problem, we’d like to propose a logging API with objective:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Define format and ways to collect events related to security groups.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Logging API will collect ACCEPT or DROP or both events related to security
groups configured on port(s). Please refer to &lt;a class="reference internal" href="#expected-api-behavior"&gt;Expected API behavior&lt;/a&gt; for
more details.&lt;/p&gt;
&lt;p&gt;This spec implements logging API for security groups for OVS native firewall
(OVS) and Iptables-based (Linux Brigde) for &lt;em&gt;operator-only&lt;/em&gt;. It also lays out
a model which can be extended to other resources (e.g Firewall logging) easily.&lt;/p&gt;
&lt;p&gt;Initially, we have both PoC for OVS native firewall and Iptables-based logging.
The OVS native firewall logging will be completely supported first as it  is
now becoming the default driver, Iptables-based logging will be finished later.
This API is considered to work consistently between OVS native firewall and
Iptables-based logging.&lt;/p&gt;
&lt;p&gt;Regarding &lt;strong&gt;multiple driver environment&lt;/strong&gt;, this feature will have a similar
validation like QoS &lt;a class="footnote-reference brackets" href="#id9" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; as a first approach. &lt;a class="footnote-reference brackets" href="#id10" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;section id="logging-implementation"&gt;
&lt;h3&gt;Logging implementation&lt;/h3&gt;
&lt;p&gt;Logging API is designed as a service plugin. It is defined as a generic logging
API for resources such as security groups and firewall.&lt;/p&gt;
&lt;p&gt;In server side, the class design for LoggingApiPlugin would look like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+-----------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;LoggingApiPluginBase&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------^------------+&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;LoggingApiPlugin&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;_init_&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;get_logs&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;get_log&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;create_log&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;update_log&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;delete_log&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The reference implementation can be found in &lt;a class="footnote-reference brackets" href="#id11" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The LoggingExtension is an agent extension. It is common for all logging
resources like security groups and firewall. The LoggingExtension will receive
CREATED/UPDATED/DELETED events of the logging resource and pass these events
to logging drivers. Each logging driver defines the resources it supports.
In case of security group, we can have a security group logging driver implemented
as OVSFirewallLogging or IptablesLoggingDriver.&lt;/p&gt;
&lt;p&gt;Class design of LoggingExtension would look like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+-----------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;AgentExtension&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------------^----------+&lt;/span&gt;
             &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------------+----------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;LoggingExtension&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;consume_api&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;_handle_notification&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Class design for LoggingDriver would look like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                 &lt;span class="o"&gt;+-----------------------------+&lt;/span&gt;
                 &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;LoggingDriver&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
                 &lt;span class="o"&gt;+-----------------------------+&lt;/span&gt;
                 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;SUPPORTED_LOGGING_TYPES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
                 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
                 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;start_logging&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log_resource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
                 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;stop_logging&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log_resource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
                 &lt;span class="o"&gt;+--------------^--------------+&lt;/span&gt;
                                &lt;span class="o"&gt;|&lt;/span&gt;
               &lt;span class="o"&gt;+----------------+-----------------+&lt;/span&gt;
               &lt;span class="o"&gt;|&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------+---------------+&lt;/span&gt;   &lt;span class="o"&gt;+--------------+---------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;IptablesLoggingDriver&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;OVSFirewallLoggingDriver&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------------------------------+&lt;/span&gt;   &lt;span class="o"&gt;+------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;SUPPORTED_LOGGING_TYPES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;SUPPORTED_LOGGING_TYPES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;start_logging&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log_resource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;start_logging&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log_resource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;stop_logging&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log_resource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;stop_logging&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log_resource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;_handle_logging&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                              &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;_create_security_group_log&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;_delete_security_group_log&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For OVS firewall: OVSFirewallLoggingDriver will act as a controller program.
It runs in each compute node to handle packet_in to produce a log line per
packet to a file.  To generate a packet in message for ACCEPT event: The
OVSFirewallLoggingDriver will insert “actions=controller” to flows matched
with security group rules whose conntrack state is NEW (first packet). It  will
also insert flows with ‘actions=controller’ before flows has ‘actions=drop’ and
conntrack state is INVALID or NOT ESTABLISHED to generate packet_in messages
for DROP event via port-number for project-isolation. For a flow example would
look like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For ingress tables:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;73&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=+&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;icmp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;d0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NXM_NX_REG6&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0..15&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;&lt;span class="n"&gt;strip_vlan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;CONTROLLER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;65535&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=+&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;icmp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;d0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NXM_NX_REG6&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0..15&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;&lt;span class="n"&gt;strip_vlan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=+&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rpl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;icmp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;d0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;strip_vlan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;53&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_mark&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0x1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CONTROLLER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;65535&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_mark&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0x1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;drop&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=+&lt;/span&gt;&lt;span class="n"&gt;inv&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;trk&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;drop&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=+&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;rpl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_mark&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;d0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;strip_vlan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;inv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_mark&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;d0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;strip_vlan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CONTROLLER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;65535&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;drop&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=+&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NXM_NX_REG6&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0..15&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="n"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mh"&gt;0x1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NXM_NX_CT_MARK&lt;/span&gt;&lt;span class="p"&gt;[]))&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=+&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ipv6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NXM_NX_REG6&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0..15&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="n"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mh"&gt;0x1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NXM_NX_CT_MARK&lt;/span&gt;&lt;span class="p"&gt;[]))&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;drop&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For egress tables:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;73&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=+&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;icmp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;d0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;resubmit&lt;/span&gt;&lt;span class="p"&gt;(,&lt;/span&gt;&lt;span class="mi"&gt;73&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="n"&gt;CONTROLLER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;65535&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=+&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;icmp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;d0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;resubmit&lt;/span&gt;&lt;span class="p"&gt;(,&lt;/span&gt;&lt;span class="mi"&gt;73&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=+&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rpl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;icmp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dl_src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;d0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;resubmit&lt;/span&gt;&lt;span class="p"&gt;(,&lt;/span&gt;&lt;span class="mi"&gt;73&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;53&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_mark&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0x1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CONTROLLER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;65535&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_mark&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0x1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;drop&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=+&lt;/span&gt;&lt;span class="n"&gt;inv&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;trk&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;drop&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=+&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;rpl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_mark&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NORMAL&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;inv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_mark&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NORMAL&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CONTROLLER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;65535&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;drop&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=+&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NXM_NX_REG6&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0..15&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="n"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mh"&gt;0x1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NXM_NX_CT_MARK&lt;/span&gt;&lt;span class="p"&gt;[]))&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ct_state&lt;/span&gt;&lt;span class="o"&gt;=+&lt;/span&gt;&lt;span class="n"&gt;est&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ipv6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;reg5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NXM_NX_REG6&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0..15&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="n"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mh"&gt;0x1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NXM_NX_CT_MARK&lt;/span&gt;&lt;span class="p"&gt;[]))&lt;/span&gt;
&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;drop&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The reference implementation can be found in &lt;a class="footnote-reference brackets" href="#id13" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For Iptables-based: IptablesLoggingDriver implementation is quite clear.
IptablesLoggingDriver just adds NFLOG rules to iptables &lt;a class="footnote-reference brackets" href="#id12" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Cloud deployers can choose &lt;strong&gt;log_driver&lt;/strong&gt; for OVS native firewall driver or
iptables driver by specifying &lt;strong&gt;ovs_fw_log&lt;/strong&gt; or &lt;strong&gt;iptables_log&lt;/strong&gt;. They are also
able to configure &lt;strong&gt;rate_limit&lt;/strong&gt; and &lt;strong&gt;burst_limit&lt;/strong&gt; &lt;a class="footnote-reference brackets" href="#id16" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; to limit maximum
packets logging per second.  Log output file can be specified by option
&lt;strong&gt;local_output_log_base&lt;/strong&gt;. These options are defined in
/etc/neutron/plugins/ml2/ml2_conf.ini:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# Driver for security group logging in the L2 agent (string value)&lt;/span&gt;
&lt;span class="c1"&gt;# 'ovs_fw_log' or 'iptables_log'&lt;/span&gt;
&lt;span class="n"&gt;log_driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ovs_fw_log&lt;/span&gt;

&lt;span class="c1"&gt;# Maximum packets logging per second. (integer value, at least 100)&lt;/span&gt;
&lt;span class="n"&gt;rate_limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;

&lt;span class="c1"&gt;# Maximum number of packets per rate_limit(integer value, at least 25)&lt;/span&gt;
&lt;span class="n"&gt;burst_limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;

&lt;span class="c1"&gt;# Output logfile&lt;/span&gt;
&lt;span class="n"&gt;local_output_log_base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;syslog&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To consume log-data, operators can:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;use third-party services such as Monasca service to consume log-data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;access directly to ‘local_output_log_base’ to take log-data.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="expected-api-behavior"&gt;
&lt;h3&gt;Expected API behavior&lt;/h3&gt;
&lt;p&gt;This spec takes security groups logging for an example:&lt;/p&gt;
&lt;p&gt;Operators can collect security events (ACCEPT/DROP or ALL (both ACCEPT and
DROP)) for some cases:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;collect events related to a specific security group applied to all VMs
by passing its security group ID to ‘resource_id’.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;collect events related to a specific security group applied to a
specific VM by passing its security group ID to ‘resource_id’ and its
bound Neutron port ID to ‘target_id’.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;collect events related to all security groups being applied to a
specific VM by passing its Neutron port ID to ‘target_id’.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;collect events related to security groups in a project: in this case
operators do not pass any value to ‘resource_id’ or ‘target_id’.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;More details, this API will log first packet which is matched with security
group rule for ACCEPT events. It will also log all packets which is unmatched
with any security group rules for DROP events.&lt;/p&gt;
&lt;p&gt;Please note that, depends on above use cases, if a new VM or a new security
group or a new security group rule is launched, its related security events
will be collected, too. On the other hands, if a VM or a security group or a
security group rule is deleted, its related security events will be not logged.
However, security events related to the remains will still be logged.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="future-work-beyond-this-spec"&gt;
&lt;h3&gt;Future work beyond this spec&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Extending logging for FWaaS v2.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Exposing the logging API for projects (e.g by using RBAC).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-operation-sample"&gt;
&lt;h3&gt;API operation sample&lt;/h3&gt;
&lt;p&gt;Take below scenario as an example:&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Operator boots a number of VMs, the VMs’ traffic is restricted
by security-group-rules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check supported logging capabilities&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;GET /v2.0/logging/loggable-resources&lt;/p&gt;
&lt;div class="highlight-json notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"loggable_resources"&lt;/span&gt;&lt;span class="p"&gt;:[{&lt;/span&gt;&lt;span class="nt"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"security_group"&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;strong&gt;logging-resource&lt;/strong&gt; and define events related to security groups
need collecting for this project.  For example, operator wants to collect
all ACCEPT &amp;amp; DROP events related to all security groups applied in project
demo (Read &lt;a class="reference internal" href="#expected-api-behavior"&gt;Expected API behavior&lt;/a&gt; section for more details)&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;POST /v2.0/logging/logs&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"log"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"create_log_test1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Collecting all security events in project demo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8d4c70a21fed4aeba121a1a429ba0d04"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"resource_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"security_group"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALL"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"log"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5f126d84-551a-4dcf-bb01-0e9c0df0c793"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8d4c70a21fed4aeba121a1a429ba0d04"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"create_log_test1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Collecting all security events in project demo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"resource_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"security_group"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"resource_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"target_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operator use external services (e.g Monasca) to consume log-data.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="example-logging-format"&gt;
&lt;h3&gt;Example logging format&lt;/h3&gt;
&lt;p&gt;Logging output should include timestamp, action(ACCEPT/DROP) project ID,
logging-resource ID, VM port ID, source MAC, destination MAC,
source IP address, destination IP address, protocol, source L4 port and
destination L4 port.  Making the format configurable is out of the scope
though and the format can be defined in implementation phase.&lt;/p&gt;
&lt;p&gt;For initial implementation would look like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;log-data of an ACCEPT event:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;May&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;05&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;07&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ACCEPT&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;736672&lt;/span&gt;&lt;span class="n"&gt;c700cd43e1bd321aeaf940365c&lt;/span&gt;
&lt;span class="n"&gt;log_resource_ids&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'4522efdf-8d44-4e19-b237-64cafc49469b'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'42332d89-df42-4588-a2bb-3ce50829ac51'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;vm_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;e0259ade&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;86&lt;/span&gt;&lt;span class="n"&gt;de&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;482&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a717&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;f58258f7173f&lt;/span&gt;
&lt;span class="n"&gt;ethernet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'fa:16:3e:ec:36:32'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ethertype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'fa:16:3e:50:aa:b5'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;ipv4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csum&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;62071&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'10.0.0.4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;header_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;identification&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;36638&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;proto&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'172.24.4.10'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;tos&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;total_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;63&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;tcp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ack&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;bits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;csum&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;15097&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dst_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TCPOptionMaximumSegmentSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;max_seg_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1460&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;TCPOptionSACKPermitted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;TCPOptionTimestamps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ts_ecr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ts_val&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;196418896&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;TCPOptionNoOperation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;TCPOptionWindowScale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;shift_cnt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
&lt;span class="n"&gt;seq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3284890090&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;src_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;47825&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;urgent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;window_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;14600&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;log-data of a DROP event:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;May&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;05&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;07&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DROP&lt;/span&gt; &lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;736672&lt;/span&gt;&lt;span class="n"&gt;c700cd43e1bd321aeaf940365c&lt;/span&gt;
&lt;span class="n"&gt;log_resource_ids&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'4522efdf-8d44-4e19-b237-64cafc49469b'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;vm_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;e0259ade&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;86&lt;/span&gt;&lt;span class="n"&gt;de&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;482&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a717&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;f58258f7173f&lt;/span&gt;
&lt;span class="n"&gt;ethernet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'fa:16:3e:ec:36:32'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ethertype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'fa:16:3e:50:aa:b5'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;ipv4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csum&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;62071&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'10.0.0.4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;header_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;identification&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;36638&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;proto&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'172.24.4.10'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;tos&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;total_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;63&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;tcp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ack&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;bits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;csum&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;15097&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dst_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TCPOptionMaximumSegmentSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;max_seg_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1460&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;TCPOptionSACKPermitted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;TCPOptionTimestamps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ts_ecr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ts_val&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;196418896&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;TCPOptionNoOperation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;TCPOptionWindowScale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;shift_cnt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
&lt;span class="n"&gt;seq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3284890090&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;src_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;47825&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;urgent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;window_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;14600&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;This model defines a generic model for all logging resources like security
groups and firewall.&lt;/p&gt;
&lt;p&gt;Log model would look like:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW(No
update)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Project ID of Logging
object owner&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;none&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Logging object name&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;none&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Logging object description&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;enabled&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Boolean&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Enable/disable log&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;resource_type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW(No
update)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;none&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Logging resource type, it could be
‘security_group’ in the initial
implemenation&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;resource_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW(No
update)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ID of resource which is enabled to
be logged. When a resource_id (which
could be a security group ID in the
initial implementation) is specified,
its related events will be collected.
For detail usage refer to
&lt;a class="reference internal" href="#expected-api-behavior"&gt;Expected API behavior&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;event&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW(No
update)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;none&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ACCEPT/DROP or ALL can be specified.
ALL is set as default.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;target_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW(No
update)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ID of resource (which could be a port
ID in the initial implementation),
where we want to collect log. When a
target_id is specified, events
related to it will be colleted.
For detail usage refer to
&lt;a class="reference internal" href="#expected-api-behavior"&gt;Expected API behavior&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;The new resources will be added.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;LOGGING_PREFIX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/logging'&lt;/span&gt;
&lt;span class="n"&gt;EVENTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'ACCEPT'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'DROP'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ALL'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'log'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'project_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TENANT_ID_MAX_LEN&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                       &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NAME_MAX_LEN&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                 &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DESCRIPTION_MAX_LEN&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'resource_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:validate_log_resource_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                          &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'resource_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
        &lt;span class="s1"&gt;'event'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;EVENTS&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                  &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'ALL'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'target_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
        &lt;span class="s1"&gt;'enabled'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_boolean&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="s1"&gt;'loggable_resources'&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
        &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Object&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;URI&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;log&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;/logging/logs&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;log&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;/logging/logs&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;GET&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;log&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;/logging/logs/{logging-resource-id}&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;GET&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;log&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;/logging/logs/{logging-resource-id}&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;DELETE&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;log&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;/logging/logs/{logging-resource-id}&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;PUT&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;loggable-resource&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;/logging/loggable-resources&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;GET&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;This REST API will only be accessible to &lt;strong&gt;admin_only&lt;/strong&gt; which is controlled by
policy.json.&lt;/p&gt;
&lt;p&gt;The volume of log highly depends on user traffic. It affects performance and
it is a potential security impact (a kind of DoS).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="operators-cli-impact"&gt;
&lt;h3&gt;Operators CLI Impact&lt;/h3&gt;
&lt;p&gt;Additional methods will be added to neutron OSC plugin to create, update,
delete,
list and get logging resource.&lt;/p&gt;
&lt;p&gt;For logging resource:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;
            &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;disable&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ACCEPT&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;DROP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ALL&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt; &lt;span class="o"&gt;|--&lt;/span&gt;&lt;span class="n"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Check supported logging capabilities:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;loggable&lt;/span&gt; &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Currently, logged data will be stored into files. So this may increase a little
bit performance overhead.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;Support both IPv4 and IPv6.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Configure to enable logging API service.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Changing the security-group API by adding ‘logging’ attribute to Security
Group API resource. It would break the compatibility with the EC2 API &lt;a class="footnote-reference brackets" href="#id14" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.
And we should avoid changing FWaaS API by extend it &lt;a class="footnote-reference brackets" href="#id15" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Hence, the logging API allow enable logging is necessary.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;y-furukawa-2&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;hoangcx,
annp,
tuhv&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Finalize a way to log data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;REST API + API tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Database model &amp;amp; database migrations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Oslo versioned object database implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Iptables based reference implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OSC support&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit Test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functional test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fullstack test&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None, since this is covered by the in-tree API tests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Regression test with the logging feature enabled.
Test if the logging feature actually works.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;The new API interface will be tested via API tests, to ensure all the
operations work as expected.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add some usages into the networking guide for operator.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write how to enable the logging API plugin.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id9" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/426946/"&gt;https://review.openstack.org/#/c/426946/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://eavesdrop.openstack.org/meetings/neutron_drivers/2017/neutron_drivers.2017-04-27-22.03.log.html"&gt;http://eavesdrop.openstack.org/meetings/neutron_drivers/2017/neutron_drivers.2017-04-27-22.03.log.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id11" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/395504/"&gt;https://review.openstack.org/#/c/395504/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/445827/"&gt;https://review.openstack.org/#/c/445827/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id13" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/396104/"&gt;https://review.openstack.org/#/c/396104/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id14" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/132134"&gt;https://review.openstack.org/132134&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id15" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/132133"&gt;https://review.openstack.org/132133&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id16" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://openvswitch.org/support/dist-docs/ovs-vswitchd.conf.db.5.html"&gt;http://openvswitch.org/support/dist-docs/ovs-vswitchd.conf.db.5.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Thu, 01 Mar 2018 00:00:00 </pubDate></item><item><title>VPN Services Support QoS</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/rocky/vpn-services-support-qos.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1727578"&gt;https://bugs.launchpad.net/neutron/+bug/1727578&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, there is no way to set VPN services’ bandwidth. This specification
proposed a way to set the VPN services’ bandwidth limit.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently, Neutron VPNaaS provides site to site VPN services, but its bandwidth
consumption is not regulated, as the VPN tunnel will cost the bandwidth from
the outside public bandwidth provided by the ISP or other organizations. That
means it is not free. The OpenStack provider or users should pay for the
limited bandwidth. So it is necessary for saving the resources.&lt;/p&gt;
&lt;p&gt;Currently, physical device configurations outside OpenStack environment cannot
be modified by OpenStack, but we can shape the outgoing traffic. VPN services
provide the security guarantee, but it shouldn’t abuse the bandwidth of
underlay network that it will affects other traffic.&lt;/p&gt;
&lt;section id="use-case"&gt;
&lt;h3&gt;Use Case&lt;/h3&gt;
&lt;p&gt;Consider that an OpenStack public cloud has been deployed in a real data
center. A cloud enterprise user has a requirement in which one of the
applications should connect to its private network 20.0.0.0/24, but for other
traffic flows, still use the original network functionality provided by
OpenStack. The network topology diagram is shown below:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                                                                                                         &lt;span class="o"&gt;+&lt;/span&gt;
                       &lt;span class="o"&gt;+--------------------+&lt;/span&gt;   &lt;span class="o"&gt;+&lt;/span&gt;                                                        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;DataCenter&lt;/span&gt;
                       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;VM1&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                                                        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;external&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt;
                       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;nic&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.11&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;+-------------------------------+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;+----+&lt;/span&gt;
                       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="n"&gt;via&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.1&lt;/span&gt;&lt;span class="o"&gt;+---+&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Default&lt;/span&gt; &lt;span class="n"&gt;Router&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
                       &lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+-----------------+&lt;/span&gt;&lt;span class="n"&gt;Interface&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.1&lt;/span&gt;            &lt;span class="o"&gt;+------+&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
                       &lt;span class="o"&gt;+--------------------+&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;gw&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;172.24.4.11&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="n"&gt;OpenStack&lt;/span&gt;                                       &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;20.0.0.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="n"&gt;via&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.5&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="n"&gt;private&lt;/span&gt;                                &lt;span class="o"&gt;.&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;                               &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="n"&gt;network&lt;/span&gt;                                &lt;span class="o"&gt;.&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;+-------------------------------+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
                                                &lt;span class="o"&gt;|&lt;/span&gt;                                                        &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="n"&gt;subnet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;                             &lt;span class="o"&gt;|&lt;/span&gt;                                                        &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
                       &lt;span class="o"&gt;+--------------------+&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                                                        &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
                       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;VM2&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                                                        &lt;span class="o"&gt;+--------+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Internet&lt;/span&gt;
                       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;nic&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.12&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                                                        &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
                       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="n"&gt;via&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.1&lt;/span&gt;&lt;span class="o"&gt;+---+&lt;/span&gt;                                                        &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
                       &lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                                                        &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
                       &lt;span class="o"&gt;+--------------------+&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                                                        &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
                                                &lt;span class="o"&gt;|&lt;/span&gt;                                                        &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
                                       &lt;span class="o"&gt;.&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;+--------------------------------+&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+-------------------------------+&lt;/span&gt;
                                       &lt;span class="o"&gt;.&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;VPN&lt;/span&gt; &lt;span class="n"&gt;Router&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Vendor&lt;/span&gt; &lt;span class="n"&gt;GW&lt;/span&gt; &lt;span class="n"&gt;Router&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;
                                                &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Interface&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.5&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;peer&lt;/span&gt; &lt;span class="n"&gt;vpn&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
                                                &lt;span class="o"&gt;+-----------------+&lt;/span&gt;&lt;span class="n"&gt;gw&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;172.24.4.12&lt;/span&gt;                 &lt;span class="o"&gt;+-----+&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;+-------+&lt;/span&gt;&lt;span class="n"&gt;hold&lt;/span&gt; &lt;span class="n"&gt;private&lt;/span&gt; &lt;span class="n"&gt;subnet&lt;/span&gt; &lt;span class="mf"&gt;20.0.0.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
                       &lt;span class="o"&gt;+--------------------+&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;VPN&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                               &lt;span class="o"&gt;|&lt;/span&gt;
                       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;VMX&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;                                &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                               &lt;span class="o"&gt;|&lt;/span&gt;
                       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;nic&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.13&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;+--------------------------------+&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;+----+&lt;/span&gt;       &lt;span class="o"&gt;+-------------------------------+&lt;/span&gt;
                       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="n"&gt;via&lt;/span&gt; &lt;span class="mf"&gt;10.0.0.1&lt;/span&gt;&lt;span class="o"&gt;+---+&lt;/span&gt;                                                        &lt;span class="o"&gt;|&lt;/span&gt;
                       &lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                                                        &lt;span class="o"&gt;|&lt;/span&gt;
                       &lt;span class="o"&gt;+--------------------+&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                                                        &lt;span class="o"&gt;|&lt;/span&gt;
                                                &lt;span class="o"&gt;|&lt;/span&gt;                                                        &lt;span class="o"&gt;|&lt;/span&gt;
                                                &lt;span class="o"&gt;+&lt;/span&gt;                                                        &lt;span class="o"&gt;+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As this diagram shows, the enterprise user owned many VMs in the private
network and the allocated IPs are from the private subnet 10.0.0.0/24. There
are two routers connected, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Default&lt;/span&gt; &lt;span class="pre"&gt;Router&lt;/span&gt;&lt;/code&gt; is used for the normal network
functions, such as NAT, Floating IP, Routing. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VPN&lt;/span&gt; &lt;span class="pre"&gt;Router&lt;/span&gt;&lt;/code&gt; is mainly used for
VPN traffic process, also contains NAT and route for other traffic. Both of the
routers are attached to the external network which is the physical underlay
network in the real data center. The VPN Router in OpenStack and Vendor GW
Router in other site maintain a VPN peer relationship across the Internet.&lt;/p&gt;
&lt;p&gt;There are two scenarios towards the VM outgoing traffic:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;VMs in the OpenStack private network access the normal websites, first send
the network packets to its gateway which is located on the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Default&lt;/span&gt; &lt;span class="pre"&gt;Router&lt;/span&gt;&lt;/code&gt;. Then send to the Internet by the data center devices.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VMs in the OpenStack private network access the other site private network
20.0.0.0/24, still first send the network packets to its gateway 10.0.0.1,
then check the route tables, the nexthop of 20.0.0.0/24 is 10.0.0.5 which
is located on &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VPN&lt;/span&gt; &lt;span class="pre"&gt;Router&lt;/span&gt;&lt;/code&gt;. The network traffic will be sent based on the
existing VPN tunnel to Vendor private site.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Like the diagram shows, the QoS Policy should be set on the qg-XX port of the
VPN router for limiting the outgoing VPN traffic.&lt;/p&gt;
&lt;p&gt;This spec focuses on the QoS of VPN outgoing traffic, so for neutron-vpnaas,
this spec will focus on the Router related with VPN services. And for the
general use cases which is that VPN service usually setup across the Internet
in tunnel mode, we will only introduce the QoS support on tunnel type VPN
services.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;We propose the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VPN&lt;/span&gt; &lt;span class="pre"&gt;Service&lt;/span&gt;&lt;/code&gt; resource accepts the Neutron QoS Policy. Once
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ipsec&lt;/span&gt; &lt;span class="pre"&gt;site&lt;/span&gt; &lt;span class="pre"&gt;connection&lt;/span&gt;&lt;/code&gt; is created, the QoS Policy will be applied on the
VPN router’s qg-XX port, as the ESP encapsulation will use the qg-XX port’s IP
to access other sites.&lt;/p&gt;
&lt;p&gt;So there are three parts that require to work:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;DB related changes, including new table &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qos_vpnservice_policy_bindings&lt;/span&gt;&lt;/code&gt;
addition and data model change.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API changes, including extend the API to accept the Neutron QoS Policy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Introduce a new l3 agent extension to extend the ability to process the QoS
policy installation on the router.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Accept the QoS parameters and implement the QoS function on our own.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apply QoS Policy on the Router interface directly, but this would affect the
west-east traffic.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;In this spec, the QoS data model and function will be provided by Neutron, so
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vpnservices&lt;/span&gt;&lt;/code&gt; table need to maintain the relationship with Neutron QoS
Policy.&lt;/p&gt;
&lt;p&gt;The following new table is added as part of the VPN QoS feature:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;CREATE TABLE `qos_vpnservice_policy_bindings` (
  `vpn_service_id` varchar(36) NOT NULL,
  `qos_policy_id` varchar(36) NOT NULL,
  UNIQUE KEY `vpn_service_id` (`vpn_service_id`),
  KEY `qos_policy_id` (`qos_policy_id`),
  CONSTRAINT `qos_vpn_service_policy_bindings_ibfk_1` FOREIGN KEY (
  `qos_policy_id`) REFERENCES `qos_policies` (`id`) ON DELETE CASCADE,
  CONSTRAINT `qos_vpn_service_policy_bindings_ibfk_2` FOREIGN KEY (
  `vpn_service_id`) REFERENCES `vpnservices` (`id`) ON DELETE CASCADE
);
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Proposed attribute:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;EXTEND_FIELDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'qos_policy_id'&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                     &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Some samples in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VPN&lt;/span&gt; &lt;span class="pre"&gt;service&lt;/span&gt;&lt;/code&gt; create/update. Users are allowed to pass
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;qos_policy_id&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Create/Update &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VPN&lt;/span&gt; &lt;span class="pre"&gt;service&lt;/span&gt;&lt;/code&gt; Request:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;vpn&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;vpnservices&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"vpnservice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"subnet_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"qos_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"a36c20d0-18e9-42ce-88fd-82a35977ee8c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"router_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"66e3b16c-8ce5-40fb-bb49-ab6d8dc3f2aa"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"myservice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"admin_state_up"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"vpnservice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"router_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"66e3b16c-8ce5-40fb-bb49-ab6d8dc3f2aa"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"PENDING_CREATE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"myservice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"external_v6_ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001:db8::1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"admin_state_up"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"subnet_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10039663455a446d8ba2cbb058b0f578"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10039663455a446d8ba2cbb058b0f578"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"external_v4_ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"172.32.1.11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5c561d9d-eaea-45f6-ae3e-08d1a7080828"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"qos_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"a36c20d0-18e9-42ce-88fd-82a35977ee8c"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;vpn&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;vpnservices&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;service_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"vpnservice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"NEW VPN SERVICE NAME"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Updated description"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"qos_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"a36c20d0-18e9-42ce-88fd-82a35977ee8c"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"vpnservice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"router_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"881b7b30-4efb-407e-a162-5630a7af3595"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"NEW VPN SERVICE NAME"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"admin_state_up"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"subnet_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"26de9cd6cae94c8cb9f79d660d628e1f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"26de9cd6cae94c8cb9f79d660d628e1f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"41bfef97-af4e-4f6b-a5d3-4678859d2485"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Updated description"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"qos_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"a36c20d0-18e9-42ce-88fd-82a35977ee8c"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="qos-policy-application-details"&gt;
&lt;h3&gt;QoS Policy Application Details&lt;/h3&gt;
&lt;p&gt;The reason for introducing this, for example, we change the use case below, we
deploy the vpn service on the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Default&lt;/span&gt; &lt;span class="pre"&gt;Router&lt;/span&gt;&lt;/code&gt;, delete the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VPN&lt;/span&gt; &lt;span class="pre"&gt;Router&lt;/span&gt;&lt;/code&gt;.
That means the general traffic and VPN traffic will pass through the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Default&lt;/span&gt; &lt;span class="pre"&gt;Router&lt;/span&gt;&lt;/code&gt;, then we apply the Neutron QoS policy on the qg-XX port of
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Default&lt;/span&gt; &lt;span class="pre"&gt;Router&lt;/span&gt;&lt;/code&gt;, it will limit all the bandwidth, so the VPN’s bandwidth
may have a lower performance, or we can say it is not consistent with
expectations.&lt;/p&gt;
&lt;p&gt;Currently, Neutron provides the QoS function but not for some interest streams.
Here we will focus on the VPN traffic. For this function, we will combine
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;iptables&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tc&lt;/span&gt;&lt;/code&gt; together. The reason for choosing them is that,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;iptables&lt;/span&gt;&lt;/code&gt; could mark the VPN interest stream by the ipsec VPN transform
protocols(such as esp, ah-esp protocols), the interface that the packets
will go out and the local encapsulated IP if running in tunnel mode. Also we
need to shape the vpn traffic before send out to the underlay network, so some
new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;iptables&lt;/span&gt;&lt;/code&gt; rules will be installed on mangle table in the router’s
namespace. Also the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;fwmark&lt;/span&gt;&lt;/code&gt; is eaiser to extend, such as ipchains.&lt;/p&gt;
&lt;p&gt;And we will introduce a new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tc&lt;/span&gt;&lt;/code&gt; wrapper which will use &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;htb&lt;/span&gt;&lt;/code&gt; and it will
provides classification algorithm. Then developers can easily implement other
complex traffic control. That means we will extend the current tc_lib in
Neutron repo. And &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vpn_qos&lt;/span&gt;&lt;/code&gt; will based on this.&lt;/p&gt;
&lt;p&gt;Just like above description, a new L3 agent extension will be introduced like
fip_qos done. We suggest to name it &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vip_qos&lt;/span&gt;&lt;/code&gt;, it will install the
appropriate &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;iptables&lt;/span&gt;&lt;/code&gt; rules in the router’s namespace which binds with
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VPN&lt;/span&gt; &lt;span class="pre"&gt;service&lt;/span&gt;&lt;/code&gt;. Then users or managers could use the QoS function to the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Default&lt;/span&gt; &lt;span class="pre"&gt;Router&lt;/span&gt;&lt;/code&gt; and not affect other network streams.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;No expected change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Users will be able to specify qos_policy during create/update &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;VPN&lt;/span&gt; &lt;span class="pre"&gt;service&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;It will save the bandwidth of the underlay network in data center.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developer may use the new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tc&lt;/span&gt;&lt;/code&gt; wrapper to do other things, as it is powerful
to support other stream control functionality.
But there may be a conflict with openstack/neutron-classifier, as it provides
defining the traffic. So we may reconsider that if possible.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;zhaobo&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add the DB model and extend the table column.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend VPN API to accept QoS policy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend new tc wrapper which support classification algorithm based on
traffic classifier feature.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend new L3 agent extension &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vip_qos&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add API validation code to validate access/existence of the qos_policy which
created in Neutron.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add UTs to Neutron-vpnaas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add API tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update CLI to accept QoS fields.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation work.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests, functional tests, API tests and scenario tests are necessary.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The Neutron API reference will need to be updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Thu, 04 Jan 2018 00:00:00 </pubDate></item><item><title>Neutron Common Classification Framework</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/backlog/pike/common-classification-framework.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/common-classification-framework"&gt;https://blueprints.launchpad.net/neutron/+spec/common-classification-framework&lt;/a&gt;
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/CommonClassificationFramework"&gt;https://wiki.openstack.org/wiki/Neutron/CommonClassificationFramework&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Different Neutron projects, services, features and related projects have
different traffic classifiers or classification APIs.
They differ on both syntax and semantics. A few examples are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Security group rules &lt;a class="footnote-reference brackets" href="#id24" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;openstack/neutron-fwaas &lt;a class="footnote-reference brackets" href="#id25" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;openstack/networking-sfc (Flow Classifier) &lt;a class="footnote-reference brackets" href="#id26" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;openstack/neutron-classifier &lt;a class="footnote-reference brackets" href="#id20" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;openstack/networking-bgpvpn &lt;a class="footnote-reference brackets" href="#id30" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;12&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;openstack/tap-as-a-service &lt;a class="footnote-reference brackets" href="#id31" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;13&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron QoS &lt;a class="footnote-reference brackets" href="#id28" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;10&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Furthermore, there are other projects with classification APIs, such as
openstack/group-based-policy &lt;a class="footnote-reference brackets" href="#id27" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;9&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and it’s possible that more will want
to support classifications in their own APIs, further reinventing the wheel
and fragmenting the language used in the OpenStack ecosystem when it comes
to defining traffic classifications.&lt;/p&gt;
&lt;p&gt;This spec introduces the Neutron Common Classification Framework (CCF),
a culmination of previous efforts: Common Classifier &lt;a class="footnote-reference brackets" href="#id19" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;,
openstack/neutron-classifier &lt;a class="footnote-reference brackets" href="#id20" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and
Common Flow Classifier &lt;a class="footnote-reference brackets" href="#id29" id="id11" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;11&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The previous spec for this RFE is archived at &lt;a class="footnote-reference brackets" href="#id19" id="id12" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Terminology:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Common Classification Framework (CCF)&lt;/strong&gt;: the name of this project, which
includes the base models and resources introduced below, the API, logic and
versioned objects to allow Consuming Services to consume from the framework.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Classification&lt;/strong&gt;: the Neutron resource being introduced for the purpose of
defining an atomic traffic classification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Classification Group (CG)&lt;/strong&gt;: the Neutron resource being introduced for the
purpose of grouping Classifications, or other Classification Groups,
together, specifying a common relation across them. This is the resource
that ultimately will be consumed by a Consuming Service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Classification Type (CT)&lt;/strong&gt;: every Classification has a type, defining the
format, supported fields and syntax validators of that classification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Classifications API&lt;/strong&gt;: the User-facing REST API that is provided by the
Common Classification Framework to instantiate the resources above.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consuming Service (CS)&lt;/strong&gt;: Neutron itself or a Neutron project, service,
extension or feature that is capable of consuming Classification Groups
(acquiring them as resources), examples of potential Consuming Services are
the ones listed in Problem Description.
These services do not talk directly to the Classifications API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;User&lt;/strong&gt;: the end-user, human or machine, tenant or admin, typically cloud
consumer, calling into the Classifications API and any Consuming Services’
REST APIs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This spec defines the new kinds of resources to be introduced, an initial set
of Classification Types and their models, and the Classifications API in order
to define such traffic classifications, which the User will call.&lt;/p&gt;
&lt;p&gt;The dedicated Classifications API provides a way to define and create
Classifications and CGs, storing them like any other resource. CSs are
then able to fetch those traffic classification definitions as
oslo.versionedobjects (OVO) and feed them to their respective internal network
classifiers (i.e. to the mechanism capable of matching on traffic, such as
Open vSwitch via the respective ML2 mechanism driver, or
iptables - it really depends on what service, and its configuration, is
consuming the Classification Groups). What Consuming Services do with the
resources consumed is entirely out of scope from the CCF.&lt;/p&gt;
&lt;p&gt;Updating Classification or CG resources is disallowed in the API, except for
changes not related to the traffic classification semantics, such as name and
description. With this, having to deal with the complexities of advertising
resource changes to CSs is also avoided which, at least for a first version
of the CCF, is beneficial as it keeps the project simpler.&lt;/p&gt;
&lt;p&gt;Consuming Services are not required to keep a local
database copy of the consumed classifications, beyond mapping CG UUIDs with
Consuming Services’ own resources. Consequently, the Common
Classification Framework should prevent Classifications from being deleted if
they are in use by at least 1 resource of any Consuming Service.&lt;/p&gt;
&lt;p&gt;Summary of changes necessary to create the Common Classification Framework:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Creation of a Neutron extension to expose the new, first version of the
Classifications API, as additional modifications will require new extensions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creation of models for the different supported protocols’ types/definitions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creation of a Neutron service plugin and DB layer to validate
the Classifications defined by the API according to the types defined and
respective supported models, and store them in the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adoption of OVO so that every Classification defined becomes a versioned and
serializable object, which will be transferred from the Common Classification
Framework to Consuming Services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create CLI using OSC so Users can define their own Classifications with ease.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Though out of scope, this is a summary of changes needed in Consuming Services:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a dependency on the CCF’s own extension.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add (or reuse) fields to/in certain API resources with the intent of
receiving Classification Group UUIDs (e.g. networking-sfc port-chain’s
flow_classifiers field could expect a common Classification Group UUID
instead of local Flow Classifier UUIDs).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Evaluate the Classifications provided to ascertain whether they are
compatible with the specific extension’s classifier (mechanism).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add logic to fetch the CGs provided by UUID, making
use of OVO in the process, potentially via neutron-lib (xgerman).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Translate the classifications’ definitions to the specific classifier’s
mechanism or language (e.g. create Open vSwitch flows matching on traffic).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Typically Consuming Services will already have their own CLI, so changes
must be made consistently with the changes made to their own APIs and/or
classification-fetching code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The diagram at &lt;a class="footnote-reference brackets" href="#id23" id="id13" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; shows the relationship between Users, the Common
Common Classification Framework and the Consuming Services.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;Grouping traffic classifications by individual types, called Classification
Types, will allow future types to be added and agreed in the future, while
keeping the remaining ones intact. Existing types can of course be updated,
thanks to versioning. Thus, this approach follows a modular, rather than
a monolithic way of defining classifications. Looking at the existing
neutron-classifier project &lt;a class="footnote-reference brackets" href="#id20" id="id14" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, which was decided as the repo to keep
the Common Classifier &lt;a class="footnote-reference brackets" href="#id21" id="id15" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; (during the Tokyo Summit 2015), there are
hints of an architecture like the one proposed here, as can be seen
in &lt;a class="footnote-reference brackets" href="#id22" id="id16" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. As such, this framework is partially based on the
neutron-classifier with the major difference that it presents a REST API for
Users to define classifications.&lt;/p&gt;
&lt;p&gt;Before delving into further detail in regards to the data model, API and how
classifications can be used by interested Neutron subprojects, a few points
need to be clarified:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Classification Types can be introduced or extended (with new fields e.g.) in
every release of the CCF. API extensions will be added to reflect these
additions in the REST API and maintain backwards compatibility.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;1 Classification is of a single type, e.g. either Ethernet, IP, HTTP,
or another supported at the time of a specific CCF release. The definition,
i.e. fields to match on, depends on the type specified.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To clarify, Classification Types define the set of possible fields and values
for a Classification (essentially, an instance of that Classification Type).
Classification Types are defined in code, where Classifications are created
via the REST API as instances of those types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Not all supported fields need to be defined - only the ones
required by the Consuming Service - which it should validate on consumption.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are also Classification Groups, which allow Classifications or other
Classification Groups to be grouped together using boolean operators. CGs
are the resources that will end up being consumed by Consuming Services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The CCF has to be able to check if a Classification Group
is currently being used, and prevent it from getting deleted if so.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the Consuming Service’s point of view, Classifications can only be read,
not created or deleted. They need to have been previously
created using the User-facing Classifications API.
Figure &lt;a class="footnote-reference brackets" href="#id23" id="id17" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; attempts to illustrate this.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The initial model of the CCF will includes the following Classification Types:
Ethernet, IPv4, IPv6, TCP and UDP, which when combined are sufficient
to provide any 5-tuple classification.&lt;/p&gt;
&lt;p&gt;The following table presents the attributes of a Classification Group
(asterisk on RW means that the attribute is non-updatable):&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access
CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO,
all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;from auth
token&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Project ID&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Name of Classification Group&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human-readable description&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;shared&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;False&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;boolean&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Shared with other projects&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;operator&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(values)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW*,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;“and”&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;[“and”,&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;“or”]&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Boolean connective: AND/OR&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;classification_groups&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW*,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[]&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;List of Classification
Groups included&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;classifications&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW*
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[]&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;List of Classifications
included&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Consuming Services will consume Classification Groups, and not atomic
Classifications (that would create more difficulties in terms of the
relationships between CCF and CSs databases), any Classification needs to
be grouped in a Classification Group to be consumed individually. As such,
the “operator” field is to be ignored for Classification Groups that only
contain 1 Classification inside.&lt;/p&gt;
&lt;p&gt;The following table presents the attributes of Classifications
of any of the types stated in this spec
(asterisk on RW means that the attribute is non-updatable):&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO,
all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;from auth
token&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Project ID&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Name of Classification&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human-readable description&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW*,
project&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;from enum
of types&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;The type of the
Classification&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;negated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW*,
project&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;False&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;boolean&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Whether to negate
classification (boolean NOT)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;definition&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="5"&gt;&lt;p&gt;type-specific attributes will go here,
given their volume I won’t detail them unless requested.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Classification Groups and Classifications of every type will be stored as the
following tables and relationships (with table name prefix &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ccf_&lt;/span&gt;&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                          &lt;span class="o"&gt;+---------------------+&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_groups&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;+---------------------+&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;                   &lt;span class="o"&gt;|*&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;cg_id&lt;/span&gt;                &lt;span class="o"&gt;+--------+&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;               &lt;span class="o"&gt;+--------+&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;operator&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
                          &lt;span class="o"&gt;+---------------------+&lt;/span&gt;
                                      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
                                      &lt;span class="o"&gt;|&lt;/span&gt;
                                      &lt;span class="o"&gt;|*&lt;/span&gt;
                      &lt;span class="o"&gt;+------------------------------+&lt;/span&gt;
                      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_groups_mapping&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                      &lt;span class="o"&gt;+------------------------------+&lt;/span&gt;
                      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;cg_id&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;
                      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_id&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
                      &lt;span class="o"&gt;+------------------------------+&lt;/span&gt;
                                      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;+--------------------+&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;+--------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ipv4_classifications&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ipv6_classifications&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------------+&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;+--------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_id&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_id&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ihl&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;traffic_class&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;diffserv&lt;/span&gt;            &lt;span class="o"&gt;+--------+&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+--------+&lt;/span&gt;&lt;span class="n"&gt;traffic_class_mask&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;diffserv_mask&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;next_header&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;hops&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;flags_mask&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;src_addr&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ttl&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dst_addr&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;protocol&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+---------------------+&lt;/span&gt;     &lt;span class="o"&gt;+--------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;src_addr&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classifications&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dst_addr&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+---------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;options_mask&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------------+&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
                           &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
                           &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+-------------------+&lt;/span&gt;
                           &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;tcp_classifications&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
                           &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;negated&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+-------------------+&lt;/span&gt;
                           &lt;span class="o"&gt;+---------------------+&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_id&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-------------------+&lt;/span&gt;        &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;src_port&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;udp_classifications&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dst_port&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-------------------+&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;flags&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_id&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;flags_mask&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;src_port&lt;/span&gt;           &lt;span class="o"&gt;+---------+&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+--------+&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dst_port&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;data_offset&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;+------------------------+&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;option_kind&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;window_size&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ethernet_classifications&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+-------------------+&lt;/span&gt;
&lt;span class="o"&gt;+-------------------+&lt;/span&gt;     &lt;span class="o"&gt;+------------------------+&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_id&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;preamble&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;src_addr&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dst_addr&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ethertype&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;+------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Some of the fields of the Classification Types presented above in the database
schema, such as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;length&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;src_addr&lt;/span&gt;&lt;/code&gt;, and others, will allow ranges or
lists to be input, through the use of commas or hyphens, for example.&lt;/p&gt;
&lt;p&gt;Masking fields allow the user to specify which individual bits of the
respective main field should be looked up during classification.&lt;/p&gt;
&lt;p&gt;Besides the Classification Types presented above, the following types are also
expected to be part of the first release of the CCF:
- Neutron (destination/source port, subnets, networks, at least)
- ICMP
- ICMPv6
- SCTP
- ARP
- VLAN
- GRE
- VXLAN
- Geneve
- MPLS
- NSH&lt;/p&gt;
&lt;p&gt;Classification Types are used to select the appropriate model of the
Classification and consequently what table it will be stored in.&lt;/p&gt;
&lt;p&gt;Classification Groups get stored in a single table and can point to other
Classification Groups, to allow mixing boolean operators.&lt;/p&gt;
&lt;p&gt;There are two important fields meant for boolean logic:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;operator&lt;/span&gt;&lt;/code&gt; in Classification Group: specifies the boolean operator used
to connect all the child Classifications and Classification Groups of that
group. This can be either AND or OR.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;negated&lt;/span&gt;&lt;/code&gt; per Classification “usage”: specifies whether to negate the
definition of the Classification, when mapped to a Classification Group,
essentially a boolean NOT. This can be True or False. Please note that
Classification Groups cannot be negated using this model.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-apis"&gt;
&lt;h3&gt;REST APIs&lt;/h3&gt;
&lt;p&gt;A new API extension is being introduced. The base URL
for the Classifications API is /v2.0/.&lt;/p&gt;
&lt;p&gt;The following table summarizes available URIs:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+----------------------+------------------------------------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Resource&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;URI&lt;/span&gt;                                 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+======================+====================================+=======+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_types&lt;/span&gt;  &lt;span class="o"&gt;|/&lt;/span&gt;&lt;span class="n"&gt;classification_types&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------------+------------------------------------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_group&lt;/span&gt;  &lt;span class="o"&gt;|/&lt;/span&gt;&lt;span class="n"&gt;classification_groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------------+------------------------------------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_groups&lt;/span&gt; &lt;span class="o"&gt;|/&lt;/span&gt;&lt;span class="n"&gt;classification_groups&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------------+------------------------------------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_group&lt;/span&gt;  &lt;span class="o"&gt;|/&lt;/span&gt;&lt;span class="n"&gt;classification_groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------------+------------------------------------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_group&lt;/span&gt;  &lt;span class="o"&gt;|/&lt;/span&gt;&lt;span class="n"&gt;classification_groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;PUT&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------------+------------------------------------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification_group&lt;/span&gt;  &lt;span class="o"&gt;|/&lt;/span&gt;&lt;span class="n"&gt;classification_groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------------+------------------------------------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification&lt;/span&gt;        &lt;span class="o"&gt;|/&lt;/span&gt;&lt;span class="n"&gt;classifications&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------------+------------------------------------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classifications&lt;/span&gt;       &lt;span class="o"&gt;|/&lt;/span&gt;&lt;span class="n"&gt;classifications&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------------+------------------------------------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification&lt;/span&gt;        &lt;span class="o"&gt;|/&lt;/span&gt;&lt;span class="n"&gt;classifications&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------------+------------------------------------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification&lt;/span&gt;        &lt;span class="o"&gt;|/&lt;/span&gt;&lt;span class="n"&gt;classifications&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;PUT&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------------+------------------------------------+-------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;classification&lt;/span&gt;        &lt;span class="o"&gt;|/&lt;/span&gt;&lt;span class="n"&gt;classifications&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------------+------------------------------------+-------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The CCF should provide a way to mark a Classification Group as being in use
(or increase the usage count) and a way to check for that and abort
certain operations if the group is in use.&lt;/p&gt;
&lt;p&gt;The CCF does not provide any mechanism to synchronize Classification Groups
to Consuming Services.&lt;/p&gt;
&lt;p&gt;Examples for a Classification Group with two Classifications inside.&lt;/p&gt;
&lt;p&gt;To list available Classification Types:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;classification_types&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"classification_types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ethernet"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ipv4"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ipv6"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"udp"&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To create a Classification of type TCP:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;classifications&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"classification"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"not_tcp_syns"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"negated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"definition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"control_flags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"0x2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"control_flags_mask: "&lt;/span&gt;&lt;span class="mh"&gt;0x2&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"classification"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"3dcc561a-1bb8-11e7-b615-23717626a4e5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"0a36035e-1bb9-11e7-b8ef-e782361fd276"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"not_tcp_syns"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"negated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"definition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"src_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"dst_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"control_flags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"0x2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"control_flags_mask: "&lt;/span&gt;&lt;span class="mh"&gt;0x2&lt;/span&gt;&lt;span class="s2"&gt;",&lt;/span&gt;
            &lt;span class="s2"&gt;"ecn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"ecn_mask"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"min_window"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"max_window"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"min_data_offset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"max_data_offset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"option_kind"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To create a Classification of type Ethernet:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;classifications&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"classification"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ipv4_over_eth"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ethernet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"definition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"ethertype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"0x800"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"classification"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"021c1ad2-1bb9-11e7-907d-937a75c8a5db"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"0a36035e-1bb9-11e7-b8ef-e782361fd276"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ipv4_over_eth"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ethernet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"negated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"definition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"negated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"preamble"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"src_addr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"dst_addr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"ethertype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"0x800"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To create a Classification Group:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;classification_groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"classification_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"no_syns_on_ipv4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Any IPv4 traffic carried over Ethernet except TCP SYNs."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"operator"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"and"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"classifications"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"3dcc561a-1bb8-11e7-b615-23717626a4e5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"021c1ad2-1bb9-11e7-907d-937a75c8a5db"&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"classification_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"387299fa-250d-11e7-8620-b38d21865984"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"0a36035e-1bb9-11e7-b8ef-e782361fd276"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"no_syns_on_ipv4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Any IPv4 traffic carried over Ethernet except TCP SYNs."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"operator"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"and"&lt;/span&gt;
        &lt;span class="s2"&gt;"classifications"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"3dcc561a-1bb8-11e7-b615-23717626a4e5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"021c1ad2-1bb9-11e7-907d-937a75c8a5db"&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"classification_groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;List Classification Groups:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;classification_groups&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"classification_groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"387299fa-250d-11e7-8620-b38d21865984"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"0a36035e-1bb9-11e7-b8ef-e782361fd276"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"no_syns_on_ipv4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Any IPv4 traffic carried over Ethernet except TCP SYNs."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"operator"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"and"&lt;/span&gt;
            &lt;span class="s2"&gt;"classifications"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s2"&gt;"3dcc561a-1bb8-11e7-b615-23717626a4e5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"021c1ad2-1bb9-11e7-907d-937a75c8a5db"&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s2"&gt;"classification_groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;Services that intend to consume Classifications only have to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Modify their existing REST APIs slightly in order to allow for
Classification Group UUIDs to be passed, if they don’t already
have an endpoint for such (e.g. networking-sfc doesn’t require
port-chain API resource changes).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement the underlying fetching of Classification definitions,
with support for OVO.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;The OpenStack Client will be extended to support the Classifications API.&lt;/p&gt;
&lt;p&gt;Possible CLI syntax of a hypothetical scenario with Neutron QoS as the
Consuming Service and the Classification Group presented above in the
example API calls, to illustrate the workflow:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ openstack network classification create --type=tcp --control_flags=0x2 --control_flags_mask=0x2 --negated tcp_syns
$ openstack network classification create --type=ethernet --ethertype=0x800 ipv4_over_eth
$ openstack network classification group create --description "Any IPv4 traffic carried over Ethernet except TCP SYNs." \
      --classification tcp_syns --classification ipv4_over_eth --operator and no_syns_on_ipv4
$ openstack network qos rule create --type bandwidth-limit --max-kbps 8000 --classification-group no_syns_on_ipv4 myqospolicy
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Possible alternatives to the data model and REST API presented are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron QoS -inspired model;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using oslo.versionedobjects serialized into JSON for the REST API,
to support the exact same resources specified in here.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;With regards to the initial model, it could as well include
Security Group Rule UUIDs, BGP VPN resource UUIDs, HTTP, and many more.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Work has started as an initial Proof of Concept, available at &lt;a class="footnote-reference brackets" href="#id32" id="id18" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;14&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.
After an initial merge on the neutron-classifier repository, work will
continue towards the goals outlined in this spec.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Igor Duarte Cardoso (&lt;a class="reference external" href="mailto:igor.duarte.cardoso%40intel.com"&gt;igor&lt;span&gt;.&lt;/span&gt;duarte&lt;span&gt;.&lt;/span&gt;cardoso&lt;span&gt;@&lt;/span&gt;intel&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;David Shaughnessy (&lt;a class="reference external" href="mailto:david.shaughnessy%40intel.com"&gt;david&lt;span&gt;.&lt;/span&gt;shaughnessy&lt;span&gt;@&lt;/span&gt;intel&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;We request the Neutron team to provide access to the neutron-classifier repo.&lt;/p&gt;
&lt;p&gt;Given the findings with the PoC code, there is no expectation that existing
code in neutron-classifier will be reused, so the repository is to be wiped
(but all the history will be kept).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Prototype/PoC (Pike-1) (David) - Finished.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finish spec (Pike) (Igor) - In Progress.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Acquire rights to merge on a repository (Pike) (Igor) - In Progress.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement first consumable version of this project (Pike to Queens) (David, Igor)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bring first time support to a Neutron service (TBD) (Queens to Rocky)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id19" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id9"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id12"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;Add common classifier resource (neutron-specs): &lt;a class="reference external" href="https://review.openstack.org/#/c/190463/"&gt;https://review.openstack.org/#/c/190463/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id20" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id4"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id10"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id14"&gt;3&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;The neutron-classifier project: &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron-classifier"&gt;http://git.openstack.org/cgit/openstack/neutron-classifier&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id21" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id15"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;The original and current RFE to bring a common classifier to Neutron: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1476527"&gt;https://bugs.launchpad.net/neutron/+bug/1476527&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id22" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id16"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;neutron-classifier inspiration: &lt;a class="reference external" href="https://github.com/openstack/neutron-classifier/blob/10b2eb3127f4809e52e3cf1627c34228bca80101/neutron_classifier/common/constants.py#L17"&gt;https://github.com/openstack/neutron-classifier/blob/10b2eb3127f4809e52e3cf1627c34228bca80101/neutron_classifier/common/constants.py#L17&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id23" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id13"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id17"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;Relationship between communicating entities: &lt;a class="reference external" href="http://i.imgur.com/9jttN11.png"&gt;http://i.imgur.com/9jttN11.png&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id24" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Security group rules: &lt;a class="reference external" href="http://developer.openstack.org/api-ref/networking/v2/?expanded=show-security-group-rule-detail"&gt;http://developer.openstack.org/api-ref/networking/v2/?expanded=show-security-group-rule-detail&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id25" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;FWaaS API spec: &lt;a class="reference external" href="http://specs.openstack.org/openstack/neutron-specs/specs/api/firewall_as_a_service__fwaas_.html"&gt;http://specs.openstack.org/openstack/neutron-specs/specs/api/firewall_as_a_service__fwaas_.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id26" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;networking-sfc API: &lt;a class="reference external" href="http://docs.openstack.org/developer/networking-sfc/api.html"&gt;http://docs.openstack.org/developer/networking-sfc/api.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id27" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;9&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Group-based Policy: &lt;a class="reference external" href="http://gbp.readthedocs.io/en/latest/usage.html"&gt;http://gbp.readthedocs.io/en/latest/usage.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id28" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;10&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Traffic classification in Neutron QoS: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1527671"&gt;https://bugs.launchpad.net/neutron/+bug/1527671&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id29" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id11"&gt;11&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Common Flow Classifier proposed model: &lt;a class="reference external" href="https://wiki.openstack.org/w/images/c/c8/neutron_common_classifier.png"&gt;https://wiki.openstack.org/w/images/c/c8/neutron_common_classifier.png&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id30" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;12&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;openstack/networking-bgpvpn API reference: &lt;a class="reference external" href="https://docs.openstack.org/developer/networking-bgpvpn/api.html#bgpvpn-resource"&gt;https://docs.openstack.org/developer/networking-bgpvpn/api.html#bgpvpn-resource&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id31" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;13&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;openstack/tap-as-a-service API reference: &lt;a class="reference external" href="https://github.com/openstack/tap-as-a-service/blob/master/API_REFERENCE.rst"&gt;https://github.com/openstack/tap-as-a-service/blob/master/API_REFERENCE.rst&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id32" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id18"&gt;14&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Latest CCF PoC: &lt;a class="reference external" href="https://review.openstack.org/#/c/445577/"&gt;https://review.openstack.org/#/c/445577/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;section id="related-information"&gt;
&lt;h3&gt;Related Information&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Data Model:
&lt;a class="reference external" href="http://i.imgur.com/MPuOAvv.png"&gt;http://i.imgur.com/MPuOAvv.png&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Tue, 19 Dec 2017 00:00:00 </pubDate></item><item><title>Neutron Resource Diagnostics</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/backlog/pike/diagnostics.html</link><description>

&lt;p&gt;RFE: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1507499"&gt;https://bugs.launchpad.net/neutron/+bug/1507499&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Cloud software is complex and problems are inevitable. Neutron is no exception
to this rule. To cope today we have helper scripts &lt;a class="footnote-reference brackets" href="#id9" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, blogs &lt;a class="footnote-reference brackets" href="#id10" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, diagnostic
tools &lt;a class="footnote-reference brackets" href="#id11" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, out-of-tree plugin utilities &lt;a class="footnote-reference brackets" href="#id12" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, etc. that could all benefit from
additional Neutron diagnostic data APIs. And while we certainly don’t want
Neutron to become a new diagnostic system, other projects &lt;a class="footnote-reference brackets" href="#id13" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; have
found value in exposing some level of diagnostic data for users (typically
operators) needing to reach under the hood.&lt;/p&gt;
&lt;p&gt;By the same token, Neutron offers a broad array of resources backed by a
heterogeneous set of technologies. As a result, standardizing a set of
concrete diagnostics across this diverse domain is no simple task.
Moreover, a Neutron resource may be realized through multiple components
(plugins, agents) spanning multiple nodes (hosts). Thus, any proposal
to collect resource diagnostic data must plan accordingly to support
multiple, potentially disparate, diagnostic participants.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This spec proposes to deliver a diagnostic framework consisting of the
following high level constructs:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Diagnostic checks that are effectively micro-plugins containing concrete
logic to carry out a diagnostic check for a given set of resource types
(&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ports&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;networks&lt;/span&gt;&lt;/code&gt;, etc.) as well as check specific metadata such
as the check’s name, description, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Diagnostic providers that are capable of discovering, managing and
executing diagnostic checks. These providers are the sources for diagnostics
and will allow neutron plugins and agents to plug-and-play with the
framework.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Diagnostics API extension that supports a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/diagnostics&lt;/span&gt;&lt;/code&gt; URI for existing
neutron resources and services the request by discovering and executing
checks on applicable providers and rolling up the responses.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each of the following constructs is discussed in greater detail in the following
sections.&lt;/p&gt;
&lt;section id="diagnostic-checks"&gt;
&lt;h3&gt;Diagnostic Checks&lt;/h3&gt;
&lt;p&gt;Diagnostic checks are effectively small plugins that provide the following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Check specific metadata including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A unique name for the check.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(optional) A description of the check’s diagnostics.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A boolean flag indicating if the check is required or not.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A set of resource types (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ports&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;networks&lt;/span&gt;&lt;/code&gt;, etc.) the check is
applicable to.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The actual diagnostic check logic. This logic will be invoked when collecting
diagnostics for a specific resource instance of a resource type that’s
supported by the check (as per the check’s metadata). Checks return a
well-formed response including a response code, (optional) text message, etc.
If a check supports multiple resource types, its implementation can key off
the resource type that’ll be passed in by the framework.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As part of this work a sample check will be provided for both a server and
agent side plugin that illustrates how to use the framework.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="diagnostic-providers"&gt;
&lt;h3&gt;Diagnostic Providers&lt;/h3&gt;
&lt;p&gt;Diagnostic providers are simply ‘sources’ for diagnostic checks and contain
the logic to discover, manage and execute checks. Services in a deployment
wishing to contribute diagnostics will therefore implement a diagnostic
provider. For this effort we’ll deliver a diagnostic provider binding
for both the neutron service as well as neutron based agents.&lt;/p&gt;
&lt;p&gt;Diagnostic providers have the following characteristics:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The means to discover and load known checks. More details in subsequent
sections.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An internal cache of loaded checks and public APIs to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Determine if the provider has a check for a given resource type or list
of resource types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List the resource types the provider has checks for.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Execute all checks applicable to a specified resource type and resource
instance, collect the well-formed results and return them.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The neutron server diagnostic provider binding delivered by this effort
will be implemented as a service plugin; consumers wishing to invoke it’s
APIs can get a reference to the plugin instance via neutron manager. In
addition, other plugins can act as a diagnostic provider by supporting
the extension and implementing the respective diagnostic methods required.
This approach will also work for agent-less plugins and mimics what’s typically
done today in such plugins when supporting extensions in their implementation.&lt;/p&gt;
&lt;p&gt;The neutron agent based diagnostic provider binding delivered by this
implementation will use the agent extension framework; plumbing the support
for all neutron based agents. However since the agent binding is remote to the
neutron API server it has the following notable differences:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;To indicate the resource types the agent diagnostic provider supports,
a set of (string) resource types is returned in the agent state report
and stored in the agent database. On the agent, this set is built by
collecting the supported resource types from the checks it manages. On the
server side, the agent’s supported resource list can be used by the API
extension controller logic to determine if the agent is applicable
to service specific diagnostic requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The public APIs to invoke checks on a specific resource type and resource
instance are remoteable so they can be called via RPC.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="diagnostic-providers-loading-checks"&gt;
&lt;h4&gt;Diagnostic Providers: Loading Checks&lt;/h4&gt;
&lt;p&gt;Diagnostic providers are responsible for loading checks upon start-up
(e.g. when service plugin starts or the agent starts). There are multiple
ways to support check plugins including:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Having each check as a stevedore entry point; then loading and managing them
via a driver manager.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Defining a specific check directory that only contains python modules where
each module is a check (plugin) and discovering + importing them from the
directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Statically defining the checks in the diagnostic provider binding code.
This is just as it sounds; statically have a list of checks in the code
rather than dynamically discovering + loading.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each approach above has it’s pros/cons. For the initial implementation we
suggest using the last approach of statically defining the checks in the code.
While this is not the most robust approach, it minimizes complexity and allows
us to get a tire-kicker more rapidly that we can then later iterate on once
we get some feedback from users.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="diagnostic-providers-data-model"&gt;
&lt;h4&gt;Diagnostic Providers: Data Model&lt;/h4&gt;
&lt;p&gt;As mentioned previously, neutron agent based diagnostic providers report
the resource types the checks they manage support. This is a list of
unique string resource types that is transported in a new key/value of
the agent state report. This list is stored in a new database table
in a new column called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;diagnostic_resource_types&lt;/span&gt;&lt;/code&gt; that maps to its
corresponding agent table entry.&lt;/p&gt;
&lt;p&gt;None (default) or an empty list signifies the agent does not provide
diagnostic data and thus will not be called to service a diagnostic
request. Neutron (OVO) objects will be updated as necessary.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="api-extension-plugin"&gt;
&lt;h3&gt;API Extension Plugin&lt;/h3&gt;
&lt;p&gt;The implementation delivered will include an API extension plugin that acts
as the REST API controller for diagnostics. As described in the REST API
section, a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/diagnostics&lt;/span&gt;&lt;/code&gt; URI is dangled off existing neutron resources
that only supports &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST&lt;/span&gt;&lt;/code&gt; with an empty request body. Therefore this
controller needs to service diagnostic requests for a specific resource
type and ID.&lt;/p&gt;
&lt;p&gt;The following pseudo code outlines the controllers logic for request handling:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Get a list of all plugin instances from the neutron manager that support
the diagnostic extension and filter them to only those that support
the said resource type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get a list of all active agents from the DB and filter to only those that
have the said resource type in their &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;diagnostic_resource_types&lt;/span&gt;&lt;/code&gt; column.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the list of plugin and agent providers that support the given resource
type, invoke their API(s) to run the checks they know about for the said
resource type and resource instance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Collect the diagnostic results, roll them into a nice response and return
them to the caller.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api"&gt;
&lt;h3&gt;REST API&lt;/h3&gt;
&lt;p&gt;When enabled, this implementation dangles a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/diagnostics&lt;/span&gt;&lt;/code&gt; URI off Neutron
resources. The only supported HTTP method for this URI is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST&lt;/span&gt;&lt;/code&gt; (with an
empty request body) that triggers diagnostic data collection from all
applicable registered diagnostic providers. While this spec proposes the
diagnostic collection be run synchronously for the initial iteration of the
implementation, future workings could make the collection job based run async
in the back ground.&lt;/p&gt;
&lt;p&gt;The generic form of the diagnostics URL is:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;resource_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;diagnostics&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The response is a list of diagnostic (dict) objects, one object per
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;diagnostic&lt;/span&gt;&lt;/code&gt;. A diagnostic is an aspect of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;{resource}&lt;/span&gt;&lt;/code&gt; checked,
and contains a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;description&lt;/span&gt;&lt;/code&gt; as well as a diagnostic &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;status&lt;/span&gt;&lt;/code&gt; object
and list of individual &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;checks&lt;/span&gt;&lt;/code&gt; run for the said diagnostic. Diagnostic
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;status&lt;/span&gt;&lt;/code&gt; is set by the diagnostics framework based on the result of
all checks for the said resource &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;diagnostic&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The array of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;checks&lt;/span&gt;&lt;/code&gt; returned for each diagnostic includes high level
details about the check such as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;name&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;description&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;provider&lt;/span&gt;&lt;/code&gt;.
In addition, checks report their own &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;status&lt;/span&gt;&lt;/code&gt; based on the result of
their check execution. If a check is not successful, the check must
return a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;remediation&lt;/span&gt;&lt;/code&gt; to describe potential ways to remediate the failed
check.&lt;/p&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;status&lt;/span&gt;&lt;/code&gt; at the diagnostic level is handled by the framework and
can be one of the following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;OK&lt;/span&gt;&lt;/code&gt;: All checks for the diagnostic are successful.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ERROR&lt;/span&gt;&lt;/code&gt;: One or more checks failed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;INACTIVE&lt;/span&gt;&lt;/code&gt;: One or more providers is inactive and couldn’t be invoked
to run the diagnostic checks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DEGRADED&lt;/span&gt;&lt;/code&gt;: Checks can be registered as optional. If a check is optional
and fails, or is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;INACTIVE&lt;/span&gt;&lt;/code&gt;, the diagnostic status will be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DEGRADED&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;subnets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;315&lt;/span&gt;&lt;span class="n"&gt;ec9bb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;&lt;span class="n"&gt;f5&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f7a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a44c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b13015a26803&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;diagnostics&lt;/span&gt;
&lt;span class="n"&gt;EMPTY&lt;/span&gt; &lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="n"&gt;BODY&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;All&lt;/span&gt; &lt;span class="n"&gt;successful&lt;/span&gt; &lt;span class="n"&gt;DHCP&lt;/span&gt; &lt;span class="n"&gt;diagnostics&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"diagnostics"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"diagnostic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"dhcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Neutron network DHCP diagnostics."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DS000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"OK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"All checks completed successfully."&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s2"&gt;"checks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"name:"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"check1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Check1 does this and that."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DS000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"OK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="s2"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DHCP Agent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"dhcp-host1"&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="s2"&gt;"remediation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"name:"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"check2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Check2 does cool stuff."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DS000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"OK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="s2"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DHCP Agent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"dhcp-host2"&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="s2"&gt;"remediation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;subnets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;315&lt;/span&gt;&lt;span class="n"&gt;ec9bb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;&lt;span class="n"&gt;f5&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f7a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a44c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b13015a26803&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;diagnostics&lt;/span&gt;
&lt;span class="n"&gt;EMPTY&lt;/span&gt; &lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="n"&gt;BODY&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="n"&gt;failed&lt;/span&gt; &lt;span class="n"&gt;dhcp&lt;/span&gt; &lt;span class="n"&gt;diagnostic&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"diagnostics"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"diagnostic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"dhcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Neutron network DHCP diagnostics."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DS002"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ERROR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Check 'check1' failed. See the check details for more info."&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s2"&gt;"checks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"name:"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"check1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Check1 does this and that."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DHCPE001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ERROR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"The dnsmasq process is not running."&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="s2"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DHCP Agent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"dhcp-host1"&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="s2"&gt;"remediation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DHCPR001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Re-enable DHCP for this network, then rerun this check."&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"name:"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"check2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Check2 does cool stuff."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DS000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"OK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="s2"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DHCP Agent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"dhcp-host2"&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="s2"&gt;"remediation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Access control to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/diagnostics&lt;/span&gt;&lt;/code&gt; is handled via standard policy definition.
The default access control is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;admin_only&lt;/span&gt;&lt;/code&gt;, but operators can change this
in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;policy.json&lt;/span&gt;&lt;/code&gt; as needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="benefits"&gt;
&lt;h3&gt;Benefits&lt;/h3&gt;
&lt;p&gt;While the main purpose of this effort is to spearhead diagnostics in Neutron and
start building out the plumbing, this functionality is immediately valuable for
consumers and out-of-tree plugins alike.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The python-don project &lt;a class="footnote-reference brackets" href="#id11" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; can implement diagnostic data collection for
data used in its analysis.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The vmware-nsx plugin can migrate some of its operator CLI functionality &lt;a class="footnote-reference brackets" href="#id12" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;
into diagnostic data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The implementation can be enhanced to collect interface stats similar to how
Nova diagnostics &lt;a class="footnote-reference brackets" href="#id13" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; does.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="future-work"&gt;
&lt;h3&gt;Future work&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Once the API solidifies, a CLI can be added to support diagnostics.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id9" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/osops-tools-generic/blob/master/neutron/listorphans.py"&gt;https://github.com/openstack/osops-tools-generic/blob/master/neutron/listorphans.py&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.tuxfixer.com/openstack-how-to-manually-delete-orphaned-neutron-port/"&gt;http://www.tuxfixer.com/openstack-how-to-manually-delete-orphaned-neutron-port/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id11" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id3"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id6"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/python-don"&gt;https://github.com/openstack/python-don&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id4"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id7"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/vmware-nsx/blob/master/vmware_nsx/shell/admin/README.rst"&gt;https://github.com/openstack/vmware-nsx/blob/master/vmware_nsx/shell/admin/README.rst&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id13" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id5"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id8"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Nova_VM_Diagnostics"&gt;https://wiki.openstack.org/wiki/Nova_VM_Diagnostics&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;section id="related-information"&gt;
&lt;h3&gt;Related Information&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1563538"&gt;https://bugs.launchpad.net/neutron/+bug/1563538&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Tue, 19 Dec 2017 00:00:00 </pubDate></item><item><title>IPv6 Router</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/ipv6-router.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ipv6-router"&gt;https://blueprints.launchpad.net/neutron/+spec/ipv6-router&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;IPv6 and IPv4 have significant differences, not only on the IP address format,
but also on the protocol operations. In this specification, we will discuss how
to support IPv6 neutron router in terms of public access.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;For IPv4, a tenant can assign a private prefix to its network, and use
floatingip to gain access to the public network that is assigned with public IP
addresses. Floatingip is currently not supported for IPv6 in neutron. There is
a neutron spec for IPv6 floatingip that may be possible for later openstack
releases &lt;a class="reference internal" href="#ipv6-fip" id="id1"&gt;&lt;span&gt;[IPV6_FIP]&lt;/span&gt;&lt;/a&gt;. To gain public access with a neutron router that is
connected to a public network, a tenant can use a GUA address in its own
network.&lt;/p&gt;
&lt;p&gt;For IPv4, public IP addresses need to be assigned to the gateway port so that
NAT traffic can terminate. For IPv6 with GUA tenant network, it’s not necessary
to assign a GUA prefix (or any prefix) to the gateway port. This is because, by
default, an IPv6 network is always assigned with the LLA prefix fe80::/10
&lt;a class="reference internal" href="#ipv6-addr" id="id2"&gt;&lt;span&gt;[IPV6_ADDR]&lt;/span&gt;&lt;/a&gt;. And the same is true for the gateway port in a neutron router
with IPv6 enabled.&lt;/p&gt;
&lt;p&gt;Note that the external network can still be associated with an explicit IPv6
subnet. Its use case will be explained in &lt;a class="reference internal" href="#ipv6-fip" id="id3"&gt;&lt;span&gt;[IPV6_FIP]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It’s possible that the upstream router runs RA. The RA may simply advertise a
default route. In the same time, it may also carry a prefix for SLAAC. In
either case, the neutron router should have a default route installed after the
RA message is processed. To cover the case where the upstream router doesn’t
advertise a default route with RA, there needs to be a way to configure the
default nexthop in the neutron router.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The implementation of &lt;em&gt;router-gateway-set&lt;/em&gt; API will be changed so that an IPv6
subnet is not required in the external network identified by the
&lt;em&gt;external-network-id&lt;/em&gt;. To create the gateway port for a neutron router, the
internal implementation of the &lt;em&gt;port-create&lt;/em&gt; API is invoked. Currently in the
IPv6 only case, without explicitly providing an IPv6 subnet, a Bad Request
exception will be generated. Assuming the gateway port is associated with the
fe80::/10 prefix, change will be made to ensure the gateway port is created
successfully.&lt;/p&gt;
&lt;p&gt;When an IPv4 subnet is added in a router, check to make sure that the router’s
gateway port is on an IPv4 public network.&lt;/p&gt;
&lt;p&gt;To support explicit nexthop configuration of neutron router in the absence of
upstream RA, add an &lt;em&gt;ipv6-gateway&lt;/em&gt; parameter in the l3 agent configuration file
as in below:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;ipv6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;gateway&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GATEWAY_LLA&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;em&gt;GATEWAY_LLA&lt;/em&gt; should be a valid LLA address. And if it’s not a valid LLA
address, L3 agent will log a warning message. With a valid &lt;em&gt;ipv6-gateway&lt;/em&gt; LLA
address, the l3 agent will install a default route with the nexthop being the
&lt;em&gt;GATEWAY_LLA&lt;/em&gt;, and the outgoing interface the gateway port.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;This specification specifies the changes to support IPv6 router.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;This spec introduces a new l3 agent configuration parameter as described in above.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;If a plugin supports neutron router and IPv6, then it may need to be changed to
support the router API semantics change.&lt;/p&gt;
&lt;p&gt;Also devstack change may be needed to support the IPv4 only, IPv6 only and dual
stack configuration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change is aligned with the community effort in support of IPv6 in neutron&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;In the IPv6 only case, it’s possible to create a fake ipv6 subnet and use
it to create the gateway port.&lt;/p&gt;
&lt;p&gt;In an IPv6 only router, the neutron public network doesn’t actually contain any
useful information currently. But removing it would require API change. In
addition, it may be useful in the future to partition the public network into
smaller broadcast domains.&lt;/p&gt;
&lt;p&gt;Another idea is to have a flag associated with a neutron router to indicate if
the router is running in one of the three modes: IPv4 only, IPv6 only or dual
stack. This can make sure that the gateway port is created properly with
required subnets.&lt;/p&gt;
&lt;p&gt;Is it necessary to provide a &lt;em&gt;disable_ipv6&lt;/em&gt; option for a neutron network,
and/or an overall config option &lt;em&gt;disable_ipv6&lt;/em&gt; in the neutron config file?&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;baoli&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;will add as needed&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Change due to router API semantics change&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create the gateway port in the absence of subnets&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Develop test cases&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;It may have a dependency on the l3 agent refactoring if it’s found that change
is needed in the l3 agent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Tempest tests should be developed to ensure the neutron routers work
properly in IPv4 only, IPv6 only and dual stack environment.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional tests are needed to ensure the gateway port is properly created in
IPv4 only, IPv6 only and dual stack cases.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Existing unit tests for the router APIs may need to be updated to
reflect the change. New unit tests may be needed to test the API semantic
changes.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;User guide to neutron router needs to be updated&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;API semantic changes need to be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;div role="list" class="citation-list"&gt;
&lt;div class="citation" id="ipv6-addr" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;IPV6_ADDR&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://tools.ietf.org/html/rfc4291"&gt;IP Version 6 Addressing Architecture&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="ipv6-fip" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;IPV6_FIP&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/139731/"&gt;IPv6 Floating IP Support&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;section id="related-information"&gt;
&lt;h3&gt;Related Information&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/131535/"&gt;Kilo refactoring and restructuring the l3 agent&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Tue, 19 Dec 2017 00:00:00 </pubDate></item><item><title>Add Port security extension support for ML2 plugin and IptablesFirewallDriver</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/ml2-ovs-portsecurity.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ml2-ovs-portsecurity"&gt;https://blueprints.launchpad.net/neutron/+spec/ml2-ovs-portsecurity&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes to add support portsecurity extension to ML2 plugin and
IptablesFirewallDriver to match it.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Neutron’s security group always applies anti-spoof rules on the VMs.
This allows traffic to originate and terminate at the VM as expected,
but prevents traffic to pass through the VM. This is required in cases
where the VM routes traffic through it.
In order to run network services in VM instances (e.g. router service
in VM &lt;a class="reference internal" href="#router-plugin-cisco" id="id1"&gt;&lt;span&gt;[router_plugin_cisco]&lt;/span&gt;&lt;/a&gt;, &lt;a class="reference internal" href="#vyatta-l3-plugin" id="id2"&gt;&lt;span&gt;[vyatta_l3_plugin]&lt;/span&gt;&lt;/a&gt; or firewall service in VM),
it is required by some services for VMs to be able to
receive/send all packets without any kind of firewall, security group,
anti spoofing on port. This is a basic requirement to run
network service within VMs. The necessity depends on the type of
services. Some services require it, some don’t.&lt;/p&gt;
&lt;p&gt;At this point Neutron has a port security extension to disable packet
filtering. (&lt;a class="reference internal" href="#port-security-extension" id="id3"&gt;&lt;span&gt;[port_security_extension]&lt;/span&gt;&lt;/a&gt;, &lt;a class="reference internal" href="#port-security-extension-db" id="id4"&gt;&lt;span&gt;[port_security_extension_db]&lt;/span&gt;&lt;/a&gt;)
But currently the portsecurity extension isn’t supported by any open source
plugins/firewall driver.
This blueprint is to add the extension support to the ML2 plugin when
configured with OVS agents using the IptablesFirewallDriver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="how-portsecurity-extension-works"&gt;
&lt;h3&gt;How portsecurity extension works&lt;/h3&gt;
&lt;p&gt;The original documentation for NSX plugin can be found at
&lt;a class="reference internal" href="#port-security-base-class" id="id5"&gt;&lt;span&gt;[port_security_base_class]&lt;/span&gt;&lt;/a&gt; and &lt;a class="reference internal" href="#quantum-port-security" id="id6"&gt;&lt;span&gt;[quantum_port_security]&lt;/span&gt;&lt;/a&gt;.
The extension adds a new attribute, “port_security_enabled”, to
network and port resources. The port_security_enabled of network is used as
the default attribute value at port creation.
When the attribute is set to True(by default), the behavior remains same to
the one without portsecurity extension, security group and anti spoofing will
act as before. When the attribute is set to False, security group and anti
spoofing are disabled on the port, and it is not allowed to set security group
or allowedaddresspair with such ports.  Since this feature is related to
security, only tenant owner is allowed to set/change the attribute.&lt;/p&gt;
&lt;p&gt;Some clarifications&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The attribute of network affects only at port creation. The already created
ports aren’t affected when the value of network is changed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the port is already associated with security group, it results in
an error to try to change port_security_enabled to False.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When port_security_enabled = False, it results in an error to set
security group or allowedaddresspair&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="steps"&gt;
&lt;h3&gt;Steps&lt;/h3&gt;
&lt;p&gt;Add port-security extension as ML2 extension driver.
And then add necessary feature in IptablesFirewallDriver.
Port security extension is already added in neutron. Implementation of this
extension in the ml2 plugin will allow enabling/disabling filters on the
neutron port as required when using the ml2 plugin.&lt;/p&gt;
&lt;p&gt;The sketch of implementation of ovs agent enhancement:
OVS bridge and its flow rules are used to route packet, push/pop vlan tag,
and tunneling. So openflow rules doesn’t need to be touched.
The security group/anti-spoofing are realized by iptables with linux
bridge whose name is qbrxxx. The actual firewall driver is
neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;$e&amp;lt;device name&amp;gt; chain in filter table is used for security group filtering
of egress packet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;$i&amp;lt;device name&amp;gt; chain in filter table is used for security group filtering
of ingress packet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;$s&amp;lt;device name&amp;gt; chain in filter table is used for anti-spoofing.
This is only partially works. anti ARP spoofing isn’t implemented. For that,
ebtables is necessary. &lt;a class="reference internal" href="#bug1274034" id="id7"&gt;&lt;span&gt;[bug1274034]&lt;/span&gt;&lt;/a&gt;
NOTE: ARP spoofing will not implemented in the scope of this BP.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So those chains will be modified to ACCEPT.
Or the parent chain of those chains is $sg-chain which demuxes packets
to the above three chains. Another option is to change the rule in $sg-chain.&lt;/p&gt;
&lt;p&gt;related bridges(take ovs plugging for example):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+----+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----+&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------+&lt;/span&gt;   &lt;span class="n"&gt;Linux&lt;/span&gt; &lt;span class="n"&gt;bridge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;qbrxxx&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;firewall&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;realized&lt;/span&gt; &lt;span class="n"&gt;here&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;iptables&lt;/span&gt; &lt;span class="n"&gt;chains&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;which&lt;/span&gt;
&lt;span class="o"&gt;+--------+&lt;/span&gt;    &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;modified&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;implement&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;spec&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------+&lt;/span&gt;   &lt;span class="n"&gt;ovs&lt;/span&gt; &lt;span class="n"&gt;bridge&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------+&lt;/span&gt;
   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------------------+&lt;/span&gt;  &lt;span class="n"&gt;ovs&lt;/span&gt; &lt;span class="n"&gt;bridge&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tun&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;portsecuritybindings and networksecuritybindings tables will be used by ml2
plugin.
The tables already exist and will be use without modification, no new tables
will be added.
They could be refered to in neutron/db/portsecurity_db.py&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Port security extension is cited here for convenience.
This blueprints doesn’t add this API, enables it.&lt;/p&gt;
&lt;p&gt;Default value of port_security_enable for a network is True, and same
attribute setting for port created from the network will inherit this value.
Then it means the same behaviour without this extension. The behavior For the
existing port (with or without security group) remain same as before.
When port_security_enabled = False, security group and anti-spoofing are
disabled on the port. It results in AddressPairAndPortSecurityRequired
exception to try to set to allowed address pairs attribute.&lt;/p&gt;
&lt;p&gt;The code could be refered from neutron/extensions/portsecurity.py&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;This feature is dangerous to the unwary. They should only be available
to network owners to avoid compromise of other people’s networks.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;port_security_enabled attribute of network and port will be added to
related notification.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None, because the port security attribute defaults to True, and therefore
existing ports will be unaffected.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;OVS agent could be heavier because its port management task will be
enhanced.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Since ML2 plugin will be changed to support port-security extension as
first class citizen. And we will use the current framework to notify l2 agent
when the attribute is changed.
Iptables firewall driver would be updated to add/update chains to make
packages passed through.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;Portsecurity extension is desired by various parties, servicevm from various
vendors who promotes virtual appliance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Documentation can be done such that disable security (or to use other
extension like allowed address pairs) to use the service YYY.
However some features can’t be disabled/enabled per port-wise and can’t be
done automatically as Neutron ports are created/deleted.
It lacks flexibility. So simple documentation doesn’t work.&lt;/p&gt;
&lt;p&gt;Another alternative is to introduce keyed knobs to control security
group and anti spoofing each instead of single knob, port_security_enabled.
The value will be dict of&lt;/p&gt;
&lt;p&gt;Example of value&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'port_security_group_enabled'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s1"&gt;'port_anti_spoofing_enabled'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="c1"&gt;# dict value is adopted to allow more precise control for filtering in future&lt;/span&gt;
&lt;span class="c1"&gt;# e.g. 'port_filter_level': 1&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'all_filtering_enabled'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="c1"&gt;# all_filtering_enabled is special key to enable/disable all&lt;/span&gt;
&lt;span class="c1"&gt;# related filtering.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PORTSECURITY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'port_security_enabled'&lt;/span&gt;
&lt;span class="c1"&gt;# or port_security_disabled to list only disabled filters&lt;/span&gt;
&lt;span class="n"&gt;EXTENDED_ATTRIBUTES_2_0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'networks'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;PORTSECURITY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
                       &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_kvp_to_dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'enforce_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ATTR_NOT_SPECIFIED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;'ports'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;PORTSECURITY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_kvp_to_dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ATTR_NOT_SPECIFIED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'enforce_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Another approach is to add a new attribute in port binding extension, like one
in “binding:profile”.
But with port binding extension, only admin is allowed to set the attribute
and a way to specify default value for a network is necessary.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Implement the port security extension in ml2 plugin
This introduces the ability to enable/disable the port_security_state
in the ml2 plugin while creating/updating a port or a network.
The create network function will assign a default port_security_state
to all ports to be created in that network.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;yalei-wang&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shweta P &amp;lt;shweta-ap05&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ijw-ubuntu (Ian Wells)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;yamahata (Isaku Yamahata)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;rui-zang&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;(name) means task assignment.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;implement portsecurity extension as ML2 extension driver
(Shweta and Isaku)
** convert dependent extension into extension driver if necessary
(Shweta and Isaku)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OVS agent and iptables firewall driver modification
(Yalei)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tests
(everyone)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;tempest will be enhanced to check if security group isn’t applied.
i.e. API tests for port-security extension and scenario tests for functional
tests.
* creation/deletion of ports with or without port_security_enabled=True/False
* try to send/receive packets that is filtered by port filtering to other ports
* check if the packets can be received/sent with other port&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Related scenario test will be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Necessary test will be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;port_security_extension unit test has been added in repo.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;API and Admin guide will be updated so that it includes
* configuration to enable portsecurity extension for ML2 OVS driver
* new attributes and new CLI interfaces&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;div role="list" class="citation-list"&gt;
&lt;div class="citation" id="port-security-extension" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;port_security_extension&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;port security extension
&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/extensions/portsecurity.py"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/extensions/portsecurity.py&lt;/a&gt;
&lt;a class="reference external" href="https://docs.google.com/document/d/18trYtq3wb0eJK2CapktN415FRIVasr7UkTpWn9mLq5M/edit"&gt;https://docs.google.com/document/d/18trYtq3wb0eJK2CapktN415FRIVasr7UkTpWn9mLq5M/edit&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="port-security-extension-db" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;port_security_extension_db&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;port security extension db part
&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/db/portsecurity_db.py"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/db/portsecurity_db.py&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="router-plugin-cisco" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;router_plugin_cisco&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Describes design of router service plugin for Cisco devices
&lt;a class="reference external" href="https://review.openstack.org/#/c/91071/"&gt;https://review.openstack.org/#/c/91071/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="vyatta-l3-plugin" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;vyatta_l3_plugin&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Design Spec For Brocade Vyatta L3 Plugin
&lt;a class="reference external" href="https://review.openstack.org/#/c/101052/"&gt;https://review.openstack.org/#/c/101052/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="port-security-base-class" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;port_security_base_class&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Port Security API base class
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/port-security-api-base-class"&gt;https://blueprints.launchpad.net/neutron/+spec/port-security-api-base-class&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="quantum-port-security" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;quantum_port_security&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Quantum Port Security
&lt;a class="reference external" href="https://docs.google.com/document/d/18trYtq3wb0eJK2CapktN415FRIVasr7UkTpWn9mLq5M/edit?pli=1"&gt;https://docs.google.com/document/d/18trYtq3wb0eJK2CapktN415FRIVasr7UkTpWn9mLq5M/edit?pli=1&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="bug1274034" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;bug1274034&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Neutron firewall anti-spoofing does not prevent ARP poisoning
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1274034"&gt;https://bugs.launchpad.net/neutron/+bug/1274034&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;section id="related-information"&gt;
&lt;h3&gt;Related Information&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Support for extensions in ML2 Mechanism Drivers&lt;/p&gt;
&lt;p&gt;spec review: &lt;a class="reference external" href="https://review.openstack.org/#/c/89208/"&gt;https://review.openstack.org/#/c/89208/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;etherpad: &lt;a class="reference external" href="https://etherpad.openstack.org/p/ML2_MD_extensions"&gt;https://etherpad.openstack.org/p/ML2_MD_extensions&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modular L2 agent&lt;/p&gt;
&lt;p&gt;spec review: &lt;a class="reference external" href="https://review.openstack.org/#/c/99187/"&gt;https://review.openstack.org/#/c/99187/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neturon Distributed Virtual Router for OVS
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-ovs-dvr"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-ovs-dvr&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open vSwitch-based Security Groups: Open vSwitch Implementation of
FirewallDriver
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ovs-firewall-driver"&gt;https://blueprints.launchpad.net/neutron/+spec/ovs-firewall-driver&lt;/a&gt;
&lt;a class="reference external" href="https://review.openstack.org/#/c/89712/"&gt;https://review.openstack.org/#/c/89712/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support for extensions in ML2 Mechanism Drivers
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-ml2-mechanismdriver-extensions"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-ml2-mechanismdriver-extensions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add Port Security Implementation in ML2 Plugin
duplicated proposal. consolidated to this one.&lt;/p&gt;
&lt;p&gt;blueprint &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/port-security-ml2"&gt;https://blueprints.launchpad.net/neutron/+spec/port-security-ml2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;spec review &lt;a class="reference external" href="https://review.openstack.org/#/c/106222/"&gt;https://review.openstack.org/#/c/106222/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NFV unaddressed interfaces&lt;/p&gt;
&lt;p&gt;blueprint &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/nfv-unaddressed-interfaces"&gt;https://blueprints.launchpad.net/neutron/+spec/nfv-unaddressed-interfaces&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;spec review &lt;a class="reference external" href="https://review.openstack.org/#/c/97715/"&gt;https://review.openstack.org/#/c/97715/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add portsecurity extension support
patch for ovs firewall driver
&lt;a class="reference external" href="https://review.openstack.org/#/c/126552/"&gt;https://review.openstack.org/#/c/126552/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;related bugs: creating network without subnet and port without subnet
&lt;a class="reference external" href="https://bugs.launchpad.net/bugs/1039665"&gt;https://bugs.launchpad.net/bugs/1039665&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/bugs/1175464"&gt;https://bugs.launchpad.net/bugs/1175464&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Tue, 19 Dec 2017 00:00:00 </pubDate></item><item><title>Support Multiple IPv6 Prefixes and Addresses for IPv6 Network</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/multiple-ipv6-prefixes.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/multiple-ipv6-prefixes"&gt;https://blueprints.launchpad.net/neutron/+spec/multiple-ipv6-prefixes&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;IPv6 standards allow for multiple IPv6 prefixes and addresses to be
associated with a given interface. This blueprint defines how multiple
IPv6 prefixes and/or addresses per Neutron port will be supported in
OpenStack, and describes how this differs from the IPv4 implementation.&lt;/p&gt;
&lt;p&gt;Some possible use cases include:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Allow a mix of public (Global Unicast Address, or GUA) and private
(e.g. Unique Local Address, or ULA) IPv6 addresses on a tenant network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IPv6 renumbering: Support for overlap interval during which old and new
IPv6 prefixes co-exist (e.g. on router port).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Floating-IP-like support: Allow for a tenant to allocate an address from
a pool of pre-determined public IPv6 addresses, and associate that
address with a VM or set of VMs. Note: Unlike the IPv4 Floating IP
feature, IPv6 support would not involve NAT translation from fixed IPs
to floating IPs. This design specification is a pre-requisite for
IPv6 Floating IPs; more details will be covered in a separate blueprint.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Considerations for IPv6&lt;/p&gt;
&lt;p&gt;There are some differences between IPv6 and IPv4 which need to be
considered when deciding how multiple IPv6 prefixes and addresses
should be configured and supported in Neutron, and how closely the
IPv6 implementation will follow the IPv4 paradigm:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;IPv6 addresses are more abundant. That means:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;We can afford to be less conservative about assigning addresses to a
port from each of the subnets within a network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No need to do NAT translation. Globally accessible addresses can
be assigned directly to the port.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IPv6 provides two main mechanisms for assigning IP addresses:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;SLAAC (Stateless Address Autoconfiguration):
This mechanism &lt;a class="reference internal" href="#ref-2" id="id1"&gt;&lt;span&gt;[Ref-2]&lt;/span&gt;&lt;/a&gt; requires minimal configuration of hosts and
routers. With SLAAC, routers periodically send out Router Advertisement
(RA) messages via multicast to all IPv6-enabled hosts on that link.
(In OpenStack, generation of RA messages by virtual routers is provided
by a router advertisement daemon, or radvd process.) The RA messages
contain one or more prefixes that identify subnets associated with
the link. Hosts on the link then generate unique IPv6 addresses per
SLAAC subnet and per interface on the link by forming a unique
“interface identifier” (typically based on the interface’s MAC
address), and combining that interface identifier with each prefix.
To obtain an router advertisement quickly, hosts on that
link may also prompt the router by sending a Router Solicitation
message &lt;a class="reference internal" href="#ref-3" id="id2"&gt;&lt;span&gt;[Ref-3]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DHCPv6: Similar to DHCPv4, a DHCP server can be configured to assign
specific IPv6 addresses to each node on a link.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With the current Neutron implementation, a subnet is configured for
SLAAC vs. DHCPv6 stateful/stateless address mode when the subnet is
created by setting the “ipv6_ra_mode” and “ipv6_address_mode” attributes
in a subnet-create API call. These attributes were added with the
blueprint listed in &lt;a class="reference internal" href="#ref-4" id="id3"&gt;&lt;span&gt;[Ref-4]&lt;/span&gt;&lt;/a&gt;. Attribute values are described in &lt;a class="reference internal" href="#ref-5" id="id4"&gt;&lt;span&gt;[Ref-5]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For the purposes of this design specification, the term “SLAAC-enabled”
subnets will be used to refer to subnets that are configured for either
SLAAC or DHCPv6-stateless address modes.&lt;/p&gt;
&lt;p&gt;The important aspect of SLAAC addressing to consider here is that
RA messages are multicast (on the all nodes multicast channel) to all
IPv6-capable nodes on a link. What this means in an OpenStack instance
is that whenever a subnet is created with SLAAC address generation mode,
all IPv6-capable hosts/VMs which are created on that network will
receive periodic RA messages which include the associated prefix for that
subnet (along with prefixes for all other SLAAC-enabled subnets on that
network). The host will therefore generate an address using that
subnet/prefix, regardless of whether the associated port-create API calls
(and any follow-up port-update API calls) for that VM happen to specify
that the subnet should be associated with that port.&lt;/p&gt;
&lt;p&gt;Theoretically, it would be possible to selectively enable/disable
delivery of RA prefix assignments on a per-port, per-subnet basis by
configuring radvd so that RA messages are delivered per subnet via
unicast, but this implementation would be rather complex and would not
scale well in a large network because of the added messaging and
processing required, and would go against the automatic nature of SLAAC.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Current Implementation&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Port creation with explicit list of fixed IPs:&lt;/p&gt;
&lt;p&gt;With the current Neutron implementation, when a port is created with
an explicit list of fixed IPs, IPs from the following subnets on the
associated network will be associated with the port:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;All subnets/IPs that are explicitly listed&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What is missing is that SLAAC-enabled subnets are not implicitly
included for association with the port, even though IPv6-enabled VMs
will be automatically generating SLAAC addresses for those subnets
based on RA messages that they receive.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Port creation without explicit list of fixed IPs:&lt;/p&gt;
&lt;p&gt;With the current Neutron implementation, when a port is created without
an explicit list of fixed IPs, IPs from the following subnets on the
associated network are associated with the port:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;One subnet from all IPv4 subnets&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One subnet from all IPv6 DHCPv6-stateful subnets&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All SLAAC-enabled subnets&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What could be considered here is whether all DHCPv6-stateful subnets
should also be implicitly included for allocation and association with
the port (along with SLAAC-enabled subnets), since IPv6 addresses are
more plentiful. However, this would be quite a shift from the IPv4 model,
so it would be safer and less confusing to stay with the current
implementation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Port update:&lt;/p&gt;
&lt;p&gt;With the current Neutron implementation, when a port is updated,
IPs from the following subnets on the associated network are
associated with the port:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;All subnets/IPs explicitly listed in the optional fixed_ips list&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What’s arguably broken here is that any existing association with
addresses from SLAAC-enabled subnets that are not explicitly included
in the fixed_ips list of a port update request will be forgotten
(deleted), even though the port will continue to use the SLAAC addresses
as long as the source of IPv6 RA messages (radvd process) continues to
send RA messages to all IPv6-enabled hosts via the all-nodes multicast
channel.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Router interface create&lt;/p&gt;
&lt;p&gt;Layer 3 (L3) agent limits the number of IP addresses that is initially
associated with an internal router interface (gateway port) to a maximum
of one IP address per family (i.e. up to one IPv4 address and up to
one IPv6 address).&lt;/p&gt;
&lt;p&gt;For externally-facing gateway ports, the number of IP addresses is
further restricted to a single IP address, either IPv4 or IPv6 &lt;a class="reference internal" href="#ref-1" id="id5"&gt;&lt;span&gt;[Ref-1]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The change described in &lt;a class="reference internal" href="#ref-1" id="id6"&gt;&lt;span&gt;[Ref-1]&lt;/span&gt;&lt;/a&gt;, which is currently abandoned, was
an attempt to relax this restriction so that up to one IPv4 address
and up to one IPv6 address would be allowed per external gateway port.&lt;/p&gt;
&lt;p&gt;This blueprint will include the change described in &lt;a class="reference internal" href="#ref-1" id="id7"&gt;&lt;span&gt;[Ref-1]&lt;/span&gt;&lt;/a&gt;, and will
also relax the restrictions for internal router ports by allowing
multiple IPv6 addresses per internal router port.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Port Create API Call&lt;/p&gt;
&lt;p&gt;The definition/syntax of the Neutron port-create API request/response
messages will not be changed for this blueprint. However, the way in
which this API call will be used, and the way that Neutron handles this
call when IPv6 subnets are included in the associated network, will
represent a small shift from the IPv4 model. The change in behavior will
revolve around the notion that if a network includes a SLAAC-enabled
subnet, then all ports on the network will get an address from that subnet
automatically. The changes can be summarized:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Current IPv4 behavior will not be changed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Port-create operations with an explicit list of fixed IPs:
When an explicit list of fixed IPs is included (via fixed_ips dictionary),
the following changes will apply:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;All SLAAC-enabled subnets on the associated network will now be
implicitly associated with the port, regardless of whether or not
these subnets are explicitly included in the fixed_ips list.
(DHCPv6-stateful subnets will continue to be included in this case
only when they are explicitly included in fixed_ips.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A port-create request can optionally include SLAAC-enabled
subnets explicitly listed in fixed_ips, but these entries are
superfluous.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Port-create operations without an explicit list of fixed IPs:
There will be no change from the current design. When a port-create
operation does not include an explicit list of fixed IPs, the following
subnets on the associated network will be associated with the port:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;One subnet from all IPv4 subnets&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One subnet from all IPv6 DHCPv6-stateful subnets&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All SLAAC-enabled subnets&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Response to API call will list all fixed IPs associated with the
port, whether the association was implicitly or explicitly included in
the port-create request.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Port Update API Call&lt;/p&gt;
&lt;p&gt;Similar to the port-create API call, the definition/syntax of the Neutron
port-update API request/response messages will not change, but the way in
which this API call is used and the way that Neutron handles these
requests will change for IPv6 subnets/addresses. The change in behavior
will revolve around the notion that if a network includes a SLAAC-enabled
subnet, then all ports on the network will get an address from that subnet
automatically. The following changes will apply:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The association of IP addresses/subnets for each SLAAC-enabled subnet
on the associated network will now be implicitly preserved (retained)
when the port-update operation does not explicitly include the
SLAAC-enabled subnet in the fixed_ips list of changed/new
subnets/addresses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The response to the API call will include addresses for all SLAAC-enabled
subnets on the network in the list fixed IPs associated with the
port, whether the association was implicitly or explicitly included in
the port-update request.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subnet Create API Call&lt;/p&gt;
&lt;p&gt;When a SLAAC-enabled subnet is created after ports have already been
created on a given network, and that subnet relies on a
provider source for RA messages (as opposed to an OpenStack reference
RADVD process; this is selected via “ipv6_ra_mode” and “ipv6_address_mode”
attributes in the subnet-create API call), then the associated IPv6-capable
hosts on the network will be expected to automatically generate SLAAC
addresses based on prefixes advertised by the provider’s source of RA
messages. In order to keep in sync with these generated addresses, the
subnet create processing will need to be modified to add entries in the
IPAllocations table for all existing ports on the network in order to
associate the ports with addresses on the SLAAC-enabled subnet.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Limits on Number of IP Addresses per Router Interface&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Externally-facing gateway ports: As discussed in the Problem
Definition section, this blueprint will relax the restrictions imposed
by the Neutron L3 agent on externally-facing gateway ports by allowing
up to one IPv4 address and up to one IPv6 address per port.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Internal router ports: This blueprint will relax restrictions imposed
on internal router ports by allowing multiple IPv6 addresses on each
internal router port. For IPv4 subnets, no change will be made, that
is, separate router interfaces will be required for each IPv4 subnet
that requires a gateway IP address.&lt;/p&gt;
&lt;p&gt;The handling for the router interface create API call will be changed
so that IPv6 subnets on a given network will share one internal router
port per router to which they are attached. That is, when the router
interface create API is called for an IPv6 subnet, a check will be
performed to see if there is already an internal router interface
on that router that supports a gateway address for one of the other
IPv6 subnets in the network. If so, the new IPv6 gateway IP address
will be added to that existing interface, rather than having a new
router interface created.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;No data model changes are anticipated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;As discussed in earlier sections, the definition/syntax of the port-create,
port-update, and subnet-delete API calls will not be changed, but the way
in which these API calls are used and the way that Neutron handles these
API calls will be modified for IPv6 subnets as compared to IPv4 subnets.
In particular, ports will be automatically associated with addresses from
all SLAAC-enabled subnets within the port’s network as part of port create
and port update operations, and the port create and port update responses
will automatically include those SLAAC addresses in the list of fixed_ips.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;There may be some risk associated with opening up an OpenStack cloud to
IPv6 RA messages (e.g. spoofed RA messages may modify the network), but this
is a concern for basic SLAAC implementation, and not something that is being
introduced with this blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;No changes anticipated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;Nothing more than what was discussed in the “REST API Impact” section.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;No significant performance impact expected.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;Yes, this effects the Neutron reference IPv6 implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Deployers will need to understand that IPv6 addresses will be automatically
and implicitly generated on every port on a network for every SLAAC-enabled
subnet in that network. This should not come as no surprise, since SLAAC is
an autoconfiguration mechanism.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Developers of L3 services may need to incorporate some of the behavior
changes proposed in the blueprint with respect to port creation when
IPv6 subnets are involved to ensure that management plane behavior properly
reflects the way that SLAAC works. The implementation for this blueprint
will be incorporated into common framework database classes, so services
that derive from these classes should automatically inherit this behavior.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This blueprint is a natural progression from the addition of RADVD and
IPv6 SLAAC support to the Neutron reference design. It is an attempt to
reconcile some inconsistencies between the way that IPv6 SLAAC works
and what IP addresses are implicitly associated when a port is created
without an explicit list of fixed IPs in the current design.&lt;/p&gt;
&lt;p&gt;This has not been discussed on mailing lists, but the blueprint and
associated patch set have been up for review since mid-Juno. This was added
as an etherpad agenda item to discuss at the Atlanta summit during the IPv6
design session, but unfortunately the design session ended before we got to
this item.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;As an alternative to what is being proposed, it would be possible to
avoid the automatic nature of RA prefix assignments by configuring radvd
so that RA messages are delivered on a per-port, per-subnet basis via
unicast. Ports that explicitly include a given SLAAC-enabled subnet would
then be sent an RA unicast that includes an advertisement of that subnet,
and ports that don’t explicitly include the SLAAC subnet would not receive
an RA unicast (or would receive an RA that doesn’t include the subnet).
However, this approach would be rather complex and error prone, and
would go against the automatic nature of SLAAC. Also, this approach would
not add much value given that IPv6 addresses can already be selectively
assigned on a subnet by using DHCPv6-stateful.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Dane LeBlanc
launchpad-id: leblancd&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Robert (Bao) Li
launchpad-id: baoli&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Port-create API handling coding and unit test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Port-update API handling coding and unit test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subnet-delete API handling coding and unit test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Router/Gateway interface coding and unit test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest test creation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Testing for API behavior will be incorporated into the Neutron in-tree
API tests, so no out-of-tree Tempest API tests will be added.&lt;/p&gt;
&lt;p&gt;A Tempest network scenario test will be added to check dataplane
connectivity when multiple addresses per port are in use:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create an internal router port with 1 IPv4, 1 SLAAC, and 1 DHCPv6 subnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create an instance using all three subnets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the instance, ping the gateway IP address for each of the three
subnets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the instance, ping an external gateway port.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;No functional tests needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;API tests for port create on a network with 1 IPv4 and 1 SLAAC
address/subnets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API test for port create on a network with 1 IPv4, 1 DHCPv4
address/subnets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API test for port create on a network with 2 DHCPv4 and 2 SLAAC
address/subnets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API test for port update: Start with a SLAAC address, add DHCPv4 address.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;The Neutron API v2 reference documentation may need to be modified to reflect
the expected behavior with respect to implicit IPv6 address assignments for
port-create, port-update, and subnet delete (although the documentation
doesn’t go into this much detail):&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/APIv2-specification#Create_Port"&gt;https://wiki.openstack.org/wiki/Neutron/APIv2-specification#Create_Port&lt;/a&gt;
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/APIv2-specification#Update_Port"&gt;https://wiki.openstack.org/wiki/Neutron/APIv2-specification#Update_Port&lt;/a&gt;
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/APIv2-specification#Delete_Subnet"&gt;https://wiki.openstack.org/wiki/Neutron/APIv2-specification#Delete_Subnet&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None needed beyond Neutron API v2 documentation changes listed above.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;div role="list" class="citation-list"&gt;
&lt;div class="citation" id="ref-1" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;Ref-1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id5"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id6"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id7"&gt;3&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;Neutron Blueprint: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/allow-multiple-subnets-on-gateway-port"&gt;Allow multiple subnets on gateway&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="ref-2" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;Ref-2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;RFC 4862: &lt;a class="reference external" href="http://tools.ietf.org/html/rfc4862"&gt;IPv6 Stateless Address Autoconfiguration&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="ref-3" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;Ref-3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;RFC 4861: &lt;a class="reference external" href="https://datatracker.ietf.org/doc/rfc4861"&gt;Neighbor Discovery for IP version 6 (IPv6)&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="ref-4" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;Ref-4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Neutron Blueprint: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ipv6-two-attributes"&gt;Two Attributes Proposal to Control IPv6 RA
Announcement and Address Assignment&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="ref-5" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;Ref-5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.dropbox.com/s/9bojvv9vywsz8sd/IPv6%20Two%20Modes%20v3.0.pdf"&gt;OpenStack Neutron IPv6 Address Mode Attributes Table&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;section id="related-information"&gt;
&lt;h3&gt;Related Information&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DevStack Blueprint: &lt;a class="reference external" href="https://blueprints.launchpad.net/devstack/+spec/ipv6-support"&gt;Add IPv6 support&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron Blueprint: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ipv6-provider-nets-slaac"&gt;Provider Networking - upstream SLAAC support&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RFC 4291: &lt;a class="reference external" href="http://tools.ietf.org/html/rfc4291"&gt;IP Version 6 Addressing Architecture&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Tue, 19 Dec 2017 00:00:00 </pubDate></item><item><title>Support IPv6 Prefix Delegation</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/ipv6-prefix-delegation.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ipv6-prefix-delegation"&gt;https://blueprints.launchpad.net/neutron/+spec/ipv6-prefix-delegation&lt;/a&gt;&lt;/p&gt;
&lt;dl class="field-list simple"&gt;
&lt;dt class="field-odd"&gt;Author&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-odd"&gt;&lt;p&gt;John Davidge&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class="field-even"&gt;Author&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-even"&gt;&lt;p&gt;Dane LeBlanc&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The IPv6 Prefix Delegation (PD) mechanism (described in RFC3769 &lt;a class="footnote-reference brackets" href="#id11" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;
and RFC3633 &lt;a class="footnote-reference brackets" href="#id12" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;) provides a way of automatically configuring IPv6
prefixes and addresses on routers and hosts. This mechanism can be used
in Neutron to automate the selection of IPv6 prefixes for tenants.&lt;/p&gt;
&lt;p&gt;With prefix delegation, a prefix delegating router (referred to as a
prefix delegation server, or PD server in this document) is configured with
a set of prefixes. The prefix delegation process begins when a router
acting as a prefix delegation requester (referred to as a prefix delegation
client, or PD client in this document) requests configuration information
through DHCP messages. When the PD server receives the request, it selects
an available prefix or prefixes for delegation to the PD client.&lt;/p&gt;
&lt;p&gt;It should be noted that the prefixes that are delegated by the PD server
are routable, that is, the PD server provides a downstream route to
the prefixes that have been delegated.&lt;/p&gt;
&lt;p&gt;This blueprint proposes using IPv6 Prefix Delegation to support automatic
assignment of IPv6 prefixes to tenants/subnets, using an external (outside
of the OpenStack cloud) router to delegate prefixes from a pre-configured
pool of routable prefixes.&lt;/p&gt;
&lt;p&gt;Note that it would be possible to have a PD server application that is
managed by Neutron that is running within a Neutron router namespace, and
that is configured using the IPAM Subnet Allocation API &lt;a class="footnote-reference brackets" href="#id13" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. This
support is out the scope of this blueprint, and will be covered in a
separate blueprint.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;In the current Neutron implementation, tenants must supply a prefix when
creating subnets. This is not a big deal for IPv4 private subnets, since
IP addresses on the private subnets can overlap. For IPv6 subnets that use
Global Unicast Address (GUA) format, addresses are globally routable
(unlike IPv6 Unique Local Addresses, or ULAs), so care needs to be taken
to ensure that prefixes chosen by one tenant do not overlap with prefixes
chosen by another tenant.&lt;/p&gt;
&lt;p&gt;An OpenStack administrator may want to simplify the process of subnet prefix
selection for the tenants by automatically supplying prefixes for IPv6 subnets
from one or more large pools of pre-configured IPv6 prefixes. This would also
eliminate any potential conflicts in prefix selection.&lt;/p&gt;
&lt;p&gt;The IPv6 Prefix Delegation mechanism provides a way of automatically
configuring IPv6 prefixes and addresses on routers and hosts, and can be
used in Neutron to automate the selection of IPv6 prefixes for tenants.
Prefix Delegation would also provide a pathway for adding IPv6 automatic
renumbering for IPv6 addresses in an OpenStack cloud as a future enhancement.&lt;/p&gt;
&lt;p&gt;This blueprint proposes using IPv6 Prefix Delegation to support automatic
assignment of IPv6 prefixes to tenants/subnets, using an external router
to delegate prefixes from a pre-configured pool of routable prefixes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="prefix-delegation-topology"&gt;
&lt;h3&gt;Prefix Delegation Topology&lt;/h3&gt;
&lt;p&gt;The prefix delegation topology being proposed in the blueprint is
displayed in the following diagram:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                  &lt;span class="o"&gt;+-------+-------+&lt;/span&gt;
                  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;PD&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
                  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Running&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
                  &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;external&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
                  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
                  &lt;span class="o"&gt;+-------+-------+&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;
                          &lt;span class="o"&gt;|&lt;/span&gt;
            &lt;span class="o"&gt;+-------------+--------------+&lt;/span&gt;
            &lt;span class="o"&gt;|&lt;/span&gt;                            &lt;span class="o"&gt;|&lt;/span&gt;
     &lt;span class="o"&gt;+------+-------+&lt;/span&gt;             &lt;span class="o"&gt;+------+-------+&lt;/span&gt;
     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt; &lt;span class="n"&gt;Router&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt; &lt;span class="n"&gt;Router&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Running&lt;/span&gt; &lt;span class="n"&gt;PD&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Running&lt;/span&gt; &lt;span class="n"&gt;PD&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Client&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
     &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;RADVD&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;RADVD&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
     &lt;span class="o"&gt;+------+-------+&lt;/span&gt;             &lt;span class="o"&gt;+------+-------+&lt;/span&gt;
&lt;span class="n"&gt;Router&lt;/span&gt; &lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="n"&gt;Router&lt;/span&gt; &lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
            &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt; &lt;span class="n"&gt;Prefix&lt;/span&gt; &lt;span class="c1"&gt;#1              | /64 Prefix #2&lt;/span&gt;
            &lt;span class="o"&gt;|&lt;/span&gt;                            &lt;span class="o"&gt;|&lt;/span&gt;
     &lt;span class="o"&gt;+------+------+&lt;/span&gt;               &lt;span class="o"&gt;+-----+-------+&lt;/span&gt;
     &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----+-----+&lt;/span&gt; &lt;span class="o"&gt;+-----+----+&lt;/span&gt;     &lt;span class="o"&gt;+----+-----+&lt;/span&gt; &lt;span class="o"&gt;+-----+----+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Tenant&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Tenant&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Tenant&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Tenant&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;VM&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;VM&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;VM&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;VM&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------+&lt;/span&gt; &lt;span class="o"&gt;+----------+&lt;/span&gt;     &lt;span class="o"&gt;+----------+&lt;/span&gt; &lt;span class="o"&gt;+----------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that in this topology, since the PD server is an entity outside of the
OpenStack cloud, the PD client needs to be authenticated by the PD
server (in order to prevent a rogue requester from depleting available
prefixes), and the identity of the PD server needs to be authenticated
by the PD requesters. This is described in Section 3.6 of RFC3769 &lt;a class="footnote-reference brackets" href="#id11" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The PD Client functionality could be provided by one of several open-source
utilities that support PD client, for example:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;WIDE DHCPv6 (dhcp6c)
License: BSD&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;dibbler (&lt;a class="reference external" href="http://klub.com.pl/dhcpv6/"&gt;http://klub.com.pl/dhcpv6/&lt;/a&gt;)
License: GNU GPL&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the initial implementation we have chosen to use dibbler, as it has some
important features missing in other clients which make it suitable for this
use case. A plugin framework will be included to allow the addition of other
client options in the future.&lt;/p&gt;
&lt;p&gt;A new dibbler-client will be started in the Neutron router namespace whenever a
subnet attached to that router requires prefix delegation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="detecting-when-a-prefix-has-been-allocated"&gt;
&lt;h3&gt;Detecting When a Prefix has Been Allocated&lt;/h3&gt;
&lt;p&gt;OpenStack/Neutron needs to be aware of prefix allocations as they occur. For
example, Neutron needs to update the IP allocation database with the gateway
IP address that has just been assigned to the internal router port when the
prefix delegation client is allocated a prefix.&lt;/p&gt;
&lt;p&gt;Dibbler supports the configuration of a custom script that gets executed
whenever a prefix allocation has been made. Such a custom script can provide
the necessary hook.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="workflow"&gt;
&lt;h3&gt;Workflow&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Initial Setup&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Admin configures the default_ipv6_subnet_pool configuration setting
(described in the IPAM Subnet Allocation specification, &lt;a class="footnote-reference brackets" href="#id13" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;)
in the neutron.conf configuration file to indicate that prefix
delegation should be used for the default subnet pool.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allocation of a Prefix&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;User/tenant creates an IPv6 subnet while supplying neither an address
pool nor a prefix. Normally, this indicates to the subnet pool allocation
infrastructure &lt;a class="footnote-reference brackets" href="#id13" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; that the prefix should be automatically
allocated from the default IPv6 allocation pool. However, in this case
(because of the configuration described in the Initial Setup section),
allocation for the default IPv6 allocation pool needs to be done
through prefix delegation. The subnet pool ID for this subnet
is populated with a special constant to indicate that prefix delegation is
required for this subnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User/tenant creates a Neutron router (if one does not already exist).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User/tenant attaches the IPv6 subnet to the Neutron router. This causes
a PD client application to get spawned in the Neutron router space.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For a SLAAC/DHCP-stateless subnet, the RADVD configuration is modified
with a “::/64” entry for the new router interface, and RADVD is signalled
to reconfigure itself. This new configuration indicates to RADVD that it
should monitor for an IPv6 address assignment on the new router
interface, at which time RAs can be initiated to advertise the new
prefix.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some PD delegation clients provide the capability of running a user
defined script whenever a prefix delegation has been received. If the
PD delegation client DOES NOT provide this capability, then a polling
script will be spawned at this time to periodically poll to detect
when an IPv6 address has been configured on the internal router interface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The configuration of the PD delegation client is modified to initiate
a PD request for the new router interface, and the PD delegation
client is signalled to reconfigure itself, or initialise a new instance
of itself where dynamic reconfiguration is not available.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The PD delegating server receives the PD request, selects an available
prefix from its block of prefixes, and sends back a
PD response back to the PD delegation client, indicating the prefix
to be used.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The PD delegating client assigns an address to the router interface
from the delegated prefix.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the PD delegating client provides the capability of running a user
defined script whenever a prefix has been delegated, then that script
will be run to update the OpenStack databases for the subnet’s new prefix.
Otherwise, the polling script will eventually detect the assignment of
the new IPv6 address to the router interface, and it will update
the OpenStack databases for the new prefix.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For SLAAC or DHCP-stateless subnets, RADVD will assign IPv6 addresses
from the delegated prefix as new ports are created on the subnet.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="limitations-and-future-enhancements"&gt;
&lt;h3&gt;Limitations and Future Enhancements&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Only /64 prefixes will be delegated in initial release (no sub-delegating).
Sub-delegation of short prefixes (large address space) into longer
prefixes by Neutron routers could be added as a future enhancement.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Only a single pool of /64 prefixes will be supported by the PD server
in the initial release. Support of multiple pools of prefixes can
be added in a future release (e.g. to add support of per-tenant prefix
pools).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Limits on the number of prefixes that each tenant is allowed to use
at any time will be maintained using the OpenStack/Neutron subnet quota.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prefix delegation will be limited to SLAAC and DHCPv6-stateless subnets
for this proposal.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If an OpenStack provider is upgrading an OpenStack instance from a version
of Neutron that does not support automatic prefix delegation to a version
of Neutron that does, no additional migration will be required.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If an OpenStack provider is upgrading an OpenStack instance from a version
of Neutron that supports automatic prefix delegation to a newer version,
then a migration script might be required to re-trigger delegation
requests for all existing automatic-prefix subnets, effectively causing
a renumbering.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;As described in the Subnet Pool Allocation specification &lt;a class="footnote-reference brackets" href="#id13" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, the
subnet create API will need to allow for the absence of both subnet
prefix and subnet pool ID. Normally, this indicates to Neutron (and the
subnet pool allocation infrastructure) that the prefix for this subnet
should be allocated from a default allocation pool configured for that IP
family. When prefix delegation is configured (see “Initial Setup” above),
however, it is understood that the allocation of IPv6 prefixes in this case
should be done through prefix delegation. In this case, the subnet pool ID
is populated with special constant to mark subnets as requiring prefix
delegation.&lt;/p&gt;
&lt;p&gt;As described in the “Allocation of a Prefix” section, the prefix allocation
process will then get triggered after a subnet that is marked for prefix
delegation (i.e. subnet pool ID is populated with the special prefix
delegation constant) is attached to a router.&lt;/p&gt;
&lt;p&gt;While the subnet is awaiting assignment of a prefix via prefix delegation,
the response for the subnet-list and subnet-show API/CLI will list the cidr
and allocation_pools for the subnet using a temporary ::/64 prefix.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;When the PD server is an entity outside of the OpenStack cloud (e.g. an
ISP edge router), then the  PD client needs to be authenticated by the PD
server (in order to prevent a rogue requester from depleting available
prefixes), and the identity of the PD server needs to be authenticated
by the PD requesters. This is described in Section 3.6 of RFC3769 &lt;a class="footnote-reference brackets" href="#id11" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Limits on the number of prefixes that each tenant is allowed to use
at any time will be maintained using OpenStack/Neutron subnet quota.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;Horizon will need to be updated to support this feature for subnet creation.
This Horizon work can be done as part of the changes being made to support
subnet allocation pools.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;If the PD client does not provide for either asynchronous notification for
the allocation of each prefix, or the configuration of a custom script that
is called upon allocation of prefixes, then a polling script will need to be
spawned whenever a subnet is created that requires prefix delegation.
The extent that these polling scripts have on performance would depend on
the scale of subnets that are being created at any point in time, but it
shouldn’t be too significant if the polling interval is a few seconds
or more.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;Yes, this change will modify the Neutron IPv6 implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Deployers wishing to use prefix delegation would need to configure an
external router to act as a PD server, and will need to configure a
pool of available IPv6 prefixes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;It may be worth considering adding a mechanism to the pluggable IPAM
infrastructure that would allow for a feature such as prefix delegation
to report prefixes that have been delegated. This would mainly be for
informational purposes, e.g. for displaying what prefixes have been
delegated through prefix delegation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This feature is complementary to the IPAM Subnet Allocation feature
&lt;a class="footnote-reference brackets" href="#id13" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. This implementation could be expanded in the future to support
an internal (Neutron-managed) PD server, and thereby used as part of the
underlying implementation for the IPv6 portion of the IPAM Subnet
Allocation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Instead of using the default_ipv6_subnet_pool Neutron configuration to
indicate that prefix delegation should be used whenever a subnet create
request is made with neither a subnet prefix nor subnet pool ID, a boolean
attribute could be added to the subnet create API to indicate that
prefix delegation should be used for this subnet. The advantage to such an
API change would be that the user would be able to select between prefix
delegation and a default allocation pool on a per-subnet basis. However,
this benefit probably doesn’t outweigh the cost of adding yet another
attribute to the API.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Dane LeBlanc
launchpad-id: leblancd&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;John Davidge
launchpad-id: john-davidge
Robert (Bao) Li
launchpad-id: baoli&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement PD client configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Coding/UT for subnet-create and router-interface-add&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Coding/UT for subnet-delete and router-interface-delete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write Functional tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write Tempest tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;The change in behavior for the subnet create API described in this proposal
will need to build off changes in that API that will be made for IPAM
Subnet Allocation &lt;a class="footnote-reference brackets" href="#id13" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;In order to test functionality with an external router serving as the
PD server, a third party CI system will be needed that incorporates
a router that supports prefix delegation. The Tempest test to run on this
third party CI system would be:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Configure the external router for prefix delegation service and
configure a block of IPv6 prefixes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create Neutron virtual routers for 2 separate tenants&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a subnet for each tenant, confirm subnet allocated for each
from the PD server’s block of prefixes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Since this feature depends upon a PD server that is running outside of
OpenStack, this feature will require a functional test that runs an
open-source PD server application in a neutron namespace, configured
with a pool of IPv6 prefixes. After the PD server application is running,
the test sequence would be similar to the sequence described in the
previous section.&lt;/p&gt;
&lt;p&gt;PD server applications that can be considered for this testing include:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;ISC DHCP server running in V6 mode
License: ISC license
(&lt;a class="reference external" href="http://www.isc.org/downloads/software-support-policy/isc-license/"&gt;http://www.isc.org/downloads/software-support-policy/isc-license/&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;dibbler (&lt;a class="reference external" href="http://klub.com.pl/dhcpv6/"&gt;http://klub.com.pl/dhcpv6/&lt;/a&gt;)
License: GNU GPL (should be evaluated to see if appropriate for OpenStack)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;This feature will require an API test for testing subnet create API with
neither prefix nor allocation pool ID specified.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Minor document changes will be required to reflect the configuration
of the default IPv6 subnet pool for prefix delegation.&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Specify any User Documentation which needs to be changed. Reference the guides
which need updating due to this change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;The Neutron API docs will need updating to reflect API behavior changes
for subnet create.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id11" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id4"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id8"&gt;3&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;RFC 3769: &lt;a class="reference external" href="http://tools.ietf.org/html/rfc3769"&gt;Requirements for IPv6 Prefix Delegation&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;RFC 3633: &lt;a class="reference external" href="http://tools.ietf.org/html/rfc3633"&gt;IPv6 Prefix Options for Dynamic Host Configuration
Protocol (DHCP) version 6&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id13" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id3"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id5"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id6"&gt;3&lt;/a&gt;,&lt;a role="doc-backlink" href="#id7"&gt;4&lt;/a&gt;,&lt;a role="doc-backlink" href="#id9"&gt;5&lt;/a&gt;,&lt;a role="doc-backlink" href="#id10"&gt;6&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;Neutron Blueprint: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/subnet-allocation"&gt;Add support for subnet allocation&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;section id="related-information"&gt;
&lt;h3&gt;Related Information&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;RFC 4862: &lt;a class="reference external" href="http://tools.ietf.org/html/rfc4862"&gt;IPv6 Stateless Address Autoconfiguration&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RFC 4861: &lt;a class="reference external" href="https://datatracker.ietf.org/doc/rfc4861"&gt;Neighbor Discovery for IP version 6 (IPv6)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RFC 4291: &lt;a class="reference external" href="http://tools.ietf.org/html/rfc4291"&gt;IP Version 6 Addressing Architecture&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Tue, 19 Dec 2017 00:00:00 </pubDate></item><item><title>Porting the Neutron Core to Python 3</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/neutron-python3.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-python3"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-python3&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Neutron currently only works with Python 2.x. As some OpenStack projects now
work with Python 3 (most of the Python clients, some of the oslo libraries…),
and since OpenStack should move to Python 3 &lt;a class="footnote-reference brackets" href="#id3" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, Neutron shall be ported to
Python 3.4.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This specification details the steps needed to port Neutron core to Python 3.&lt;/p&gt;
&lt;p&gt;The goal here is only to be able to run all the unit tests with Python 3.4.
This may not be enough to make sure that Neutron is fully compatible with
Python 3.4: we will also need to run Neutron in a devstack that uses Python
3.x, but this is another issue.&lt;/p&gt;
&lt;p&gt;Obviously, these changes must not break any of Neutron’s reverse dependencies.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;If deployers want to run services under Python 3, they should install Python 3
with the whole stack. There will not be any differences for those who want
to stick to Python 2, as we will make sure not to break anything.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Once Neutron has been ported to Python 3, developers will not able to write
code that only works with Python 2, since the py34 gate will be voting.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;cyril-roelandt&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Fix issues with the dependencies that are not Python 3 compatible: see the
“Dependencies” section.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure “tox -epy34” only runs tests that are specifically listed in
tox.ini.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable the py34 gate in Neutron and make it voting. We should now be able to
avoid regressions while working.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fix the most obvious issues (print statements, failing imports, …) that can
probably be caught by 2to3. Checks for these might be added to
tools/misc-sanity-checks.sh to avoid regressions. Once the py34 is voting and
all the unit tests pass on Python 3, we will be able to remove them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fix all the tests, one by one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once they all work, remove the explicit list of tests to run when using
Python 3 from tox.ini and add py34 to the default env list.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Neutron has dependencies on packages that currently do not work with Python 3:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;oslo.db: Works with Python 3.4, even though we need a new release. The only
issue is MySQL-Python which is not Python 3 compatible yet, but one can
use mysqlclient as a drop-in replacement (MySQL-Python + py3 support +
fixes).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;olso.messaging: Thanks to the work of Victor Stinner, the RabbitMQ and ZMQ
drivers and all the executors work on Python 3. Only the Qpid and AMQP 1.0
drivers don’t work on Python 3, but it should not block porting Neutron to
Python 3. Currently, this work can only be found in the git repository, but a
Python3-compliant version should be released in a near future.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All in all, there is probably no major issue with the dependencies.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Developers might be interested in reading the official Python 3 page on the
Openstack wiki &lt;a class="footnote-reference brackets" href="#id4" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. It shows the current progress and details some common
issues that arise when porting code to Python 3.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://techs.enovance.com/6521/openstack_python3"&gt;http://techs.enovance.com/6521/openstack_python3&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Python3"&gt;https://wiki.openstack.org/wiki/Python3&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 19 Dec 2017 00:00:00 </pubDate></item><item><title>Online Schema Migrations</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/online-schema-migrations.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/online-schema-migrations"&gt;https://blueprints.launchpad.net/neutron/+spec/online-schema-migrations&lt;/a&gt;&lt;/p&gt;
&lt;dl class="field-list simple"&gt;
&lt;dt class="field-odd"&gt;Author&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-odd"&gt;&lt;p&gt;Mike Bayer &amp;lt;&lt;a class="reference external" href="mailto:mike.bayer%40redhat.com"&gt;mike&lt;span&gt;.&lt;/span&gt;bayer&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;This specification discusses the issue of database schema migrations which
may proceed while allowing both the previous and the updated version of the
Neutron database API to run against that schema at the same time.  This is
part of a larger approach which is to allow a Neutron application to
be upgraded to a new version without incurring downtime while the database
schema is migrated.&lt;/p&gt;
&lt;p&gt;To achieve this goal fully, several areas must be addressed:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The first is that database schema migrations can be applied which
don’t impact the old version of the software as it runs.  These migrations
are referred to as &lt;strong&gt;expansive&lt;/strong&gt; migrations, which only add new elements,
never removing any.  Once the old software has been entirely replaced
with the new version, a second series of migrations known as the &lt;strong&gt;contract&lt;/strong&gt;
migrations are run separately; these migrations remove the old elements
that are no longer used.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The newer version of the software must also be prepared to accommodate
for the fact that the old version of the software may still be running
as well, meaning it may need to read and persist data from both the old
and new schema structures simultaneously.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Within the scope of the new software referring to both versions of the
schema, a strategy for data migrations must be devised.  These migrations
can run over time as a function of the data access code itself slowly
moving data to the new format, or can run as separate scripts or processes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The sequence of movements between expand/contract, old and new software
versions, and migration of data must also be orchestrated fully.
Front-end RPC clients and database access services are typically upgraded
independently of each other, and additionally at which point “contract” is safe to run must
be established.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This blueprint is primarily concerned with only the &lt;strong&gt;first&lt;/strong&gt; bulletpoint,
that of organizing schema migrations such that those which are strictly
“expansive” may be run separately from those which are “contractual”.
The other bullets above will need to be considered separately.&lt;/p&gt;
&lt;p&gt;Note that an approach to the problem addressed here has already been
accepted for Nova, also called “online schema migrations”.   The
specification here builds upon the work of Nova’s, proposing
essentially the same concept, but implemented slightly differently,
in such a way that there is no
sharp break from Neutron’s existing system of using Alembic migration
scripts, and does not abandon the use of version identifiers which
identify an explicit, known state of the schema.   There is also
a proposal for upstream changes in Alembic so that both Nova’s “live”
approach and the “scripted” approach here can share the same codebase
against a revised Alembic autogeneration API that allows much greater
extensibility.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Database migrations of Neutron and other Openstack applications traditionally
involve the replacement of some version of the schema with another one;
tables and columns are dropped, new ones added.   This change
necessarily involves that the software which communicates with the schema
must also change at the same time, where the old version is shut down
completely before beginning the migration, the migration then proceeds fully
offline, and then the new version is started.   In terms of a multiple-node
Openstack deployment, this means that the entire application
on all nodes must be fully shut down and upgraded globally all at once.
The offline migration may also be time consuming in terms of what kinds of
operations are present and what target database is in use.&lt;/p&gt;
&lt;p&gt;The business requirements of many key Openstack consumers is such that
the downtime involved with fully upgrading all nodes simultaneously as
well as running full schema migrations during that downtime is no
longer acceptable; a new approach that allows the application to keep
running while the migration goes on must be developed, in particular
for key Openstack components such as Nova, Neutron, and Cinder.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Within this document we will address the goal of organizing schema
migrations into “expand” and “contract” phases that are also linked to
major release versions.   The phases are as follows:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Migrations that run under “expand” are “additive” (e.g. tables,
columns,  indexes and constraints are only created, not dropped)
only, and are safe to run while the old version of the application
continues to run.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Migrations that run under “contract” are “subtractive” (e.g. tables,
columns, indexes and constraints are only dropped, not created) and
only run once software running on all nodes communicates exclusively
with the new version of the schema, and all data has been migrated.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The steps involved in each of the two phases will be rendered as
explicit migration directives within Alembic migration scripts, as is
already the case for Neutron.  The only difference will be that a
given migration will be broken out into individual scripts for each
phase of operation that the migration includes.   These scripts will
be assembled into semi-independent lineages that can be run
separately.  These lineages will also be classified among release
versions, so that migration lineages will be targetable at the level
of both release and phase, e.g.  “expand liberty”,  “contract M”, etc.&lt;/p&gt;
&lt;p&gt;The new scheme is supported by Alembic’s  recently added support for
long-lived branches, roots, branch names, and individual file
directories.   The workflow can be implemented at a proof-of-concept
level without writing any new code,  by creating the new directory
structure and manually assembling new migration files into the
appropriate branches using Alembic’s updated command line tools.&lt;/p&gt;
&lt;p&gt;However, in order to facilitate the use of Alembic autogenerate, new
features will be added upstream to Alembic’s autogenerate API which
will allow for the creation of custom autogenerate behaviors and
filesystem flows.  We will build a new tool that adapts Nova’s current
online schema migrations logic to this new API such that the logic
used to group migrations into “expand”  and “contract” steps may now
stream those instructions into individual migration files, targeted
into the file structure referred to above.  It is  hoped that this
same tool will also be able to continue to send migration directives
directly to a database as well, thus allowing Nova’s current “live”
approach to be rolled into the same codebase.  Improvements and
behavioral contracts for the “expand” / “contract” workflow system
will apply both to the “live” and “scripted” approaches, thus making
the two approaches that much more interchangeable.&lt;/p&gt;
&lt;section id="alembic-migrations"&gt;
&lt;h3&gt;Alembic Migrations&lt;/h3&gt;
&lt;p&gt;Right now, Neutron makes use of Alembic migrations, which involves a
series of migration scripts organized into the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron/db/migration/alembic_migrations/versions&lt;/span&gt;&lt;/code&gt; directory.  These
scripts are organized into a kind of backwards linked list structure,
where each script is identified by a six-byte hash scheme, and
contains a variable that links it to the &lt;em&gt;previous&lt;/em&gt; hash in the
series.   The rationale for this linked structure is that new versions
can be inserted into the middle of the chain without impacting more
than one existing migration file; by using a “backwards” linking
model, and new versions can be added to the end of the list without
impacting any existing versions.&lt;/p&gt;
&lt;p&gt;Recent versions of Alembic have been enhanced to reconsider this
“backwards linked list” structure as just a specialization of a more flexible
structure, the directed acyclic graph, or DAG.   In this approach, we
remove the requirement that each migration script can only refer to a single
anscestor (e.g. dependency), as well as the requirement that only one
migration script can refer to a particular ancestor.   The structure basically
becomes open to the concepts of branching and merging which are very
familiar in version control systems.   Alembic now has the ability to
run upgrades or downgrades along individual branches which are tracked
individually within a database schema, meaning a schema’s “head” version
may be in fact a series of hashes, each representing the “head” of an
individual revision stream.  The branches can optionally originate from entirely
independent root revisions with no dependencies on each other, and can
also be organized into individual subdirectories.   Revisions within
branches can also refer to specific revisions within other branches as
dependencies, and branches may be merged back together into a single
revision stream.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="expand-and-contract-scripts"&gt;
&lt;h3&gt;Expand and Contract Scripts&lt;/h3&gt;
&lt;p&gt;The current design of a migration script includes that it indicates
a specific “version” of the schema, and includes directives that apply
all necessary changes to the database at once.  If we look for example
at the script &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;2d2a8a565438_hierarchical_binding.py&lt;/span&gt;&lt;/code&gt;, we will see:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;# .../alembic_migrations/versions/2d2a8a565438_hierarchical_binding.py&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;upgrade&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="c1"&gt;# .. inspection code ...&lt;/span&gt;

    &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s1"&gt;'ml2_port_binding_levels'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'port_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'host'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="c1"&gt;# ... more columns ...&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;port_binding_tables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;
            &lt;span class="s2"&gt;"INSERT INTO ml2_port_binding_levels "&lt;/span&gt;
            &lt;span class="s2"&gt;"SELECT port_id, host, 0 AS level, driver, segment AS segment_id "&lt;/span&gt;
            &lt;span class="s2"&gt;"FROM &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt; "&lt;/span&gt;
            &lt;span class="s2"&gt;"WHERE host &amp;lt;&amp;gt; '' "&lt;/span&gt;
            &lt;span class="s2"&gt;"AND driver &amp;lt;&amp;gt; '';"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drop_constraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fk_name_dvr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s1"&gt;'ml2_dvr_port_bindings'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'foreignkey'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drop_column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ml2_dvr_port_bindings'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'cap_port_filter'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drop_column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ml2_dvr_port_bindings'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'segment'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drop_column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ml2_dvr_port_bindings'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'driver'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# ... more DROP instructions ...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The above script contains directives that are both under the “expand”
and “contract” categories, as well as some data migrations.  the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;op.create_table&lt;/span&gt;&lt;/code&gt;
directive is an “expand”; it may be run safely while the old version of the
application still runs, as the old code simply doesn’t look for this table.
The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;op.drop_constraint&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;op.drop_column&lt;/span&gt;&lt;/code&gt; directives are
“contract” directives (the drop column moreso than the drop constraint); running
at least the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;op.drop_column&lt;/span&gt;&lt;/code&gt; directives means that the old version of the
application will fail, as it will attempt to access these columns which no longer
exist.&lt;/p&gt;
&lt;p&gt;The data migrations in this script are adding new
rows to the newly added &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ml2_port_binding_levels&lt;/span&gt;&lt;/code&gt; table.   Data migrations
may or may not be “safe” to run within the “expand” or “contract” phase,
depending on the nature of the data.  It is expected that most data migrations
will run outside of migration scripts going forward, and instead be implemented
as part of the model/API layer as the application runs.&lt;/p&gt;
&lt;p&gt;Note that this spec suggests, but not requires Neutron to move to live
data migrations implemented in the application instead of migration
scripts. This part will require a separate consideration and is out of
scope for the spec.&lt;/p&gt;
&lt;p&gt;Under the proposed plan, the above script, assuming it were added as part
of the new architecture, would be stated as two scripts; an “expand” and a
“contract” script:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;# expansion operations&lt;/span&gt;
&lt;span class="c1"&gt;# .../alembic_migrations/versions/liberty/expand/2bde560fc638_hierarchical_binding.py&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;upgrade&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s1"&gt;'ml2_port_binding_levels'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'port_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'host'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="c1"&gt;# ... more columns ...&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;# contraction operations&lt;/span&gt;
&lt;span class="c1"&gt;# .../alembic_migrations/versions/liberty/contract/4405aedc050e_hierarchical_binding.py&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;upgrade&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drop_constraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fk_name_dvr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s1"&gt;'ml2_dvr_port_bindings'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'foreignkey'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drop_column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ml2_dvr_port_bindings'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'cap_port_filter'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drop_column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ml2_dvr_port_bindings'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'segment'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drop_column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ml2_dvr_port_bindings'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'driver'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# ... more DROP instructions ...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The two scripts would be present in different subdirectories and also
part of entirely separate versioning streams, discussed in the section
below “New Migration Layout”.  The “expand” operations are in the
“expand” script, and the “contract” operations are in the “contract”
script.&lt;/p&gt;
&lt;p&gt;The data migrations are removed, as these are expected to
generally not occur within schema migrations any more.  However,
the approach remains compatible with allowing “safe” data migrations to be
manually placed within the expand or contract scripts if deemed appropriate
in some cases.&lt;/p&gt;
&lt;p&gt;For the time being, until live data migration is accepted in Neutron, data
migration rules belong to one of script subtrees.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="new-migration-layout"&gt;
&lt;h3&gt;New Migration Layout&lt;/h3&gt;
&lt;p&gt;With Alembic’s new capabilities, we can propose a new structure for
Neutron’s migration files that is compatible with “expand” / “contract”
while at the same time remains compatible with the existing stream
of Alembic migration files in Neutron.   A new directory/branch
structure will be laid out which allows all versions/streams to be apparent:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;migration&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;alembic_migrations&lt;/span&gt;&lt;span class="o"&gt;/...&lt;/span&gt;

&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
             &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;existing&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
             &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;existing&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
             &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;existing&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
             &lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;liberty&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;liberty&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;expand&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
                                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;expansion&lt;/span&gt; &lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
                                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;expansion&lt;/span&gt; &lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
                                &lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;liberty&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
                                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
                                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
                                &lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;M_release&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;M_release&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;expand&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;M_release&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="n"&gt;etc&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Above, the existing /versions/ directory with all of its current migration
scripts remains intact; these versions are still the scripts that take a
Neutron database up through Kilo at least.  Following those, a new
series of subdirectories are added, organized among major Openstack releases,
and within each subdirectory, the “expand” and “contract” series of scripts
are themselves separate.&lt;/p&gt;
&lt;p&gt;The series of scripts within &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/expand/&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/contract/&lt;/span&gt;&lt;/code&gt; are
themselves originating from independent “roots”; that is, the “down”
revision for the bottommost script in each directory is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;None&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The production of these scripts is supported by the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;alembic&lt;/span&gt; &lt;span class="pre"&gt;revision&lt;/span&gt;&lt;/code&gt; command,
which now includes options to place files in specific directories as well
as what the “down revision” of a given revision is to be, including
that it may be a “root”, thus allowing the creation of new branches
and roots.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="cross-branch-dependencies"&gt;
&lt;h3&gt;Cross-Branch Dependencies&lt;/h3&gt;
&lt;p&gt;To accommodate for the fact that the scripts in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;liberty/expand&lt;/span&gt;&lt;/code&gt;
can’t be run until all the old scripts in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;versions/&lt;/span&gt;&lt;/code&gt; have run, as
well as that individual scripts in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;liberty/contract/&lt;/span&gt;&lt;/code&gt; can’t run until
their correpsonding “expand” has run, Alembic’s cross-branch dependency
feature will be used.   From a DAG point of view, this is the same as a script
declaring another one as a dependency, but from Alembic’s perspective the
script is not considered to be any kind of “down revision”; only a script
whose version must be invoked within the target schema before the current
one can be run.   They are indicated in Alembic scripts as a separate directive:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;# revision identifiers, used by Alembic.&lt;/span&gt;
&lt;span class="n"&gt;revision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2a95102259be'&lt;/span&gt;
&lt;span class="n"&gt;down_revision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'29f859a13ea'&lt;/span&gt;
&lt;span class="n"&gt;branch_labels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;span class="n"&gt;depends_on&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'55af2cb1c267'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'4fcb78af5a01'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;By establishing “depends_on”, a particular script indicates what migration
scripts in other branches need to be run first, before this one can.
When we instruct Alembic to invoke this migration, it will ensure that
all dependency scripts are run first.   It is expected that
the automated script creation tool will be able to build out these
directives automatically.&lt;/p&gt;
&lt;p&gt;Alembic branch dependencies are discussed in the Alembic documentation
referred to in the References section.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="branch-labels"&gt;
&lt;h3&gt;Branch Labels&lt;/h3&gt;
&lt;p&gt;Alembic also now provides for “branch labels”, meaning that in addition
to having our migration files in different directories, versioned across
independent branches with independent roots, we can also apply one or
more “labels” to a branch as a whole which is then addressable using Alembic’s
command line tools.
Whereas in Neutron today we can see some migration scripts that are intentionally
named &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;juno_release.py&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;kilo_release.py&lt;/span&gt;&lt;/code&gt;, we can apply these names
to the branches as a whole.    Like branch dependencies, these are also
indicated as directives within migration scripts; however, the branch
label only need be present in &lt;em&gt;any&lt;/em&gt; single revision script within the
branch.  Typically, the first script within the branch is a good
choice for placing a label:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;# revision identifiers, used by Alembic.&lt;/span&gt;
&lt;span class="n"&gt;revision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2a95102259be'&lt;/span&gt;
&lt;span class="n"&gt;down_revision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;  &lt;span class="c1"&gt;# because we are a "root"&lt;/span&gt;
&lt;span class="n"&gt;branch_labels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'liberty_expand'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'release_expand'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;depends_on&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'55af2cb1c267'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;So above, we would apply names such as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;"liberty_expand"&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;"liberty_contract"&lt;/span&gt;&lt;/code&gt; to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;liberty/expand&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;liberty/contract&lt;/span&gt;&lt;/code&gt; branches,
appropriately.  This allows Alembic commands to be run which refer to the
branch as a whole, such as:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;alembic&lt;/span&gt; &lt;span class="n"&gt;upgrade&lt;/span&gt; &lt;span class="n"&gt;liberty_expand&lt;/span&gt;&lt;span class="nd"&gt;@head&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Where above, all migrations up until the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;liberty_expand&lt;/span&gt;&lt;/code&gt; branch will
be run (including dependent versions from the old series of migration
files first, if not already run).   This will allow Neutron’s command suite
to accommodate specific target points within the new versioning scheme
without the need to become aware of specific revisions.&lt;/p&gt;
&lt;p&gt;If labels that are agnostic of “release” are desired, such as a branch
that indicates “run all the expand steps up to the current release”, we
can add additional “latest release” labels that move to new branches
as new releases are established.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="new-neutron-db-commands"&gt;
&lt;h3&gt;New Neutron DB Commands&lt;/h3&gt;
&lt;p&gt;Right now, Neutron allows database upgrades running the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron-db-manage&lt;/span&gt;&lt;/code&gt;
script, which links into Alembic’s own &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;upgrade&lt;/span&gt;&lt;/code&gt; command.   This script
will be enhanced to allow for running individual migration streams by taking
advantage of new argument forms that are part of Alembic.  The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;alembic&lt;/span&gt; &lt;span class="pre"&gt;upgrade&lt;/span&gt;&lt;/code&gt;
command will still be used but will now be passed the appropriate branch
labels specific to the target operation, such as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron-db-manage&lt;/span&gt; &lt;span class="pre"&gt;expand&lt;/span&gt;&lt;/code&gt;
or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron-db-manage&lt;/span&gt; &lt;span class="pre"&gt;contract&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="automation-of-scripting"&gt;
&lt;h3&gt;Automation of Scripting&lt;/h3&gt;
&lt;p&gt;The previous sections essentially make possible the entire “expand” / “contract”
workflow completely, in such a way that workflow from Neutron’s existing
Alembic versioning scripts is maintained without any backwards incompatibility.
However, the addition of new migration scripts would at first be available
only by manually targeting each portion of the workflow individually.&lt;/p&gt;
&lt;p&gt;We instead can enhance Neutron’s use of Alembic “autogenerate” such
that a single revision autogenerate step can produce multiple files as
needed; a migration that includes both “expand” and “contract”
directives would generate two separate scripts.&lt;/p&gt;
&lt;p&gt;Right now, Nova OSM makes use of Alembic autogenerate in order to derive
information about how a target database differs from the model established
in code.  It uses a public method &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;compare_metadata()&lt;/span&gt;&lt;/code&gt; to achieve this;
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;compare_metadata()&lt;/span&gt;&lt;/code&gt; returns a simple list of “diffs” which refer to changes
in schema objects like tables, columns, and constraints.  Nova OSM then
keys “operational” objects such as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;AddTable&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DropColumn&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;AddConstraint&lt;/span&gt;&lt;/code&gt;,
etc.  These “operational” objects then link back into Alembic’s API,
associated with corresponding “operation” constructs in Alembic such
as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;op.create_table()&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;op.drop_column()&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;op.add_constraint()&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Nova’s OSM is basically consuming an Alembic “autogenerate diff” stream
and streaming it into an Alembic “run operations” stream.   It follows that
Alembic can provide infrastructure such that an autogenerate
diff stream can be supplied directly as a migration operation stream.
Both the “live” OSM approach of Nova and the “scripted” approach
proposed here can consume this same operation stream, partition it
based on operation type into “expand” and “contract” streams, and then
direct those streams either to a live database context for “live” migrations
&lt;em&gt;or&lt;/em&gt; to a series of migration scripts for scripted migrations.&lt;/p&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;alembic&lt;/span&gt; &lt;span class="pre"&gt;revision&lt;/span&gt;&lt;/code&gt; command will also be opened up such that a plugin
may establish an open-ended series of revision scripts generated from
portions of these operational streams.   The end result will be that
a single call to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;alembic&lt;/span&gt; &lt;span class="pre"&gt;revision&lt;/span&gt; &lt;span class="pre"&gt;--autogenerate&lt;/span&gt;&lt;/code&gt; as performed by
Neutron developers today will generate separate “expand” and “contract” scripts
directly.&lt;/p&gt;
&lt;p&gt;These new APIs are already  underway in upstream development branches and are
tracked by separate Alembic issues (see References).  By closely linking the
implementations for “live” migrations and “scripted”
migrations, it is hoped that the majority of ongoing effort within OSM
can contribute to both approaches simultaneously, thus reducing the risk
that work is wasted either if one or the other approach is abandoned
or that improvements and workflows begin to diverge if both approaches
remain in active use.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;Expand/contract workflow itself has no direct impact on the data model.   The
other aspects of online schema migrations, namely support of multiple
versions of a schema simultanouesly as well as moving data between those
structures at runtime have an enormous impact; however, that’s outside the
scope of this document.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;End users will be using a modified workflow when schema upgrades
are performed, running “expand” and “contract” steps separately and
at the appropriate time.&lt;/p&gt;
&lt;p&gt;In terms of backup procedures, there is no difference. Database always
represents some specific subset of head revisions (the only difference
between the proposed feature and the current state is that the subset
has more than one element).&lt;/p&gt;
&lt;p&gt;If/once we adopt live data migration in Neutron, it won’t change a lot
in terms of database backups either way. The only significant thing is
that the same logical object could now be represented by multiple
versions of database rows, depending on whether migration for the
object is complete. Anyway, backups would still work as usual.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Developers should continue to use &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;alembic&lt;/span&gt; &lt;span class="pre"&gt;revision&lt;/span&gt; &lt;span class="pre"&gt;--autogenerate&lt;/span&gt;&lt;/code&gt;
in order to create new migration scripts.  This operation will create
multiple scripts, so to the degree that developers need to manually
tune these scripts, they’ll be dealing with more than one script.  Since
data migrations will generally no longer be within these scripts, and
also since we now have the ability to render custom directives via
autogenerate, it is hoped that pretty much anything Nova’s “live” OSM
approach can automate can also be completely automatic within the
“scripted” approach as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Live migrations were originally proposed as a replacement for
SQLAlchemy-Migrate, which has the additional issues of a very rigid
and unworkable numbering scheme as well as verbose migration scripts
that rely heavily on full table declarations and reflection.  These
are not issues for projects that already use Alembic, as Alembic was
designed to solve these problems among others.&lt;/p&gt;
&lt;p&gt;Live migration also offers the advantages that no script
at all needs to be generated or committed into the source repository,
and also that because there is literally no way to alter how
migrations will proceed on a per-change basis, developers are not
given any opportunity to inadvertently produce a migration that is
non-expansive or to inappropriately write statements in a migration
that result in performing a data migration.  This is noted
as allowing a “purely declarative” approach to migrations, where the
model code is all that’s needed to indicate how to get to the new
schema.&lt;/p&gt;
&lt;p&gt;However, this advantage only works under limited circumstances. While
simple cases are easily automated by both approaches, the issue of
accommodating for special cases, unsupported features, and variability
in support and/or reliability on various backends is not addressed
by the “live” approach. Live migrations only offers in such cases that
the upstream migration system must be modified to accommodate for the
target case, or the application must be modified to no longer require
such a schema migration. Special cases include changes to complex
types like ENUMs and precision numerics, operations involving CHECK
constraints and some kinds of server defaults, special constructs such
as indexes that use vendor-specific extensions, and even simple
things like changes of table or column name that can’t be
distinguished from an add/drop of two separate objects.&lt;/p&gt;
&lt;p&gt;The availability and reliability of the reflection and autogenerate
features on backends is not necessarily consistent, nor can the
Alembic / SQLAlchemy projects make any such guarantee. In particular,
less common backends such as that of IBM DB2, which is published
independently of SQLAlchemy or Alembic, may not support some
operations correctly at all, and it is not currently known to what
extent autogenerate and reflection produce accurate results,
especially in thorny cases such as indexes, unique constraints, and
column types.  Alembic’s autogenerate feature was not intended to be
used in the way that live migrations does, and it’s a risky assumption
that it will produce correct results perfectly under all cases on
thousands of production systems.&lt;/p&gt;
&lt;p&gt;While the “scripted” OSM approach maintains reliance upon explicit migration
scripts that must be checked in and occasionally edited, the advantage to this
approach is that the sequence of migration steps to be run are produced
just once, up front, in a controlled environment.  Unusual migrations against
special types or other constructs are again a non-issue as they can be
scripted explicitly as needed.  These steps can then be
carefully reviewed and tested by developers and then shipped, where there
is no risk of them doing something entirely different when run against
a backend of a lesser-used vendor or with unusual configurations.  They
also maintain the advantage that operator-maintained schema
structures are unaffected; the “live” approach documents that operators
would need to re-create their own schema structures after a “contract” is run.&lt;/p&gt;
&lt;p&gt;In order to maintain that scripted migrations stay appropriately
expansive / contractual and without inappropriate data migrations in
the face of developer intervention, we should require that developers
use the autogenerated migration scripts that are generated for them as
is, and that they don’t modify these scripts except to support
operations that aren’t supported as automatable migrations.  Schema
migrations should be tested as part of the CI process including that
the “online upgrades” are tested against previous API versions, and
migration scripts of course go through the usual Gerrit code review
process; identifying migrations that are non-expansive or are data
migrations is not difficult.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Mike Bayer&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Ann Kamyshnikova
Henry Gessau
Ihar Hrachyshka&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;update neutron-db-manage to support upgrade for multiple heads.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update neutron-db-manage revision to generate multiple scripts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get alembic updated to include update stream generated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;use the alembic autogenerate feature to filter operations into subtrees.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;implement new expand/contract neutron-db-manage commands.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;document the change in the upgrade flow in user and developer docs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;introduce testing for expand-only schema upgrade.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Upstream changes to Alembic for the autogenerate integration aspect.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Functional tests should include that “expand” migrations are run and that
the previous version of the API still works fully against an expanded
migration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Expand/contract workflow will need to be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Usage of autogenerate along with expand/contract workflow can be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Alembic’s Branching Model
&lt;a class="reference external" href="http://alembic.readthedocs.org/en/latest/branches.html"&gt;http://alembic.readthedocs.org/en/latest/branches.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Online Schema Migrations in Nova
&lt;a class="reference external" href="http://specs.openstack.org/openstack/nova-specs/specs/liberty/approved/online-schema-changes.html"&gt;http://specs.openstack.org/openstack/nova-specs/specs/liberty/approved/online-schema-changes.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nova’s Overall Online Upgrade approach
&lt;a class="reference external" href="http://docs.openstack.org/developer/nova/devref/upgrade.html"&gt;http://docs.openstack.org/developer/nova/devref/upgrade.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operations as Objects
&lt;a class="reference external" href="https://bitbucket.org/zzzeek/alembic/issue/302/operations-as-objects"&gt;https://bitbucket.org/zzzeek/alembic/issue/302/operations-as-objects&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extensible Revision / Autogenerate strategies
&lt;a class="reference external" href="https://bitbucket.org/zzzeek/alembic/issue/301/extensible-revision-autogenerate"&gt;https://bitbucket.org/zzzeek/alembic/issue/301/extensible-revision-autogenerate&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron patch to rearrange migration directory into subtrees
&lt;a class="reference external" href="https://review.openstack.org/194198"&gt;https://review.openstack.org/194198&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 19 Dec 2017 00:00:00 </pubDate></item><item><title>Neutron QoS API Models and Extension</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/qos-api-extension.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/quantum-qos-api"&gt;https://blueprints.launchpad.net/neutron/+spec/quantum-qos-api&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The scope of this spec is to implement the bandwidth limiting API and layout
the QoS models for future API and models extension introducing more
types of QoS rules.&lt;/p&gt;
&lt;p&gt;In the network jargon QoS (Quality of Service) is about limiting, prioritizing
or guaranteeing speed of traffic, in this case, on neutron ports.
For example we could mark traffic to be handled with higher priority
by switches/routers (IP/VLAN headers), or we may want to set minimum or maximum
bandwidth constraints on certain types of traffic (realtime traffic needs
to be processed with higher priority: Voice over IP, streaming, …, to reduce
latency), or the administrator of a cloud may want to offer different service levels
based on the available network bandwidth.&lt;/p&gt;
&lt;p&gt;As we propose them, QoS policies could be applied:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Per network: All the ports plugged on the network where the QoS policy is&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;applied get the policy applied to them.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Per port: The specific port gets the policy applied, when the port had any&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;network policy that one is overridden.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The definition of network QoS can involve many parameters and it is
difficult to standardize support for it across installations and Cloud
Service Providers (CSPs). Currently, there are a number of Neutron
plugins that have their own quality of service API extension, but each
has their own parameters and structure. (Note: look for the extensions
and reference them)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The CSP could provide the option of choosing a QoS policy from a
pre-configured list of policies which that particular CSP supports.
A common way to express such
categorization is through the use of the name field in a
QoS policy, which can be used to create arbitrary levels of
service like “Platinum”, “Gold”, “Silver”,
“Bronze”, and “Best-effort” levels. Note, these categories are just
examples, the specific naming convention could be defined by the CSP,
and could have a different set of policies in this list.&lt;/p&gt;
&lt;p&gt;Even from a tenant’s perspective, it might be convenient and easier to
select the desired QoS from a CSP supplied list, rather than have to
articulate complex details of the QoS policy. The actual definition of
the network QoS to which each of these levels maps to might vary
between installations and CSPs, and could include bandwidth
guarantees, priorities, etc., and will be left, by default to the CSP
admin to define as stated before.&lt;/p&gt;
&lt;p&gt;In Telcos use cases, tenants could be interested (and trusted) to
configure policies themselves. That could be allowed by modifying the
default policies.json provided with neutron.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;The model consist of two main parts, policies, and rules. Policies are
composed of rules. Even if that can look overcomplicated as a start,
it will allow the feature to be easily extended without changes
to object relationships (QoSPolicy &amp;lt;-&amp;gt; Port / QoSPolicy &amp;lt;-&amp;gt; Network) in the
future.&lt;/p&gt;
&lt;p&gt;For the case of bandwidth limiting, we have a third model QoSBandwidthLimitRule
that extends QoSRule base data model.&lt;/p&gt;
&lt;p&gt;New rules could be introduced by adding new submodels to QoSRule.&lt;/p&gt;
&lt;p&gt;QoSPolicy model has the following attributes:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, tenant&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;none&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;QoS name&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, tenant&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;none&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;QoS description&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;shared&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, tenant&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;False&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Boolean&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;If accessible
by other
tenants&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;tenant_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, tenant&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Tenant ID of
QoS object
owner&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;the QoSRule object, which composes QoSPolicy, has the following attributes:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;qos_policy_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;QoSPolicy
reference&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, tenant&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;enum&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Type of QoS&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;direction&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, tenant&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;egress&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ingress/
egress&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;(reserved)
from vm
perspective&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;tenant_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, tenant&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Tenant ID of
QoS object
owner&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The QoSBandwidthLimitRule model would look like:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;qos_rule_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;QoSRule we
extend&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;max_kbps&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, tenant&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;not NULL, &amp;gt;0&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;max_burst_kbps&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, tenant&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;NULL or &amp;gt;0&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;burst over
max_kbps&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="future-work-beyond-this-spec"&gt;
&lt;h3&gt;Future work beyond this spec&lt;/h3&gt;
&lt;p&gt;Traffic classification: traffic classifier which can be attached to QoS
rules, so the bandwidth limitations or specific marks are handled only on
certain types of traffic.&lt;/p&gt;
&lt;p&gt;Example workflow with TC:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;sip&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;traffic&lt;/span&gt; \
         &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;protocol&lt;/span&gt; &lt;span class="n"&gt;udp&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="mi"&gt;5060&lt;/span&gt;  \
         &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="s2"&gt;"SIP signaling"&lt;/span&gt;

&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; \
                        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; \
                        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="n"&gt;parameters&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; \
                        &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;traffic&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;classifier&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We believe traffic classifiers should be something to be shared with other
pieces of software in neutron (tap as a service, service chaining, etc..).&lt;/p&gt;
&lt;p&gt;More rule types:
* Traffic marking: dscp, ipv6 flow labels, vlan 802.1p
* Bandwidth guarantees: best effort, or strict (in conjunction with
nova-scheduling)&lt;/p&gt;
&lt;p&gt;Access control to QoS policy could be performed by a generalized
RBAC support. Evaluate quota controlling the different types policies.&lt;/p&gt;
&lt;p&gt;Other QoS work:
* Congestion notification support: setting the IP ECN bit over the
tenant network packets when guarantees can’t be met, for example.&lt;/p&gt;
&lt;p&gt;Explore integration with flavor framework.&lt;/p&gt;
&lt;p&gt;Network aggregated bandwidth limit.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Proposed attribute:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;QOS_RULE_COMMON_FIELDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'policies'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
        &lt;span class="s1"&gt;'shared'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_boolean&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'rules'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;'rule_types'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;SUB_RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s1"&gt;'bandwidth_limit_rules'&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
        &lt;span class="s1"&gt;'parent'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'collection_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'policies'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'member_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'policy'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'parameters'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QOS_RULE_COMMON_FIELDS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                       &lt;span class="s1"&gt;'max_kbps'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                    &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                    &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:integer'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
                       &lt;span class="s1"&gt;'max_burst_kbps'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                                    &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                    &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                    &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:integer'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
                     &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;QOS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"qos_policy_id"&lt;/span&gt;

&lt;span class="n"&gt;EXTENDED_ATTRIBUTES_2_0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'ports'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;QOS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;}}},&lt;/span&gt;
    &lt;span class="s1"&gt;'networks'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;QOS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;}}},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Sample request/responses:&lt;/p&gt;
&lt;p&gt;Create Policy Request:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;policies&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10Mbit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"This policy limits the ports to 10Mbit max."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"False"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10Mbit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"This policy limits the ports to 10Mbit max."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"46ebaec0-0570-43ac-82f6-60d2b03168c4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8d4c70a21fed4aeba121a1a429ba0d04"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"False"&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;List available rule types:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"rule_types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"bandwidth_limit"&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Create Rule Request:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;policies&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="n"&gt;ebaec0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0570&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="n"&gt;ac&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;&lt;span class="n"&gt;f6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="n"&gt;d2b03168c4&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bandwidth_limit_rules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"bandwidth_limit_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"max_kbps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"bandwidth_limit_rule"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5f126d84-551a-4dcf-bb01-0e9c0df0c793"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"46ebaec0-0570-43ac-82f6-60d2b03168c4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"max_kbps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"max_burst_kbps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Show specific policy:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;policies&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="n"&gt;ebaec0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0570&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="n"&gt;ac&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;&lt;span class="n"&gt;f6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="n"&gt;d2b03168c4&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8d4c70a21fed4aeba121a1a429ba0d04"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"46ebaec0-0570-43ac-82f6-60d2b03168c4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10Mbit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"This policy limits the ports to 10Mbit max."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"bandwidth_limit_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5f126d84-551a-4dcf-bb01-0e9c0df0c793"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"46ebaec0-0570-43ac-82f6-60d2b03168c4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"max_kbps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"10000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"max_burst_kbps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}]&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;List Request:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET /v2.0/qos/policies

Response:
{
   “policies”:
       [
            {
               "tenant_id": "8d4c70a21fed4aeba121a1a429ba0d04",
               "id": "46ebaec0-0570-43ac-82f6-60d2b03168c4",
               "name": "10Mbit",
               "description": "This policy limits the ports to 10Mbit max.",
               "shared": False,
               "bandwidth_limit_rules": [{
                  "id": "5f126d84-551a-4dcf-bb01-0e9c0df0c793",
                  "policy_id": "46ebaec0-0570-43ac-82f6-60d2b03168c4",
                  "max_kbps": "10000",
                  "max_burst_kbps": "0",
               }]
            },
            {
                ...
            }
       ]
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;By default QoS policies and rules will be managed by the cloud administrator,
that makes the tenant unable to create specific qos rules, or attaching
specific ports to policies.&lt;/p&gt;
&lt;p&gt;In some use cases, like telcos, the administrator may trust the tenants, and
therefore let them create and attach their own policies to ports. Those use
cases would be supported by modification of policy.json and specific
documentation will be released with the extension.&lt;/p&gt;
&lt;p&gt;This limitation could be partly overcome by the use of RBAC.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;Additional methods will be added to python-neutronclient to create,
list, update, and delete QoS policies and rules.
Dedicated CLI command will be added to create and update each QoS rule type.&lt;/p&gt;
&lt;p&gt;policy manipulation:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;
&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;policy rules manipulation:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bandwidth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; \
                       &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;max_kbps&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;max_burst_kbps&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bandwidth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; \
                       &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;max_kbps&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;max_burst_kbps&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bandwidth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bandwidth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bandwidth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="o"&gt;+-------------------+---------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-------------------+---------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;bandwidth_limit&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="n"&gt;Mbps&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;max_kbps&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;max_burst_kbps&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;                               &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-------------------+---------------------------------+&lt;/span&gt;

&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;available&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;

&lt;span class="o"&gt;+-----------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;QoS&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="n"&gt;types&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;bandwidth_limit&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;attach port/net to policy:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;NET&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;OR&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;NAME&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;....&lt;/span&gt;

&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;NOTE: based on the initial implementation, regular tenants may be able to use
policies marked as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Shared&lt;/span&gt;&lt;/code&gt; without any &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;policy.json&lt;/span&gt;&lt;/code&gt; modification. Later
in time the RBAC implementation may allow more granular control.&lt;/p&gt;
&lt;p&gt;detach port/net from policy:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;no&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In some QoS drivers, additional messaging calls will be created that the
L2 agents in the cluster will use to query QoS information when
creating networks and ports. Although those message flows should be optimized
to avoid scale issues, and we should look into common methods and messages
to propagate this kind of information related to ports and network resources.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;An Additional configuration section will be added to the Neutron
plugin configuration, to configure a driver that implements the QoS
API.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Doing QoS / traffic classification inside instances. This is limited to the
most basic ones, since instances wouldn’t be able to mark external
segmentation packets to prioritize traffic at L2/L3 level.
Also the tenants could not be trusted to do the right thing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nova flavors support for QoS &lt;a class="footnote-reference brackets" href="#id4" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; allows bandwidth limiting settings via
the libvirt interface on the VM tap. This is enough for basic BW limiting
on the VMs, but other QoS rules are not supported, and this also lacks
support for service port QoS. User may need to stick to one approach or
the other. This needs to be documented.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;Community, specially telcos and operators has been looking for a way to
introduce QoS capabilities into neutron managed SDNs. For some use
cases prioritization and low jitter is fundamental to some types of
applications for example voice over IP, or video streaming.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;mangelajo&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;gsagie&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;scollins&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;irenab&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;vikram&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Moshe Levi&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mathieu Rohon&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;gampel&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;REST API + API tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Database models &amp;amp; database migrations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;python-neutronclient support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;command line client implementation, bash completion included.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;openstack-sdk implementation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On other specs:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;RPC methods&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Driver model&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Driver implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reference OVS implementation &lt;a class="footnote-reference brackets" href="#id3" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None, since this is covered by the in-tree API tests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;None, in the lower level specs functional testing will be used to
verify the low level reference implementation, and make sure effective
bandwidth limiting is performed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;The new api interface will be tested via API tests, to ensure all
the operations work as expected.&lt;/p&gt;
&lt;p&gt;We should include tests to make sure incompatible rules are tested, with
the very basic bandwidth limiting we only need to look at not having
two different bandwidth limiting rules in one policy.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Additional documentation will be needed for deployers/operators, including
alternatives to the default policy.json file provided in neutron.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Additional documentation will be required for the REST API additions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Additional documentation will be required for the User Guide.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Design documentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation about how to add new rule types.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;ML2/OVS spec: &lt;a class="reference external" href="https://review.openstack.org/#/c/182349/"&gt;https://review.openstack.org/#/c/182349/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/InstanceResourceQuota#Bandwidth_limits"&gt;https://wiki.openstack.org/wiki/InstanceResourceQuota#Bandwidth_limits&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;section id="related-information"&gt;
&lt;h3&gt;Related Information&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/132661/"&gt;https://review.openstack.org/#/c/132661/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://lwn.net/Articles/640101/"&gt;https://lwn.net/Articles/640101/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://specs.openstack.org/openstack/neutron-specs/specs/liberty/neutron-flavor-framework-templates.html"&gt;http://specs.openstack.org/openstack/neutron-specs/specs/liberty/neutron-flavor-framework-templates.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Tue, 19 Dec 2017 00:00:00 </pubDate></item><item><title>Role-based Access Control for QoS policies</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/rbac-qos-policies.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1512587"&gt;https://bugs.launchpad.net/neutron/+bug/1512587&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add a Role-based Access Control for QoS policies in Neutron.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently, in neutron QoS policies cannot be shared across subsets of tenants. This proposal
talks about using RBAC &lt;a class="footnote-reference brackets" href="#id4" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; for QoS policies and making them shareable across tenants.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Introduce a new QosPolicyRBAC table that will control sharing of Neutron QoS policies between
tenants. The existing logic of shared policies will then be updated to leverage the new RBAC
code as the first implementation. The current ‘shared’ attribute on the qos-policy will be
presented as a wildcard entry in the new table to preserve backwards API compatibility
(more details below).&lt;/p&gt;
&lt;p&gt;This specification only impacts which users are allowed to apply the qos-policies - not how
they apply or what happens afterwards. As this feature leverages the existing RBAC code, it
will be a whitelist-only model. i.e. the action column can’t be a negative that states a certain
tenant can’t do something. Tenants will be able to delete policies they own, however the
deletion will be forbidden in case the policy is shared and being used (e.g. attached to other
tenant’s network).&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;Add a model of RBAC for qos policy, Using the existing RBAC for Data model as reference &lt;a class="footnote-reference brackets" href="#id5" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;QosPolicyRBAC Table structure:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;id of RBAC entry&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;tenant_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;auto&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;owner of RBAC
entry&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;object_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;object
exists&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;object
affected by RBAC&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;object_type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;type has
RBAC table&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;type of object&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;target_tenant&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RWU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;tenant ID the
entry affects.
* for all&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;action&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;in actions
for object&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;allowed tenant
action on object&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="example-entries"&gt;
&lt;h3&gt;Example Entries&lt;/h3&gt;
&lt;p&gt;A legacy shared qos policy:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;object_id = &amp;lt;some_qos policy_id&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;target_tenant = ‘*’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;action = ‘access_as_shared’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;id = &amp;lt;uuid&amp;gt;  # auto generated&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tenant_id = &amp;lt;uuid-of-policy-creator&amp;gt;  # generated by API&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A qos policy shared to a specific tenant:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;object_id = &amp;lt;some_qos policy_id&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;target_tenant = &amp;lt;some_tenant_id&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;action = ‘access_as_shared’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;id = &amp;lt;uuid&amp;gt;  # auto generated&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tenant_id = &amp;lt;uuid-of-policy-creator&amp;gt;  # generated by API&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All entries are to allow the action they describe. There won’t be any ‘deny’ rules at this time.&lt;/p&gt;
&lt;p&gt;The object ID is simply the UUID of the policies to which the RBAC entry will be applied.&lt;/p&gt;
&lt;p&gt;The target_tenant will be the tenant (a.k.a. project) ID to which the RBAC entry is granting
permission to perform an action on the target object. This entry may also be an asterisk to
represent that it applies to all tenants.&lt;/p&gt;
&lt;p&gt;The action will describe what the tenant can do with the object. This specification deals with
only one action - ‘access_as_shared’ to indicate that the tenant can access it like it would a
shared policy. This could then be extended in the future to include something like ‘deny’ to
provide RBAC for blacklisting as well. Supported actions are discoverable via the API.&lt;/p&gt;
&lt;p&gt;Finally, each RBAC entry will also have a tenant ID that indicates the tenant that created the
policy itself. This will normally be the same tenant as the object being shared, but it might
not be in the case of admin-created policies for other tenants.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Existing RBAC API’s will be extended to take new parameter - a new ‘object-type’ option would be
added to the existing CLI.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'rbac_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'action'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'access_as_shared'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'cc4abd64f6e5409da3ae6c04124f6d37'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'object_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'qos-policy'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'target_tenant'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'1b245fd28a13435bb075dadac5951f8d'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'object_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'f60eb0dc-ce07-419c-aa80-1114aafd38a7'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;Tenants will be able to share qos policies with each other. This shouldn’t be a major issue, since
the ownership will never change. Effectively, each tenant will be responsible for its policy
utilization.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;The end user will be able to specify the qos policy as object-type.
A new ‘object-type’ option would be added to the existing CLI. No new CLI is required.&lt;/p&gt;
&lt;p&gt;Attach a new RBAC to an existing qos-policy:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;rbac&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tenant&lt;/span&gt; \
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;tenant&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="n"&gt;access_as_shared&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RBAC_OBJECT&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;There should be no impact to the regular global shared qos policy workflow. The new API usage will
only be required for fine-grained entries.&lt;/p&gt;
&lt;p&gt;From the perspective of a tenant that has a policy shared to it, the policy will show up as ‘shared’
just like a globally shared policy would.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Checking the ‘shared’ attribute for the qos-policy will now involve a join to another table.
Same goes with respect to policy listing and updating.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change shouldn’t impact the community in any major way as the legacy API remains.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add the DB model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adjust existing ‘shared’ attribute to use rbac and add migration script.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the client to CRUD the new RBACs type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add UTs to Neutron server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add API tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;No tests are required. API tests should be sufficient.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;No functional test is likely necessary for this work. All of this is
at the API layer without impacting the dataplane.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Excercise basic CRUD of RBAC entries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure qos policies are revealed and hidden as RBAC entries are changed&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;The workflow for adding RBAC for qos policy entries will need to be added to &lt;a class="footnote-reference brackets" href="#id6" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Role-based access control for networks,
&lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/liberty/rbac-networks.html"&gt;https://specs.openstack.org/openstack/neutron-specs/specs/liberty/rbac-networks.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;RBAC Data model,
&lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/liberty/rbac-networks.html#data-model-impact"&gt;https://specs.openstack.org/openstack/neutron-specs/specs/liberty/rbac-networks.html#data-model-impact&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Qos User Configuration guide,
&lt;a class="reference external" href="http://docs.openstack.org/liberty/networking-guide/adv_config_qos.html"&gt;http://docs.openstack.org/liberty/networking-guide/adv_config_qos.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Tue, 19 Dec 2017 00:00:00 </pubDate></item><item><title>Allow Neutron Port Without IP Address</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/newton/unaddressed-port.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/vm-without-l3-address"&gt;https://blueprints.launchpad.net/neutron/+spec/vm-without-l3-address&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Allow to create unaddressed port. i.e. port without l3-address, subnets
and to boot with the port.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently VM only with L2 address without ipv4/ip6 address can’t be created.
In fact, it is already possible to create a port without IPv4 address,
or without IPv6 address. This means that the current implementation of neutron
port creating could accept empty subnet in request(you will not be forced to
specify the subnet), of cause the VIF type of the created port here is unbound.&lt;/p&gt;
&lt;p&gt;Neutron and nova create interfaces with the assumption that the
interface’s L2 and L3 assigned addresses are intrinsic attributes;
that an L3 address is not optional, and that traffic should never
be seen by that machine unless it is addressed to the recognised
addresses.&lt;/p&gt;
&lt;p&gt;Network applications (for example, routers) often forward traffic that
is not intended for them, and may actually have&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;interface without a primary L3 address, which may be receiving
traffic for so many disparate addresses that configuring them
all in Neutron itself is a pointless burden&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;A typical use case is when a user wishes to deploy a VM which accepts
traffic that is neither IPv4 nor IPv6 in nature, one that accepts is a
superset of v4 and v6 traffic, or one that accepts traffic for a very
wide address range (for either forwarding or termination) and where
the port has no primary address.  In such cases, the VM is not a
conventional application VM.&lt;/p&gt;
&lt;p&gt;NOTE: many sentence are shamelessly stolen from &lt;a class="reference internal" href="#nova-l2-net-without-subnet" id="id1"&gt;&lt;span&gt;[nova-l2-net-without-subnet]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And we must also note that some L2 driver like l2-pop maybe have problem when
deal with this kind of port because it use arp proxy to answer arp from known
ip address.
And also some service like novnc service may be not work for the port without
IP address.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Allow to boot VM with port without l3-address.
Actually the current neutron allows to create a port without subnet.
New typical work flow would be as follows (which doesn’t work currently)&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Create neutron L2 network, but any subnets aren’t associated to it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Boot VM on the network&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Or&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Create neutron L2 network. subnets may or may not be associated to it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create neutron port on the network without fixed ips&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Boot VM with the created port&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the neutron side, if this kind of port created, security-groups should be
removed and filter like anti-mac-spoofing should be disabled.
And also, if necessary, fix L2/L3 agent codes which depend on that port
should has a fixed ip.&lt;/p&gt;
&lt;p&gt;In the nova side, fixed ips and subnet checking exception check like
PortRequiresFixedIP and NetworkRequiresSubnet should be removed carefully.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None. Because the current neutron API implementation allows to create a port
without specifying the subnet or any fixed ips in request. So we don’t need
a new flag to define it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;Of cause, unaddressed ports are dangerous to the unwary. But because the
operation of this kind of ports just follow the existing process, only
the network owners and administrators have the privilege to operate the port.
The security impact is minimal.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;L2/L3 agent might be confused without fixed ip address since such a code
path isn’t tested.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Yalei Wang
Zang Rui
Isaku Yamahata(yamahata)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;to be added&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;python neutron client to specify that no fixed ip address is associated&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;python nova client to specify that no fixed ip address is associated&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;nova neutronv2 network driver, remove the current verification
PortRequiresFixedIP and NetworkRequiresSubnet, fix bug
&lt;a class="reference internal" href="#nova-l2-net-without-subnet" id="id2"&gt;&lt;span&gt;[nova-l2-net-without-subnet]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;remove the security group or other packages filter of the unaddressed port in
neutron.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;add tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;if necessary, fix neutron components.
especially L2/L3 agents, security group driver&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Nova neutronv2 network driver would need modification.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Necessary api/functional tests will be added.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create port without fixed ip address
** connection tests between ports&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;boot VM with such ports&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;attach/detach such ports to VMs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create port without fixed ip address and tests connectivity between ports&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The related part will be updated.&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;nova boot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;neutron port creation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;div role="list" class="citation-list"&gt;
&lt;div class="citation" id="nova-l2-net-without-subnet" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;nova-l2-net-without-subnet&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;Creating Neutron L2 networks (without subnets) doesn’t work as expected
&lt;a class="reference external" href="https://bugs.launchpad.net/nova/+bug/1039665"&gt;https://bugs.launchpad.net/nova/+bug/1039665&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;section id="related-information"&gt;
&lt;h3&gt;Related Information&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Make libvirt use the new network model datastructures
&lt;a class="reference external" href="https://review.openstack.org/#/c/11923/"&gt;https://review.openstack.org/#/c/11923/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NFV unaddressed interfaces
&lt;a class="reference external" href="https://review.openstack.org/#/c/97715/"&gt;https://review.openstack.org/#/c/97715/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Tue, 19 Dec 2017 00:00:00 </pubDate></item><item><title>Port data plane status</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/pike/port-data-plane-status.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1598081"&gt;https://bugs.launchpad.net/neutron/+bug/1598081&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron may not be well equipped to detect data plane failures affecting the
underlying networking infrastructure. This spec addresses that issue by means
of allowing external tools to report to Neutron about faults in the underlying
data plane that are affecting the ports. A new REST API field is proposed to
that end.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;An initial description of the problem was introduced in bug #159801 &lt;a class="footnote-reference brackets" href="#id6" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. This
spec focuses on capturing one (main) part of the problem there described, i.e.
extending Neutron’s REST API to cover the scenario of allowing external tools
to report network failures to Neutron. Out of scope of this spec are works to
enable port status changes to be received and managed by mechanism drivers.&lt;/p&gt;
&lt;p&gt;This spec provides the plumbing to address bug #1575146 &lt;a class="footnote-reference brackets" href="#id7" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; in subsequent
work. Specifically, and argued by the Neutron driver team in &lt;a class="footnote-reference brackets" href="#id8" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron should not shut down the port completely upon detection of underlay
network failure; connectivity between instances on the same node may still
be reachable. External tools may or may not want to trigger a status change
on the port based on their own logic and orchestration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Port down is not detected when an uplink of a switch is down.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The physical network bridge may have multiple physical interfaces plugged;
shutting down the logical port may not be needed when network redundancy is
in place.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;section id="use-case"&gt;
&lt;h3&gt;Use case&lt;/h3&gt;
&lt;p&gt;The network elements of a cloud infrastucture is managed by two SDN
controllers: SDN controller A manages the virtual switches hosted on OpenStack
nodes, and SDN controller B manages Top of Rack (ToR) switches.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                   &lt;span class="o"&gt;+---------------+&lt;/span&gt;
                   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Orchestrator&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;+-----------+&lt;/span&gt;  &lt;span class="n"&gt;Fault&lt;/span&gt; &lt;span class="n"&gt;Mmgmt&lt;/span&gt;  &lt;span class="o"&gt;+---------+&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;+---------------+&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------+-------+&lt;/span&gt;                       &lt;span class="o"&gt;+-----+----+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;SDN&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Neutron&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Controller&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="o"&gt;+-----+----+&lt;/span&gt;
&lt;span class="o"&gt;+------+-------+&lt;/span&gt;                             &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;                              &lt;span class="o"&gt;+------+-------+&lt;/span&gt;
 &lt;span class="o"&gt;+-----+------+&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;SDN&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ToR&lt;/span&gt; &lt;span class="n"&gt;Switch&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Controller&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;+------------+&lt;/span&gt;                       &lt;span class="o"&gt;+------+-------+&lt;/span&gt;
                                             &lt;span class="o"&gt;|&lt;/span&gt;
                                             &lt;span class="o"&gt;|&lt;/span&gt;
                                             &lt;span class="o"&gt;|&lt;/span&gt;
                                        &lt;span class="o"&gt;+----+----+&lt;/span&gt;
                                        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;vSwitch&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                                        &lt;span class="o"&gt;+---------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;SDN Controller B has network monitoring capabilities that enables northbound
users to be notified of topology changes, e.g. due to hardware failures or
cable pulled. In this use case, user is an orchestrator with fault management
capabilities that collects fault events from multiple data sources and updates
the status of affected cloud resources. The orchestrator can be a system
composed by various OpenStack projects such as Vitrage/Monasca for Root Cause
Analysis (RCA), Congress for cloud resource status updates and remediation
actions, and Aodh for event alarming.&lt;/p&gt;
&lt;p&gt;One possible workflow is:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;SDN Controller B detects ToR switch port down and reports to orchestrator;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Orchestrator finds affected cloud resources (e.g. (sub)set of Neutron ports
attached to Nova instances) caused by the underlay data plane outage;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Orchestrator updates the data plane port status of those Neutron ports;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron sends notification to the message bus;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Aodh and Congress consume Neutron notifications:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;&lt;p&gt;Aodh sends an event alarm to affected Neutron port users;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Congress triggers remediation actions (e.g. Congress policy actions) for
switch-over to a standby instance.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;A similar workflow was presented at the OpenStack Summit Barcelona keynote demo &lt;a class="footnote-reference brackets" href="#id9" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;A couple of possible approaches were proposed in &lt;a class="footnote-reference brackets" href="#id6" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; (comment #3). This spec
proposes tackling the problem via a new extension API to the port resource.
The extension adds a new attribute &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;data_plane_status&lt;/span&gt;&lt;/code&gt; to represent the
status of the underlay data plane. This attribute is to be managed by entities outside
of Neutron, while the ‘status’ attribute is managed by Neutron. Both status
attributes are independent from one another.&lt;/p&gt;
&lt;p&gt;The field should be read-only by project users and read-write by any user with
a specific role.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;A new attribute will be added to the ‘ports’ table as a Neutron extension.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;data_plane_status&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R, project
RW, user w/role&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None, “ACTIVE”
“DOWN”&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;A new API extension to the ports resource is going to be introduced.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;EXTENDED_ATTRIBUTES_2_0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'ports'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'data_plane_status'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                              &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="examples"&gt;
&lt;h4&gt;Examples&lt;/h4&gt;
&lt;p&gt;Updating port data plane status to down:&lt;/p&gt;
&lt;div class="highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;PUT /v2.0/ports/&amp;lt;port-uuid&amp;gt;
Accept: application/json
{
    "port": {
        "data_plane_status": "DOWN"
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="command-line-client-impact"&gt;
&lt;h3&gt;Command Line Client Impact&lt;/h3&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;plane&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ACTIVE&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;DOWN&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Argument –data-plane-status is optional.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id5"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;RFE: Port status update,
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1598081"&gt;https://bugs.launchpad.net/neutron/+bug/1598081&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;RFE: ovs port status should the same as physnet
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1575146"&gt;https://bugs.launchpad.net/neutron/+bug/1575146&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Neutron Drivers meeting, July 21, 2016
&lt;a class="reference external" href="http://eavesdrop.openstack.org/meetings/neutron_drivers/2016/neutron_drivers.2016-07-21-22.00.html"&gt;http://eavesdrop.openstack.org/meetings/neutron_drivers/2016/neutron_drivers.2016-07-21-22.00.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id9" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Demo: OpenStack and OPNFV - Keeping Your Mobile Phone Calls Connected
&lt;a class="reference external" href="https://www.youtube.com/watch?v=Dvh8q5m9Ahk"&gt;https://www.youtube.com/watch?v=Dvh8q5m9Ahk&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;section id="related-information"&gt;
&lt;h3&gt;Related Information&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron v2 API
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/APIv2-specification"&gt;https://wiki.openstack.org/wiki/Neutron/APIv2-specification&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron: resource status &amp;amp; admin state up
&lt;a class="reference external" href="https://docs.google.com/presentation/d/1-cex849lLsmRsZ302lqkwvXbexhe6cwuCZ2JSE8Rp2s"&gt;https://docs.google.com/presentation/d/1-cex849lLsmRsZ302lqkwvXbexhe6cwuCZ2JSE8Rp2s&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Tue, 19 Dec 2017 00:00:00 </pubDate></item><item><title>Extend logging framework to support FWaaS v2</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/rocky/extend-logging-framework-to-support-for-FWaaS-v2.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1720727"&gt;https://bugs.launchpad.net/neutron/+bug/1720727&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;All content of this spec is based on &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/pike/logging-API-for-security-group-rules.html"&gt;original spec&lt;/a&gt;
and to extend supporting the logging feature for FWaaS v2 which was mentioned
in the &lt;em&gt;Future work beyond this spec&lt;/em&gt; section.&lt;/p&gt;
&lt;p&gt;We expect reviewers to check &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/pike/logging-API-for-security-group-rules.html"&gt;original spec&lt;/a&gt; before going ahead with below sections.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The current logging framework just supports security group as an initial
implementation. FWaaS v2 lacks this useful feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;To extend the feature to support FWaaS v2, we would like to propose
additional information comparable to &lt;em&gt;Proposed Change&lt;/em&gt; section in
&lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/pike/logging-API-for-security-group-rules.html"&gt;original spec&lt;/a&gt; as following:&lt;/p&gt;
&lt;section id="logging-implementation"&gt;
&lt;h3&gt;Logging implementation&lt;/h3&gt;
&lt;p&gt;Currently, Logging API is designed as a service plugin. It is also defined as a
generic logging API for resources such as security groups and firewall.
Reference implementation can be found in &lt;a class="footnote-reference brackets" href="#id6" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The server side is one aspect we need to handle. At the moment in Neutron
Security Group logging implementation, we have a function as request validator &lt;a class="footnote-reference brackets" href="#id7" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.
This code should be moved out from neutron to neutron-lib and will
be more generic so it can handle both Neutron SG and FWaaS.
The expected outcome of this step is to make sure this validator is still
working for Security Group and it can also be applied for FWaaS.&lt;/p&gt;
&lt;p&gt;Regarding to agent side:&lt;/p&gt;
&lt;p&gt;For L2 layer, the &lt;em&gt;LoggingExtension&lt;/em&gt; is an L2 agent extension. It is common for
all logging resources like security groups and firewall. For L3 layer,
&lt;em&gt;LoggingL3AgentExtension&lt;/em&gt; is an L3 agent extension dedicated for firewall.
These agent extensions will receive CREATED/UPDATED/DELETED events of the
logging resource and pass these events to logging drivers. Each logging driver
defines the resources it supports. In case of FWaaS v2, logging driver named
&lt;em&gt;FWaaSv2LoggingDriver&lt;/em&gt; will be implemented. This class will inherit
from &lt;em&gt;LoggingDriver&lt;/em&gt; class.&lt;/p&gt;
&lt;p&gt;Regarding to driver side:&lt;/p&gt;
&lt;p&gt;There are two drivers will be implemented in order to support for both
L2 layer (instance) and L3 layer (router).&lt;/p&gt;
&lt;p&gt;For L2 layer, a driver named &lt;em&gt;FWaaSv2L2LoggingDriver&lt;/em&gt; will be implemented. It
acts as a controller program.
This driver will insert flows log into table=91 and table=92 with
ct_state=NEW to generate ACCEPT events, insert flows log into
table=93 to generate DROP events.&lt;/p&gt;
&lt;p&gt;For L3 layer, a driver named &lt;em&gt;FWaaSv2L3LoggingDriver&lt;/em&gt; will be implemented based on
iptables in user namespace level. It runs in network node to handle router’s
port by adding NFLOG rules to iptables. We would like to propose detail solution
as following:&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;The structure of iptables rules.&lt;/p&gt;
&lt;p&gt;We will introduce two new chains:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;neutron-l3-agent-accepted: log first accept packet and accept all
packets which are matched with firewall rules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;neutron-l3-agent-dropped: log and drop all packets.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;New iptables structure when logging is enabled would look like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;Chain INPUT (policy ACCEPT)
target     prot opt source               destination
neutron-l3-agent-INPUT  all  --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
neutron-filter-top  all  --  anywhere             anywhere
neutron-l3-agent-FORWARD  all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
neutron-filter-top  all  --  anywhere             anywhere
neutron-l3-agent-OUTPUT  all  --  anywhere             anywhere

Chain neutron-filter-top (2 references)
target     prot opt source               destination
neutron-l3-agent-local  all  --  anywhere             anywhere

Chain neutron-l3-agent-FORWARD (1 references)
target     prot opt source               destination
neutron-l3-agent-scope  all  --  anywhere             anywhere
neutron-l3-agent-iv4dd529723  all  --  anywhere             anywhere
neutron-l3-agent-ov4dd529723  all  --  anywhere             anywhere
neutron-l3-agent-fwaas-defau  all  --  anywhere             anywhere
neutron-l3-agent-fwaas-defau  all  --  anywhere             anywhere

Chain neutron-l3-agent-INPUT (1 references)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             mark match 0x1/0xffff
DROP       tcp  --  anywhere             anywhere             tcp dpt:9697

Chain neutron-l3-agent-OUTPUT (1 references)
target     prot opt source               destination

Chain neutron-l3-agent-fwaas-defau (2 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere

Chain neutron-l3-agent-iv4dd529723 (1 references)
target     prot opt source               destination
neutron-l3-agent-dropped       all  --  anywhere             anywhere             state INVALID
neutron-l3-agent-accepted     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
neutron-l3-agent-dropped       all  --  anywhere             anywhere

Chain neutron-l3-agent-local (1 references)
target     prot opt source               destination

Chain neutron-l3-agent-ov4dd529723 (1 references)
target     prot opt source               destination
neutron-l3-agent-dropped       all  --  anywhere             anywhere             state INVALID
neutron-l3-agent-accepted     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
neutron-l3-agent-accepted     all  --  anywhere             anywhere

Chain neutron-l3-agent-scope (1 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere             mark match ! 0x4000000/0xffff0000

Chain neutron-l3-agent-fw-chain (2 references)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere

chain neutron-l3-agent-accepted
target     prot opt source               destination
NFLOG      all  --  anywhere             anywhere             state NEW limit: avg 100/sec burst 25 nflog-prefix  12823226497704342389
ACCEPT     all  --  anywhere             anywhere

chain neutron-l3-agent-dropped
target     prot opt source               destination
NFLOG      all  --  anywhere             anywhere             limit: avg 100/sec burst 25 nflog-prefix  12823226497704342389
DROP       all  --  anywhere             anywhere
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to capture packets and parse information of packets. This requires at least two steps.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;First we need to dump packets into raw format.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We propose to implement a python binding for &lt;cite&gt;libnetfilter_log&lt;/cite&gt;, same
idea like &lt;a class="footnote-reference brackets" href="#id8" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After we have packets in raw format, we need to parse these data into
human readable format.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In order to do that, we propose to use &lt;cite&gt;ryu&lt;/cite&gt; &lt;a class="footnote-reference brackets" href="#id9" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; library for this step.
PoC implementation looks like &lt;a class="footnote-reference brackets" href="#id10" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;About how to configure logging feature,
See &lt;a class="reference external" href="https://review.openstack.org/#/c/480117/"&gt;networking guide&lt;/a&gt; for detail.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="expected-api-behavior"&gt;
&lt;h3&gt;Expected API behavior&lt;/h3&gt;
&lt;p&gt;This spec takes FWaaS v2 logging as an example:&lt;/p&gt;
&lt;p&gt;Operators can collect security events (ALLOW/DROP or ALL) for some cases:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Collect events related to a specific firewall group applied to all
instances/routers ports by passing its firewall group ID to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_id&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Collect events related to a specific firewall group applied to a
specific instance/router by passing its firewall group ID to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_id&lt;/span&gt;&lt;/code&gt;
and its bound Neutron port ID to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;target_id&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Collect events related to all firewall groups being applied to a
specific instance by passing its Neutron port ID to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;target_id&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Collect events related to firewall groups in a project: in this case
operators do not pass any value to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_id&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;target_id&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="api-operation-sample"&gt;
&lt;h3&gt;API operation sample&lt;/h3&gt;
&lt;p&gt;Same as &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/pike/logging-API-for-security-group-rules.html"&gt;original spec&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Same as &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/pike/logging-API-for-security-group-rules.html"&gt;original spec&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add support firewall_group as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;loggable_resource&lt;/span&gt;&lt;/code&gt; type.
In order to do that, there are two changes required:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Make request validator and rpc callback to be more generic in order to
support firewall_group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On FWaaS, use above generic methods to register to Neutron side.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;Same as &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/pike/logging-API-for-security-group-rules.html"&gt;original spec&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="operators-cli-impact"&gt;
&lt;h3&gt;Operators CLI Impact&lt;/h3&gt;
&lt;p&gt;Add &lt;cite&gt;firewall_group&lt;/cite&gt; to be on of –resource-type. Also add &lt;cite&gt;firewall_group&lt;/cite&gt;
in output of supported logging capabilities.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Same as &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/pike/logging-API-for-security-group-rules.html"&gt;original spec&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;Same as &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/pike/logging-API-for-security-group-rules.html"&gt;original spec&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None as it done along with logging feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;y-furukawa-2&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;hoangcx,
annp,
cuongnv&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Finalize a way to log data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement &lt;em&gt;FWaaSv2LoggingDriver&lt;/em&gt; based reference implementation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Same as &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/pike/logging-API-for-security-group-rules.html"&gt;original spec&lt;/a&gt;&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Same as &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/pike/logging-API-for-security-group-rules.html"&gt;original spec&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Same as &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/pike/logging-API-for-security-group-rules.html"&gt;original spec&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Same as &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/pike/logging-API-for-security-group-rules.html"&gt;original spec&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Same as &lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/pike/logging-API-for-security-group-rules.html"&gt;original spec&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/395504/"&gt;https://review.openstack.org/#/c/395504/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/139c8341f4eaa5f214050d4f7f1cca3f2a1cae34/neutron/services/logapi/common/validators.py#L111"&gt;https://github.com/openstack/neutron/blob/139c8341f4eaa5f214050d4f7f1cca3f2a1cae34/neutron/services/logapi/common/validators.py#L111&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/commonism/python-libnetfilter"&gt;https://github.com/commonism/python-libnetfilter&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id9" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/osrg/ryu"&gt;https://github.com/osrg/ryu&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/445827/26/neutron/privileged/agent/linux/libnetfilter_log.py"&gt;https://review.openstack.org/#/c/445827/26/neutron/privileged/agent/linux/libnetfilter_log.py&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Mon, 02 Oct 2017 00:00:00 </pubDate></item><item><title>&amp;lt;Project&amp;gt; Scorecard</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stadium/queens/placeholder.html</link><description>

&lt;p&gt;This document template is meant to be used as a scorecard to assess how
a project eligible for inclusion meets the Neutron Stadium requirements
as defined in this &lt;a class="reference external" href="http://specs.openstack.org/openstack/neutron-specs/specs/newton/neutron-stadium.html"&gt;specification&lt;/a&gt;.
If the outcome of the assessment is negative, the project inclusion is
rejected.&lt;/p&gt;
&lt;section id="neutron-integration"&gt;
&lt;h2&gt;Neutron integration&lt;/h2&gt;
&lt;ul class="simple" id="n0"&gt;
&lt;li&gt;&lt;p&gt;N0. Does the project use the Neutron REST API or rely on proprietary backends?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="n1"&gt;
&lt;li&gt;&lt;p&gt;N1. Does the project integrate/use neutron-lib?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="n2"&gt;
&lt;li&gt;&lt;p&gt;N2. Do project members actively contribute to help neutron-lib achieve its
goal?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="n3"&gt;
&lt;li&gt;&lt;p&gt;N3. Do project members collaborate with the core team to enable subprojects
to loosely integrate with the Neutron core platform by helping with the definition
of modular interfaces?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="n4"&gt;
&lt;li&gt;&lt;p&gt;N4. How does the project provide networking services? Does it use modular interfaces
as provided by the core platform?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="n5"&gt;
&lt;li&gt;&lt;p&gt;N5. If the project provides new API extensions, have API extensions been discussed
and accepted by the Neutron drivers team? Please provide links to API specs, if
required.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul class="simple" id="d1"&gt;
&lt;li&gt;&lt;p&gt;D1. Does the project have a doc tox target, functional and continuously
working? Provide proof (e.g. links to logs.openstack.org).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="d2"&gt;
&lt;li&gt;&lt;p&gt;D2. If the project provides API extensions, does the project have an
api-ref tox target, functional and continuously working? Provide proof
(e.g. links to logs.openstack.org).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="d3"&gt;
&lt;li&gt;&lt;p&gt;D3. Does the project have a releasenotes tox target, functional and
continuously working? Provide proof.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="d4"&gt;
&lt;li&gt;&lt;p&gt;D4. Describe the types of documentation available: developer, end user,
administrator, deployer.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="continuous-integration"&gt;
&lt;h2&gt;Continuous Integration&lt;/h2&gt;
&lt;ul class="simple" id="c1"&gt;
&lt;li&gt;&lt;p&gt;C1. Does the project have a Grafana dashboard showing historical trends of
all the jobs available? Provide proof (links to grafana.openstack.org).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="c2"&gt;
&lt;li&gt;&lt;p&gt;C2. Does the project have CI for unit coverage? Provide proof (links to
logs.openstack.org).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="c3"&gt;
&lt;li&gt;&lt;p&gt;C3. Does the project have CI for functional coverage? If so, does it include
DB migration and sync validation?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="c4"&gt;
&lt;li&gt;&lt;p&gt;C4. Does the project have CI for fullstack coverage?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="c5"&gt;
&lt;li&gt;&lt;p&gt;C5. Does the project have CI for Tempest coverage? If so, specify nature
(API and/or Scenario).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="c6"&gt;
&lt;li&gt;&lt;p&gt;C6. How does a project validate upgrades on a continuous basis? Does
the project require or support CI for Grenade coverage?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="c7"&gt;
&lt;li&gt;&lt;p&gt;C7. Does the project provide multinode CI?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="c8"&gt;
&lt;li&gt;&lt;p&gt;C8. Does the project support Python 3.x? Provide proof.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="release-footprint"&gt;
&lt;h2&gt;Release footprint&lt;/h2&gt;
&lt;ul class="simple" id="r1"&gt;
&lt;li&gt;&lt;p&gt;R1. Does the project adopt &lt;a class="reference external" href="http://semver.org/"&gt;SemVer&lt;/a&gt;?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="r2"&gt;
&lt;li&gt;&lt;p&gt;R2. Does the project have release deliverables? Provide proof as available
in the &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/"&gt;release repo&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="r3"&gt;
&lt;li&gt;&lt;p&gt;R3. Does the project use upper-constraints?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="r4"&gt;
&lt;li&gt;&lt;p&gt;Does the project integrate with OpenStack Proposal Bot for requirements updates?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="stable-backports"&gt;
&lt;h2&gt;Stable backports&lt;/h2&gt;
&lt;ul class="simple" id="s1"&gt;
&lt;li&gt;&lt;p&gt;S1. Does the project have stable branches and/or tags? Provide history of
backports.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="client-library"&gt;
&lt;h2&gt;Client library&lt;/h2&gt;
&lt;ul class="simple" id="l1"&gt;
&lt;li&gt;&lt;p&gt;L1. If the project requires a client library, how does it implement CLI and
API bindings?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="scorecard"&gt;
&lt;h2&gt;Scorecard&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Scorecard&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n0"&gt;N0&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n1"&gt;N1&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n2"&gt;N2&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n4"&gt;N4&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n5"&gt;N5&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d1"&gt;D1&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d3"&gt;D3&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c2"&gt;C2&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c3"&gt;C3&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c4"&gt;C4&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c6"&gt;C6&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c7"&gt;C7&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c8"&gt;C8&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r1"&gt;R1&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r2"&gt;R2&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r3"&gt;R3&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r4"&gt;R4&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#s1"&gt;S1&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Final remarks: (To be compiled by PTL).&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 21 Sep 2017 00:00:00 </pubDate></item><item><title>QoS detailed reporting of available QoS rules</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/pike/qos-detailed-reporting-of-available-rules.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1686035"&gt;https://bugs.launchpad.net/neutron/+bug/1686035&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;With [1] different QoS rules can be supported by different backend drivers.
Whether the driver can handle the given rule type, and the parameters passed
with the rule, are validated only when the user wants to apply the rule to a
port/network.
With [2] merged, Neutron returns a list of all rule types supported by
at least one of the enabled backends.
This is not enough as users are unable to discover what values are supported by
the back ends for each rule type&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;We propose to add new API. This call would be used to get details of every
available rule type.&lt;/p&gt;
&lt;section id="rest-api"&gt;
&lt;h3&gt;REST API&lt;/h3&gt;
&lt;p&gt;New REST API call is:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;rule_type&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Request example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bandwidth_limit&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The response is a dict with details for the supported rule type for each of the
enabled backends.&lt;/p&gt;
&lt;p&gt;As parameter values can be returned:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;list of supported values if driver uses “type:values” validator from
neutron-lib to validate this parameter&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;dict with ‘start’ and ‘end’ value if driver uses “type:range” validator from
neutron-lib to validate this parameter. Both ‘start’ and ‘end’ values are
inclusive in the range.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;QoS rule types uses only “type:values” and “type:range” validators currently and
only those validators are supported by this spec.&lt;/p&gt;
&lt;p&gt;This call should be available only for users with admin rights to not expose
details about cloud infra to regular users.&lt;/p&gt;
&lt;p&gt;Response example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"rule_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"bandwidth_limit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"drivers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ovs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"supported_parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"max_kbps"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"range"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_values"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="s2"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s2"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
                        &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"max_burst_kbps"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"range"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_values"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="s2"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s2"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
                        &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"choices"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_values"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"ingress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"egress"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"linuxbridge"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"supported_parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"max_kbps"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"range"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_values"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="s2"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s2"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
                        &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"max_burst_kbps"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"range"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_values"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="s2"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s2"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
                        &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"choices"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"parameter_values"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"egress"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference internal" href="qos-improved-validation-mechanism-rules.html"&gt;&lt;span class="doc"&gt;QoS improved validation mechanism for rules and port types&lt;/span&gt;&lt;/a&gt;
[2] &lt;a class="reference external" href="https://review.openstack.org/#/c/461257"&gt;https://review.openstack.org/#/c/461257&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 11 Sep 2017 00:00:00 </pubDate></item><item><title>L2 Extension flow management support</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/backlog/pike/l2-extension-ovs-flow-management.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1563967"&gt;https://bugs.launchpad.net/neutron/+bug/1563967&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The l2-agent-extension-api that merged in Mitaka allows extensions of the
Open vSwitch agent to manipulate the Open vSwitch OpenFlow tables.&lt;/p&gt;
&lt;p&gt;This introduces a challenge of interoperability between extensions creating
flows.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;As the Open vSwitch flow table matches traffic to flows based on packet
characteristics in the order of priority assigned to the flow, it will
inevitably result in two extensions using flows that will block the extension
that uses the lower priority flows.&lt;/p&gt;
&lt;p&gt;Therefore a flow manager or flow pipeline is necessary, that would reconcile
flows for multiple extensions in a consistent and mutually compatible way.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;In order to make extensions optional, pluggable and interoperable in the
context of OpenFlow rules we need to define a pipeline model, and a l2
extension API interface, with the main purpose of avoiding cases where
two extensions manipulate the same exact table, inserting eventually
incompatible flows, and to let extensions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;declare OpenFlowFunctions, where an OpenFlowFunction is a set of tables
that implement the extension behaviour and can be plugged in either the
egress or ingress pipeline.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;declare the need to reference other OpenFlowFunctions within the same
extension (for example an extension could need to learn flows into another
of its own functions on a different stage of the pipeline ingress/egress,
a typical example of this is mac-learning ingress function learns to an
egress function).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;declare OpenFlowRegisters, which will be used inside the function, and
sometimes can be used by other functions as a medium to exchange metadata.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;declare the need for a specific OpenFlowRegister, generally the needed
registers are filled or received up by the fixed blocks, but eventually
extensions, or different extension functions may need to interoperate by
exchanging metadata in registers.&lt;/p&gt;
&lt;p&gt;Public registers or functions can be accessed by other extensions, but non
public registers can’t. This sets a minimum base for extension interoperation,
where that makes sense.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Three classes will be provided for the extensions and other OpenFlow mechanisms
(like the OpenFlow firewall driver, or the proposed fixed blocks -see below-)
to declare their OpenFlow functions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;OpenFlowFunction&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenFlowTable&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenFlowRegister&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The code could roughly look like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nd"&gt;@openflow_pipeline&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;register_openflow_function&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;EgressTrafficClassifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;openflow_pipeline&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OpenFlowFunction&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;extension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"FIXED_BLOCKS"&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'EGRESS_TRAFFIC_CLASSIFIER'&lt;/span&gt;
    &lt;span class="n"&gt;bridge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openflow_pipeline&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INTEGRATION_BRIDGE&lt;/span&gt;

    &lt;span class="n"&gt;declares_registers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;OpenFlowRegister&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'CLASSIFIER_MARK'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                           &lt;span class="n"&gt;public&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;declares_tables&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;OpenFlowTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'CLASSIFIER'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NEXT&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;needs_registers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;OpenFlowRegister&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'OUTPUT_PORT'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;needs_function&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;OpenFlowfunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'INGRESS_TRAFFIC_X'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                      &lt;span class="n"&gt;OpenFlowfunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'INPUT_TAGGING'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

    &lt;span class="c1"&gt;# The openflow manager will register the following attributes on the&lt;/span&gt;
    &lt;span class="c1"&gt;# class once it has resolved all dependencies and creations&lt;/span&gt;
    &lt;span class="c1"&gt;#          &amp;lt;name&amp;gt;_table&lt;/span&gt;
    &lt;span class="c1"&gt;#          &amp;lt;name&amp;gt;_reg&lt;/span&gt;
    &lt;span class="c1"&gt;#          &amp;lt;name&amp;gt;_function&lt;/span&gt;
    &lt;span class="c1"&gt;#&lt;/span&gt;
    &lt;span class="c1"&gt;# for all the declared and needed registers, so in this example&lt;/span&gt;
    &lt;span class="c1"&gt;# we would have the following class attributes:&lt;/span&gt;
    &lt;span class="c1"&gt;#     - classifier_mark_reg&lt;/span&gt;
    &lt;span class="c1"&gt;#     - classifier_table&lt;/span&gt;
    &lt;span class="c1"&gt;#     - output_port_reg&lt;/span&gt;
    &lt;span class="c1"&gt;#     - ingress_traffic_x_function&lt;/span&gt;
    &lt;span class="c1"&gt;#     - input_tagging_function&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;A top level OpenFlow manager, used by the l2 extension manager will be
responsible of taking all the OpenFlowFunctions declared, resolving order,
and assigning table numbers and registers to every function.&lt;/p&gt;
&lt;p&gt;OpenFlowFunctions can choose the bridge or where they want to live
(provider network bridges, integration bridge, tunnel bridge), taking baby
steps we will start by supporting functions that want to live in the
integration bridge, but the bridge intention should be declared in the function
to allow future extensibility.&lt;/p&gt;
&lt;p&gt;The OpenFlowManager will inspect the declared tables default action, which
can be:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;NEXT, the lowest priority rule inserted in table jumping to next
OpenFlow function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DROP, the lowest priority rule inserted in the table drops the packet.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="description-of-the-integration-bridge-pipeline"&gt;
&lt;h3&gt;Description of the integration bridge pipeline&lt;/h3&gt;
&lt;p&gt;The pipeline is divided in two paths, from the neutron port of VM instance
point of view:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Egress path (traffic that leaves the VM/port)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ingress path (traffic that goes to a VM/port)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The pipeline looks like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;               +----------+
           +&amp;lt;--+ vm-tap-a &amp;lt;---------------+
           |   +----------+               |
           |                              |
           |   +----------+               |
           |&amp;lt;--+ vm-tap-b &amp;lt;-----+         |
           |   +--+-------+     |         |
           |                    |         |
     0+----v------------+ 253+--+---------+--+
      | initial_tagging |  |  input_stage    |
      +-----------+-----+  +--------^--------+
                  |                 |
      +-----------v-----+  +--------+--------+
 E    |  [ function A ] |  | [ function .. ] |
 G    +-----------+-----+  +--------^--------+
 R                |                 |
 E    +-----------v-----+  +--------+--------+
 S    |  [ function ..] |  | [ function F ]  |
 S    +-----------+-----+  +--------^--------+
                  |                 |
 |    +-----------v-----+  +--------+--------+   .
 |    | egress filter   |  |  ingress filter |  /|\
\|/   +-----------+-----+  +--------^--------+   |
 °                |                 |            |
      +-----------v-----+  +--------+--------+
      |  [ function C ] |  | [ function .. ] |   I
      +-----------+-----+  +--------^--------+   N
                  |                 |            G
      +-----------v-----+  +--------+--------+   R
      |  [ function ..] |  ^  [ function E ] |   E
      +-----------+-----+ /+--------^--------+   S
                  |      /          |            S
      +-----------v-----+ 0+--------+--------+
      |ingress deflector|  | initial_tagging |
      +----------+------+  +---------^-------+
                 |                   |
      +----------v------+            |
      |  output_stage   +------+     |
      +-----------+-----+      |     |
                               |     |
                             +-v-----+-------+
                             | patch-br-xxx  |
                             +---------------+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Notes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;vm-tap-a and vm-tap-b: are VMs or service ports attached to a bridge.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;patch-br-xxx: is the patch port going to bridge br-xxx&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functions can be made of several tables, it’s the responsibility of the function
to jump around its own tables or to the next function once its processing has
finished.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="openflowfunction-capabilities"&gt;
&lt;h3&gt;OpenFlowFunction capabilities&lt;/h3&gt;
&lt;p&gt;OpenFlow functions would have the right to add_flows/del_flows to normally
manipulate packets as usual in the next cases:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Drop a packet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Alter packet details&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set a queue&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;push/pop data to the stack (stack size must not change after ending function)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;learn actions in other functions belonging to the same extension&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;…&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;etc&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Special handling is required for:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;NORMAL action: normal action should not be executed immediately via action,
but a register will be marked so the specific packet will be handled with
“NORMAL” at output stage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify destination on the ingress path: the input tagging details must
be reset, and based on the locality/externality of the packet destination,
update of input tagging fields (using a helper).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Output a clone of the packet:
“output:X,goto_table:&amp;lt;next-function-first-table&amp;gt;” may be used.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Redirect packet to a new destination and stop pipeline processing (for
extensions that want to move the packet to an ancillary bridge and are
completely sure that further processing on the bridge should not happen)
will use output:X with no resubmit to next function.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Helpers will be provided, for cases like the “NORMAL” one, or packet cloning,
and we may want to consider some filter to enforce sanity of the actions.&lt;/p&gt;
&lt;p&gt;Notes:&lt;/p&gt;
&lt;p&gt;Inserted flows will have to be re-inserted by extensions by calling their
openflow functions as necessary when, for example, openvswitch has been reset
and the flows need to be recreated.&lt;/p&gt;
&lt;p&gt;We could have a DSL to define how flows are created for each function, but
that would increase the complexity of this, and we prefer to take baby steps
toward a better integration between extensions. In a future we could consider
such option we have the foundations of a first openflow pipeline.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="openflowfunction-fixed-blocks-integration-bridge"&gt;
&lt;h3&gt;OpenFlowFunction fixed blocks (integration bridge)&lt;/h3&gt;
&lt;p&gt;Some common OpenFlowFunctions are provided by the Open vSwitch agent, the agent
will declare and register those:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;INITIAL_TAGGING: Takes care of identifying the source or destination of the
packet, marks the network in a register, and sends the packet to the egress
or ingress path (with priority for egress path when both the source and
destination of the packet is local)&lt;/p&gt;
&lt;p&gt;Some extensions may want to change the destination, or duplicate packets
with new destinations. Helpers should be provided for that kind of
manipulation, so the registers will resemble the same settings done by
INITIAL_TAGGING function.&lt;/p&gt;
&lt;p&gt;The egress path has priority to cover the case when a packet is both egress
and ingress in the same bridge (source and destination ports are local
to the hypervisor)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;INGRESS_DEFLECTOR: For packets that are both egress and ingress on the
local hypervisor, this stage is in charge of moving
packets from the end of the egress path, to the start of the ingress path,
so any ingress filtering or packet processing happens before the packet
is finally sent to the output port.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;INGRESS_FILTER, EGRESS_FILTER: Is provided by the security groups
firewall driver (openvswitch firewall), if no OpenFlow filter is provided
such stage of the pipeline is reserved for the L2 filtering of the hybrid
firewall used for L2 MAC filtering to overcome the iptables/ebtables
limitations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;INPUT_STAGE: Goes after the ingress path, the packet is directed
to its destination port, or gets the NORMAL rule executed based on the
packet details. In a future revision, we could get rid of all NORMAL rules,
with that, transparent vlans and port trunking could be implemented as simple
OpenFlow functions, with no need for separate bridges.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OUTPUT_STAGE: Goes after the egress path, the packet is directed to
its destination patch port or with NORMAL, when going to another bridge.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each l2-agent extension for the Open vSwitch agent can declare one
or several functional blocks to be plugged.&lt;/p&gt;
&lt;p&gt;Every functional block can be composed of one or more OpenFlow tables.&lt;/p&gt;
&lt;p&gt;Every functional block has an entry and at least one exit point (next function).
The manager will insert a default jump to next function as the lowest priority
rule for every function table if table “default” is NEXT.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ordering-of-functions"&gt;
&lt;h3&gt;Ordering of functions&lt;/h3&gt;
&lt;p&gt;Ordering of functional blocks is defined in the manager, and maintained in the
core neutron. If somebody wants to declare a new function in the pipeline,
they can come to the community and discuss about its insertion point,
alternatively we will include common extension points that can be used
right away.&lt;/p&gt;
&lt;p&gt;COMMON prefixed points can be used by several extensions, and the ordering
between extension functions won’t be guaranteed.&lt;/p&gt;
&lt;p&gt;Extensions that require several plug points should declare all of them as
separate OpenFlow functions, and make use of them as necessary (note the
&amp;lt;&amp;gt;_&amp;lt;DIR&amp;gt;_PREFILTER / &amp;lt;&amp;gt;_&amp;lt;DIR&amp;gt;_POSTFILTER examples below)&lt;/p&gt;
&lt;p&gt;An example of the functional blocks per pipeline could be:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;EGRESS_PIPELINE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;COMMON_EGRESS_PREFILTER0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;TAAS_EGRESS_PREFILTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;BGPVPN_EGRESS_PREFILTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;SFC_EGRESS_PREFILTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;COMMON_EGRESS_PREFILTER1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;COMMON_EGRESS_FILTER0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;EGRESS_FILTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;COMMON_EGRESS_FILTER1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;COMMON_EGRESS_POSTFILTER0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;QOS_EGRESS_MIN_BW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;QOS_EGRESS_DSCP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;SFC_EGRESS_POSTFILTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;TAAS_EGRESS_POSTFILTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="n"&gt;COMMON_EGRESS_POSTFILTER1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;INGRESS_PIPELINE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;COMMON_INGRESS_PREFILTER0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;TAAS_INGRESS_PREFILTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;SFC_INGRESS_PREFILTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;COMMON_INGRESS_PREFILTER1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;COMMON_INGRESS_FILTER0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;INGRESS_FILTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;COMMON_INGRESS_FILTER1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;COMMON_INGRESS_POSTFILTER0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;TAAS_INGRESS_POSTFILTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;SFC_INGRESS_POSTFILTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;COMMON_INGRESS_POSTFILTER1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Please note that the fixed blocks (INITIAL_TAGGING, INPUT_STAGE, OUTPUT_STAGE,
INGRESS_DEFLECTOR) are not included in the configuration definition, as are
neither ingress or egress pipeline, but blocks that will steer traffic to the
right pipelines.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://www.opennetworking.org/images/stories/downloads/sdn-resources/onf-specifications/openflow/openflow-switch-v1.4.1.pdf"&gt;https://www.opennetworking.org/images/stories/downloads/sdn-resources/onf-specifications/openflow/openflow-switch-v1.4.1.pdf&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 29 Aug 2017 00:00:00 </pubDate></item><item><title>Upgrade controllers with no API downtime</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/backlog/pike/no-downtime-server-upgrade.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/online-upgrades"&gt;https://blueprints.launchpad.net/neutron/+spec/online-upgrades&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently, database migration for a new major neutron release means full
shutdown of all neutron-server instances before &lt;a class="reference external" href="http://docs.openstack.org/developer/neutron/devref/alembic_migrations.html#expand-and-contract-scripts"&gt;contract&lt;/a&gt;
alembic migration scripts are applied.&lt;/p&gt;
&lt;p&gt;When running a popular cloud, it’s usually hard or impractical to shut down all
neutron-server instances before applying all &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;contract&lt;/span&gt;&lt;/code&gt; alembic migration
scripts that may take a while, especially for databases with a lot of data to
migrate. Such a shutdown requires a significantly more elaborate planning,
trying to squeeze the upgrade process in a maintenance window with less
disruption to API users. For clouds with high SLAs, it may be impossible to
shutdown all Neutron API endpoints at one time, leaving users with no
Networking API for extended time. Due to dependencies from other services (i.e.
Nova) on Neutron API availability, upgrades have a greater impact as Neutron is
a central service in any Openstack installation.&lt;/p&gt;
&lt;p&gt;This spec describes an approach to allow for non-impacting neutron-server
upgrades, leaving instances running in a cluster. Instead of full shutdown,
operators will be able to upgrade the services in rolling mode, upgrading each
node running the service without disruption for other such nodes. If Networking
API is served by multiple nodes hidden behind a load balancer, that approach
should allow for no-downtime upgrade experience. Ideally, users would not
notice any issues accessing Neutron API services for the entirety of the
upgrade.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Running mixed major versions of neutron-server in a cloud opens the question
of how to mitigate slight differences of API behaviour between those
versions.  For example, in Newton, all resources received a new
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; field.  If we would run mixed Mitaka/Newton versions of
neutron-server behind a round robin load balancer, then consequent GET calls
for the same resource would result in different reply payloads, depending on
which particular neutron-server is hit by an API request.&lt;/p&gt;
&lt;p&gt;Enforcing consistent API behaviour for mixed version environment, or pinning
API behaviour to a version that would describe previous major version
behaviour, is &lt;em&gt;out of scope&lt;/em&gt; for the proposal. Consequent blueprints may
clarify best practices, or propose mechanisms for strict API behaviour
control.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Since neutron-server downtime derives solely from executing unsafe &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;contract&lt;/span&gt;&lt;/code&gt;
upgrade migrations while neutron-server is operational, the solution is to make
those migrations safe for online execution, or eliminate them. This is achieved
with two major changes:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Time consuming data migration changes are moved from neutron-db-manage phase
into neutron-server itself, so that data is migrated while the service is up
and serving requests, instead of while it’s fully shut down. Data migration
process will be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;lazy&lt;/span&gt;&lt;/code&gt;, happening at the time when a resource is touched
by plugin code. That said, users should not be able to switch to a next
major version before they complete migration for all remaining resources. We
will provide a tool to trigger pending migrations (preferrably in chunks)
that will become part of preparation process for next upgrade. The tool will
be modeled similar to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;online-data-migrations&lt;/span&gt;&lt;/code&gt; command found in Cinder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remaining schema contraction changes are postponed to the time when:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;all the data is migrated from old tables/columns, and&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;no neutron-server instances running in a cluster are able to access
obsolete tables/columns.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This idea is not new, other projects already got rid of unsafe migration
scripts that would require offline execution. Among those projects are Nova
and Cinder.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Data migration between multiple tables/columns implemented in neutron-server
runtime is potentially error prone and requires specific reviewer attention. It
would be impractical to expect proper attention to those intricacies for any
patch that needs to read or update a database model. So the first step is to
isolate the layer that has access to database models behind a special facade.
The base of the facade is oslo.versionedobjects and corresponding NeutronObject
framework that is already in tree and is successfully used by several features
(qos, vlan-aware-vms). The work to switch all the plugin code that accesses
database using SQLAlchemy models, to object facade, is ongoing and is tracked
as a &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/adopt-oslo-versioned-objects-for-db"&gt;separate blueprint&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once plugin code is switched to using objects for resource persistence, we can
implement any needed &lt;em&gt;data&lt;/em&gt; migration rules in a single place, in a
corresponding object class, isolating consuming code from all the complexities
of the migration/conversion process.&lt;/p&gt;
&lt;p&gt;Since in-object translation of data is lazy, at the point of next major upgrade
some resources may still have their database records not transitioned to a new
format. To facilitate next major upgrade, &lt;a class="reference external" href="https://review.openstack.org/#/c/432494/"&gt;a new neutron-db-manage CLI command
(migrate-data)&lt;/a&gt; will be implemented
that can be executed by operators before proceeding with the upgrade. The
command will migrate any remaining data models to a new format. The command
will run data migration scripts exposed via a stevedore namespace, for external
subprojects to be able to make use of it.&lt;/p&gt;
&lt;p&gt;Even with persistence facade, some work on migration mechanism and techniques
is expected. For the start, a Pike feature that would need a schema/data
migration change will be identified and used as a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;guinea&lt;/span&gt; &lt;span class="pre"&gt;pig&lt;/span&gt;&lt;/code&gt; to explore the
proposal practicalities.&lt;/p&gt;
&lt;p&gt;At the time of writing, &lt;a class="reference external" href="https://bugs.launchpad.net/bugs/1580880"&gt;port bindings rework&lt;/a&gt; is probably the best candidate to
try the new approach.&lt;/p&gt;
&lt;p&gt;As for unsafe &lt;em&gt;schema&lt;/em&gt; changes, if at release X we want to introduce a contract
migration we can only do so destructively in release X+2 (i.e. after all the
data used by X and X+1 located in the old schema is migrated), which guarantees
that whenever the deployer upgrades to X+2 (from X+1), the server instance
running behind won’t hit the data/code being affected by the schema migration.
At this point, even seemingly unsafe operations like dropping tables or columns
become safe to execute while neutron-server instances are online. For Ocata and
later, there should be no new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;contract&lt;/span&gt;&lt;/code&gt; alembic scripts at all. Those may
show up again in later releases.&lt;/p&gt;
&lt;p&gt;To achieve the goal for Newton to Ocata and later upgrades, we should guarantee
that all patches will follow decided path during Ocata and later. This will be
achieved by both automation as well as social means.&lt;/p&gt;
&lt;p&gt;For the former, we introduce a &lt;a class="reference external" href="https://review.openstack.org/#/c/400239/"&gt;functional test&lt;/a&gt; that fails on attempt to execute
an operation known to be unsafe.&lt;/p&gt;
&lt;p&gt;We will probably not be able to catch everything programmatically, so we still
need to make sure core reviewer team is aware of new requirements, and
proactively track all proposed alembic migrations at least first cycles until
it becomes a habit of an average Joe the Reviewer to spot and -1 unsafe
patches.&lt;/p&gt;
&lt;p&gt;To make sure the new upgrade mode works, a new gating grenade job will be
implemented that will run multiple neutron-server instances of different major
versions. Access to Networking API will be implemented using a lightweight load
balancer (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;haproxy&lt;/span&gt;&lt;/code&gt;) hiding multiple instances of neutron-server behind it.
We may also consider moving known consumers of Neutron API (for example, Nova)
to the ‘old’ subnode to make sure it can talk to newer as well as older Neutron
in the same setup.  Only two adjacent major versions of neutron-server will be
used in the grenade job to conform to &lt;a class="reference external" href="https://governance.openstack.org/reference/tags/assert_supports-upgrade.html#requirements"&gt;assert:supports-upgrade tag requirements&lt;/a&gt;.&lt;/p&gt;
&lt;section id="action-items"&gt;
&lt;h3&gt;Action items&lt;/h3&gt;
&lt;p&gt;(The feature assumes completion of &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/adopt-oslo-versioned-objects-for-db"&gt;adopt-oslo-versioned-objects-for-db
blueprint&lt;/a&gt;
but does not strictly depend on it.)&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Block unsafe contract migrations at the start of Ocata (&lt;em&gt;Done&lt;/em&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Explore practicalities of the proposal for data migrations for a new feature.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a voting grenade job running different major versions of neutron-server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Document new upgrade path in ops upgrades guide, with its limitations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update devref and wider audience about new requirements.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 29 Aug 2017 00:00:00 </pubDate></item><item><title>Strict minimum bandwidth support (egress)</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/backlog/pike/strict-minimum-bandwidth-support.html</link><description>

&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;RFE link: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1578989"&gt;https://bugs.launchpad.net/neutron/+bug/1578989&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Newton release added minimum bandwidth support to QoS policy
rules. While this improvement works at the hypervisor level,
it’s a best effort measure that will not prevent over-subscription
on a specific network link bandwidth (When SUM i port[i].min_bw &amp;gt;
max available bandwidth within a provider network).&lt;/p&gt;
&lt;p&gt;NFV/Telcos are interested in these types of rules to make sure
functions don’t over commit compute nodes.&lt;/p&gt;
&lt;p&gt;Cloud Service Providers could make use of this feature to provide bandwidth
guarantees for streaming.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;To provide a strict constraint we need scheduling cooperation with
Nova through integration with the new Nova placement API [1][2].&lt;/p&gt;
&lt;p&gt;Neutron L2 agents, or the specific plugin/backend will be responsible
for registering per compute resources into the placement API. L2 agents
are proposed to take this responsibility, since it mimics the design
decision in Nova where nova-compute reports resources to such API.
This has the benefit of distributing the workload across all the nodes
instead having a central service responsible of syncing to the placement
API.&lt;/p&gt;
&lt;p&gt;The resources will have the following form, please note INGRESS is
provided as a reference but it’s out of the scope of this spec:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;NIC_BW_EGRESS.&amp;lt;physical-network&amp;gt;
NIC_BW_INGRESS.&amp;lt;physical-network&amp;gt;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;physical-network will be the “physnet” in the reference implementation,
or “tunneling” in the case of requesting bandwidth on the tunneling
path.&lt;/p&gt;
&lt;p&gt;While modeling the tunneling bandwidth is not a simple thing, because it
could vary based on host routers and interfaces, we will provide this
simple model to start with.&lt;/p&gt;
&lt;p&gt;Nova will use those details to count down and manage the inventories
at its side.&lt;/p&gt;
&lt;p&gt;When Nova creates, updates or gets a port, Neutron will show the
resource counts needed by the port in the response, removing any
dependency from Nova into the Neutron QoS policy rules:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="s2"&gt;"device_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5e3898d7-11be-483e-9732-b2f5eccd2b2e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"resources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"NIC_BW_EGRESS.ext-net"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;/*&lt;/span&gt;&lt;span class="n"&gt;kbps&lt;/span&gt;&lt;span class="o"&gt;*/&lt;/span&gt;
                   &lt;span class="s2"&gt;"NIC_BW_INGRESS.ext-net"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This extra dictionary could be incorporated to the QoS extension itself,
but it makes sense to make something agnostic to the QoS extension that
other resource aware extensions could make use of.&lt;/p&gt;
&lt;p&gt;There is a common architecture in network configuration that we need to
address. It’s very common to bond several interfaces, and pass each
specific physnet or even tunneling through a VLAN on such bonding.&lt;/p&gt;
&lt;p&gt;To properly handle that case is where we need to make virtual physnets
handling the nesting, for example by providing a configuration
like this per-agent:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;virtual_physnets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bond0phys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;bond0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bond1phys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;bond1&lt;/span&gt;

&lt;span class="n"&gt;nested_physnets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bond0phys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;physnetA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bond0phys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;physnetB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; \
                  &lt;span class="n"&gt;bond0phys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;tunneling&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; \
                  &lt;span class="n"&gt;bond1phys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;physnetC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bond1phys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;physnetD&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In such case the &amp;lt;physical-network&amp;gt; part of the resources to nova would
be substituted by bond0phys for physnetA / physnetB / tunneling and
by bond1phys for physnetC and D.&lt;/p&gt;
&lt;p&gt;The extra level of indirection is provided by virtual_physnets so
interface name changes won’t de-sync the nova resources and allocations.&lt;/p&gt;
&lt;p&gt;In this specific case, the total bandwidth will be collected from bond0 and
bond1 and reported to NIC_BW_{EGRESS,INGRESS}.{bond0phys,bond1phys}, see
work item 1.&lt;/p&gt;
&lt;section id="dependencies"&gt;
&lt;h3&gt;Dependencies&lt;/h3&gt;
&lt;p&gt;We depend on several Nova changes which will allow the definition
of custom resource classes [4].&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Collecting available bandwidth from physnets on the agents
with the ability to override bandwidth in config.
Asignee: Rodolfo Alonso &amp;lt;&lt;a class="reference external" href="mailto:rodolfo.alonso.hernandez%40intel.com"&gt;rodolfo&lt;span&gt;.&lt;/span&gt;alonso&lt;span&gt;.&lt;/span&gt;hernandez&lt;span&gt;@&lt;/span&gt;intel&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write an API for sending collected bandwidth information to the
Nova placement API. For the in-tree drivers this information can be
sent right away from the agents to avoid the neutron-server bottleneck
problem. But out-of-tree drivers would have the freedom to use such API from
the QoS driver itself by, for example periodically syncing with the backend
to grab bandwidth information. Or the out-of-tree drivers could choose to
send the placement information from the backend itself to nova.
Assignee: Miguel Lavalle&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nova placement API client (custom resource classes [4])
Initial nova placement API client has already been merged [3]
Assignee: Miguel Lavalle (he’s handling it for Routed Networks)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Making the resources field available on port create/update/get for nova.
Assignee: Slawek Kaplonski&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="http://docs.openstack.org/developer/nova/placement.html"&gt;http://docs.openstack.org/developer/nova/placement.html&lt;/a&gt;
[2] &lt;a class="reference external" href="http://docs.openstack.org/developer/nova/placement_dev.html"&gt;http://docs.openstack.org/developer/nova/placement_dev.html&lt;/a&gt;
[3] &lt;a class="reference external" href="https://review.openstack.org/#/c/414726"&gt;https://review.openstack.org/#/c/414726&lt;/a&gt;
[4] &lt;a class="reference external" href="https://review.openstack.org/#/q/topic:bp/custom-resource-classes"&gt;https://review.openstack.org/#/q/topic:bp/custom-resource-classes&lt;/a&gt;
[5] &lt;a class="reference external" href="https://github.com/openstack/nova/tree/master/nova/scheduler/client"&gt;https://github.com/openstack/nova/tree/master/nova/scheduler/client&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 29 Aug 2017 00:00:00 </pubDate></item><item><title>Floating IPs for Routed Networks</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/victoria/routed-networks-floating-ips.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1667329"&gt;https://bugs.launchpad.net/neutron/+bug/1667329&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This specification proposes the implementation of floating IPs for Routed
Networks.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/newton/routed-networks.html"&gt;Neutron Routed Networks&lt;/a&gt; are composed of individual L2 segments stitched
together by L3 routers in the operator infrastructure. The operator has the
option to route the fixed IP addresses of the ports in such a network to the
external world, but this might not be feasible for IPv4 without a large enough
externally routable address range.&lt;/p&gt;
&lt;p&gt;Routed Networks were implemented in the first place to support a large number
of ports / VMs, beyond the constraints of networks based on a single L2
broadcast domain. Operators want to be able to support a number of ports / VMs
as large as possible and route a subset of them externally, without being
limited by the availability IPv4 address ranges.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This specification proposes to enable the association of ports in a Routed
Network with floating IP addresses (floating IPs). This will enable operators
and their users to create ports in routed networks with fixed IP addresses in
private ranges and assign to them scarce publicly routable IPv4 addresses only
when needed, through the association of floating IPs. This functionality will
require the changes described in the following sections.&lt;/p&gt;
&lt;section id="creation-of-subnets-spanning-segments"&gt;
&lt;h3&gt;Creation of subnets spanning segments&lt;/h3&gt;
&lt;p&gt;To support the use of floating IP’s on a routed provider network, there
needs to be a way to create a subnet that is not bound to a segment. In its
current state, a subnet cannot be created on a network without specifying a
segment when one or more subnets on the network are already bound to a
segment.&lt;/p&gt;
&lt;p&gt;A new subnet service type of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network:routed&lt;/span&gt;&lt;/code&gt; will be introduced. When a
subnet supports this service_type it can be associated to the network of a
routed provider network rather than having to be associated to one of the
segments that comprises the routed network. This provides a way of expressing
the notion of a subnet that spans the segments of a routed network. As such,
this not only supports the use of floating IP’s on routed networks but also
allows various neutron backends to handle these subnets in innovative ways.&lt;/p&gt;
&lt;p&gt;The current definition of a routed provider network is a network in which
each subnet is associated to a different segment. This definition will change
subtly and include networks where 1 or more subnets with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network:routed&lt;/span&gt;&lt;/code&gt; in
its &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;service_types&lt;/span&gt;&lt;/code&gt; is associated with the network but none of the individual
segments comprising it.&lt;/p&gt;
&lt;p&gt;To enable this, minor changes to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;_validate_segment()&lt;/span&gt;&lt;/code&gt; in
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron/db/ipam_backend_mixin.py&lt;/span&gt;&lt;/code&gt; that allow for subnets with this special
service type to exist outside of any segment.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="service-subnets-and-floating-ips-for-routed-networks"&gt;
&lt;h3&gt;Service subnets and floating IPs for routed networks&lt;/h3&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/neutron/latest/admin/config-service-subnets.html"&gt;Service subnets&lt;/a&gt; enable operators to define valid port types for each subnet
on a network, without limiting networks to one subnet or manually creating
ports with a specific subnet ID. Using this feature, operators can ensure that
ports for instances and router interfaces, for example, always use different
subnets.&lt;/p&gt;
&lt;p&gt;To allow floating IP’s to be created on a routed network, an operator will
leverage this functionality when creating the floating IP subnet. To create a
floating IP subnet that can be used on a routed provider network, the subnet
should be created with two &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;service_types&lt;/span&gt;&lt;/code&gt;: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network:routed&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network:floatingip&lt;/span&gt;&lt;/code&gt;. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network:routed&lt;/span&gt;&lt;/code&gt; allows the subnet to be pinned to
the network rather than a particular segment, and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network:floatingip&lt;/span&gt;&lt;/code&gt;
allows for floating IP’s be allocated from the subnet.&lt;/p&gt;
&lt;p&gt;No changes are anticipated to enable this to work properly. Documentation
will be updated to explain the workflow for operators. No change to the
current workflow for creating/associating/disassociating/deleting floating
IP’s will be introduced.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="dvr-and-routed-provider-networks"&gt;
&lt;h3&gt;DVR and routed provider networks&lt;/h3&gt;
&lt;p&gt;No changes to the current operation of DVR need to be made in support of
these changes. Changes to documentation will be made to reflect the fact that
subnets on segments where you wish to have floating IP gateway ports built
should be created with the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;`service_type&lt;/span&gt;&lt;/code&gt; of
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network:floatingip_agent_gateway&lt;/span&gt;&lt;/code&gt; should be used to indicate that compute
nodes can reach the routed external network on a given segment. For the
network node connectivity, a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;service_type&lt;/span&gt;&lt;/code&gt; of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network:router_gateway&lt;/span&gt;&lt;/code&gt;
should be used to indicate centralized router ports will be instantiated on
the proper segment(s).&lt;/p&gt;
&lt;p&gt;Because only the ToR device providing connectivity to the network segment
would know how to reach the floating IP (DVR will send a gratuitous ARP),
connectivity from outside the segment must be provided host routes that steer
traffic to the appropriate segment. This can be achieved by enabling
neutron-dynamic-routing, enabling it to announce FIP reachability to
ToR routers, and ensuring ToR routers propogate the FIP host route with an
appropriate next-hop. Documentation will be added to explain how this can be
set up by an operator.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="floating-ips-advertisement-with-bgp-dynamic-routing"&gt;
&lt;h3&gt;Floating IPs advertisement with BGP Dynamic Routing&lt;/h3&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/ocata/networking-guide/config-bgp-dynamic-routing.html"&gt;BGP Dynamic Routing&lt;/a&gt; is a Neutron Stadium project that enables advertisement
of self-service (private) network prefixes to physical routers that support
BGP, thus removing the conventional dependency on static routes. A &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BGP&lt;/span&gt;
&lt;span class="pre"&gt;speaker&lt;/span&gt;&lt;/code&gt; advertises the self-service network prefixes to associated &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BGP&lt;/span&gt;
&lt;span class="pre"&gt;peers&lt;/span&gt;&lt;/code&gt;, which represent the BGP capable physical routers in the operator
infrastructure.&lt;/p&gt;
&lt;p&gt;In its current state, neutron-dynamic-routing determines next-hops for floating
IP’s by identifying the relevant router and floating IP agent gateway ports
and mapping floating IP’s to their proper endpoint. In this way, it is
completely agnostic of segments and is capable of properly discovering and
announcing the correct next-hop for a /32 host route of a floating IP.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;This change is not expected to pose any new security concerns.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;No client impacts are anticipated. The network guide will be updated with
proper documentation and example configurations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="future-work"&gt;
&lt;h3&gt;Future Work&lt;/h3&gt;
&lt;p&gt;For some operators, there is a desire to allow for floating IP’s to be
associated to a port without first connecting a router to an external network
and a tenant network. This can be implemented in many ways. One way is by
relying on a cloud-init-like process to set the FIP as a loopback address
inside a VM and rely on a BGP process to announce the FIP with the fixed IP
as the next-hop address for the floating IP. With the implementation described
in previous sections in place, a similar scheme would be the next logical
iteration of routed provider networks.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~ryan-tidwell"&gt;Ryan Tidwell&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~minsel"&gt;Miguel Lavalle&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Introduce the new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network:routed&lt;/span&gt;&lt;/code&gt; subnet service type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refactor network segment integrity checks to allow subnets with a
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;service_type&lt;/span&gt;&lt;/code&gt; of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network:routed&lt;/span&gt;&lt;/code&gt; to be associated directly to a
network.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;There are currently no tempest tests for routed provider networks. However,
some tests are being developed and tests that cover floating IP creation on
routed provider networks can eventually be added to these tests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Unknown&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;The following tests can be added to the suite of scenario tests being developed
in &lt;a class="reference external" href="https://review.opendev.org/#/c/665155/"&gt;https://review.opendev.org/#/c/665155/&lt;/a&gt; :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Floating IP subnets can be created on a routed provider network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Floating IP’s can be created on a routed provider network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Floating IP’s from the same subnet can be associated to ports across
different segments&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests in neutron-dynamic-routing to assert proper route discovery on
routed provider networks&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Document new behavior for creating floating IP subnets&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Document how to use in conjunction with neutron-dynamic-routing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Example configurations of routed networks, ToR router BGP config, and
neutron-dynamic-routing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;A new section to the Neutron devref will be added describing the implementation
of floating IPs for routed networks.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Sun, 23 Jul 2017 00:00:00 </pubDate></item><item><title>QoS improved validation mechanism for rules and port types</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/pike/qos-improved-validation-mechanism-rules.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1586056"&gt;https://bugs.launchpad.net/neutron/+bug/1586056&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;While the QoS service models an abstraction of rules that can be applied
to port packets by different plugins, it’s currently not able to correctly
handle the variety of different port types existing in a deployment,
or specific limitations of certain plugins or technologies.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The administrator may desire, and it’s something common,
to mix openvswitch and SR-IOV. While SR-IOV is used for higher throughput
functions, ovs is there for handling normal VM loads.&lt;/p&gt;
&lt;p&gt;One of the first differences we will find in SR-IOV is that, it’s not able
to limit bandwidth in both directions, while OVS and Linuxbridge are able.&lt;/p&gt;
&lt;section id="policy-compatibility"&gt;
&lt;h3&gt;Policy compatibility&lt;/h3&gt;
&lt;p&gt;For example, the DSCP marking rule is currently implemented in OVS alone, this
means that a QoS policy applied to a linuxbridge or sr-iov bound port won’t be
fully realized.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rule-compatibility"&gt;
&lt;h3&gt;Rule compatibility&lt;/h3&gt;
&lt;p&gt;If we look at rule validation, we are planning on expanding existing rules
with new parameters [3], but in such cases some mechanisms declaring themselves as
supporters of such rule may not support the specific parameter (direction, traffic
classification, etc..). In the case of non-ml2 plugins, some types of ports may not
support specific parameters as well (based on the nature of the port).&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;We propose validation changes to policies, rules parameters, ports (qos-policy) and
networks (qos-policy) at the API level. As a result when a conflicting change
is detected, such conflict is immediately reported to the API caller, and the
operation is stopped with a 409 HTTP Conflict error:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ neutron qos-&amp;lt;type&amp;gt;-rule-update &amp;lt;pol-id&amp;gt; &amp;lt;rule-id&amp;gt; -&amp;lt;parameter&amp;gt; &amp;lt;value&amp;gt;
Error: you have a port (&amp;lt;port id&amp;gt;) of type (..) attached to that rule,
       which is unable to accept &amp;lt;parameter&amp;gt;=&amp;lt;value&amp;gt;.
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In the context of ML2, the mechanism drivers will define not only the rule types
they support, but also the parameter values, going from:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;supported_qos_rule_types&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;qos_consts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RULE_TYPE_BANDWIDTH_LIMIT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="n"&gt;qos_consts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RULE_TYPE_DSCP_MARK&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;to:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;supported_qos_rule_types&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;qos_consts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RULE_TYPE_BANDWIDTH_LIMIT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"max_kbps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;qos_consts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ANY_VALUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"max_burst_kbps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;qos_consts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ANY_VALUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"parameter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"value1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"value2"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                    &lt;span class="s2"&gt;"parameter2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parameter2Validator&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;qos_consts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RULE_TYPE_DSCP_MARK&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"dscp_mark"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;qos_consts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ANY_VALUE&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For validations which can’t be handled by simple list, another validator class will be provided
to be subclassed which will require a validation and a description of how the validation is
accomplished (To make sure we have a verbose description in place if we wanted to report
capabilities in the future, or to provide more meaningful errors to users of the API).&lt;/p&gt;
&lt;p&gt;A different mechanism driver not supporting the new “parameter” would have a declaration as
follows, where “parameter” is not declared in the dictionary:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;supported_qos_rule_types&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;qos_consts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RULE_TYPE_BANDWIDTH_LIMIT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"max_kbps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;qos_consts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ANY_VALUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"max_burst_kbps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;qos_consts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ANY_VALUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;qos_consts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RULE_TYPE_DSCP_MARK&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"dscp_mark"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;qos_consts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ANY_VALUE&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Where Parameter2Validator example, and the generic class for validation would look like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ParameterValidator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="nd"&gt;@abc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Parameter2Validator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ParameterValidator&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Validates that parameter2 is higher than two"&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Updating existing mechanism drivers to expose the new details will be necessary,
but we will provide one cycle with support for the old form, and deprecation notice
for existing out-of-tree mechanism drivers.&lt;/p&gt;
&lt;p&gt;New functions will be added to the QoS service plugin “notification” interface:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;validate_policy_for_port&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;validate_policy_for_network&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;network_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For the second function, the base driver provides a default implementation
that will fetch the network ports and iterate over validate_policy_for_port,
but can be overriden by the implementation.&lt;/p&gt;
&lt;p&gt;This will be responsible for verifying the policy/port pairs, and
throwing a detailed exception in case of a conflicting case.&lt;/p&gt;
&lt;p&gt;In ML2, we propose to use the in process callbacks to validate the
BEFORE_CREATE/BEFORE_UPDATE of NETWORK and PORT objects. While the
modification of rules will be handled by the QoS plugin alone
consuming the validate_policy_for_port function that will be provided
by the implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1586056"&gt;https://bugs.launchpad.net/neutron/+bug/1586056&lt;/a&gt;
[2] &lt;a class="reference external" href="https://review.openstack.org/#/c/319694/"&gt;https://review.openstack.org/#/c/319694/&lt;/a&gt;
[3] &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1560961"&gt;https://bugs.launchpad.net/neutron/+bug/1560961&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 03 May 2017 00:00:00 </pubDate></item><item><title>Neutron-vpnaas Scorecard</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stadium/pike/neutron-vpnaas.html</link><description>

&lt;section id="neutron-integration"&gt;
&lt;h2&gt;Neutron integration&lt;/h2&gt;
&lt;ul id="n0"&gt;
&lt;li&gt;&lt;p&gt;N0. Does the project use the Neutron REST API or relies on proprietary backends?&lt;/p&gt;
&lt;p&gt;Yes. Neutron-vpnaas implements its own set of Neutron API extensions on top of
the Neutron core framework and it does so by using the service plugin model.
The API exposed has open source implementations, and it provides a pluggable
mechanism for proprietary backends.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n1"&gt;
&lt;li&gt;&lt;p&gt;N1. Does the project integrate/use neutron-lib?&lt;/p&gt;
&lt;p&gt;Yes. The migration report shows that there are currently 598 total imports.
Neutron is imported 112 times and Neutron-lib 77 times, for a migration
percentage of 40.7400%.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n2"&gt;
&lt;li&gt;&lt;p&gt;N2. Do project members actively contribute to help neutron-lib achieve its
goal?&lt;/p&gt;
&lt;p&gt;No. None of the project core members have merged anything meaningful into neutron-lib
(source: &lt;a class="reference external" href="https://review.openstack.org/#/q/project:openstack/neutron-lib+status:merged,75"&gt;https://review.openstack.org/#/q/project:openstack/neutron-lib+status:merged,75&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n3"&gt;
&lt;li&gt;&lt;p&gt;N3. Do project members collaborate with the core team to enable subprojects
to loosely integrate with the Neutron core platform by helping with the definition
of modular interfaces?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-vpnaas/commit/7c10c41376f10898347cbc644d8d504b8258c99c"&gt;https://github.com/openstack/neutron-vpnaas/commit/7c10c41376f10898347cbc644d8d504b8258c99c&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n4"&gt;
&lt;li&gt;&lt;p&gt;N4. How does the project provide networking services? Does it use modular interfaces
as provided by the core platform?&lt;/p&gt;
&lt;p&gt;Yes, for the most part, but as far as the agent side is concerned, the project relies
on the use of a VPN agent that specializes the base L3 agent, this is prone to breakage,
and leads to deployment complications when VPN and L3 services are deployed together.
This problem has been filed as a bug to track the work. And it is being working slowly.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-vpnaas/blob/master/neutron_vpnaas/services/vpn/agent.py#L46"&gt;https://github.com/openstack/neutron-vpnaas/blob/master/neutron_vpnaas/services/vpn/agent.py#L46&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1692128"&gt;https://bugs.launchpad.net/neutron/+bug/1692128&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/488247/"&gt;https://review.openstack.org/#/c/488247/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n5"&gt;
&lt;li&gt;&lt;p&gt;N5. If the project provides new API extensions, have API extensions been discussed
and accepted by the Neutron drivers team? Please provide links to API specs, if
required.&lt;/p&gt;
&lt;p&gt;VPNaaS API was initially created by the neutron core team, and so implicitly had been
agreed upon by previous core team.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul id="d1"&gt;
&lt;li&gt;&lt;p&gt;D1. Does the project have a doc tox target, functional and continuously
working? Provide proof (links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini"&gt;https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs-draft.openstack.org/09/480809/2/gate/gate-neutron-vpnaas-docs-ubuntu-xenial/8209306//doc/build/html/"&gt;http://docs-draft.openstack.org/09/480809/2/gate/gate-neutron-vpnaas-docs-ubuntu-xenial/8209306//doc/build/html/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d2"&gt;
&lt;li&gt;&lt;p&gt;D2. If the project provide API extensions, does the project have an
api-ref tox target, functional and continously working? Provide proof
(links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes. There is an API reference and is being confirmed its accuracy, see:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/447345/"&gt;https://review.openstack.org/#/c/447345/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://developer.openstack.org/api-ref/networking/"&gt;http://developer.openstack.org/api-ref/networking/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-lib/blob/master/api-ref/source/v2/vpnaas.inc"&gt;https://github.com/openstack/neutron-lib/blob/master/api-ref/source/v2/vpnaas.inc&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d3"&gt;
&lt;li&gt;&lt;p&gt;D3. Does the project have a releasenotes tox target, functional and
continously working? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini"&gt;https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/releasenotes/neutron-vpnaas/"&gt;http://docs.openstack.org/releasenotes/neutron-vpnaas/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs-draft.openstack.org/74/483374/2/check/gate-neutron-vpnaas-releasenotes/f8f42ee//releasenotes/build/html/"&gt;http://docs-draft.openstack.org/74/483374/2/check/gate-neutron-vpnaas-releasenotes/f8f42ee//releasenotes/build/html/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d4"&gt;
&lt;li&gt;&lt;p&gt;D4. Describe the types of documentation available: developer, end user,
administrator, deployer.&lt;/p&gt;
&lt;p&gt;Yes. These documentations are going to be published, see:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/482510/"&gt;https://review.openstack.org/#/c/482510/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/446835/"&gt;https://review.openstack.org/#/c/446835/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs-draft.openstack.org/26/303226/26/check/gate-neutron-vpnaas-docs-ubuntu-xenial/3776f6d//doc/build/html/"&gt;http://docs-draft.openstack.org/26/303226/26/check/gate-neutron-vpnaas-docs-ubuntu-xenial/3776f6d//doc/build/html/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs-draft.openstack.org/10/482510/1/check/gate-neutron-docs-ubuntu-xenial/9a5a443//doc/build/html/admin/vpnaas-scenario.html"&gt;http://docs-draft.openstack.org/10/482510/1/check/gate-neutron-docs-ubuntu-xenial/9a5a443//doc/build/html/admin/vpnaas-scenario.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="continuous-integration"&gt;
&lt;h2&gt;Continuous Integration&lt;/h2&gt;
&lt;ul id="c1"&gt;
&lt;li&gt;&lt;p&gt;C1. Does the project have a Grafana dashboard showing historical trends of
all the jobs available? Provide proof (links to grafana.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://grafana.openstack.org/dashboard/db/neutron-vpnaas-failure-rates"&gt;http://grafana.openstack.org/dashboard/db/neutron-vpnaas-failure-rates&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c2"&gt;
&lt;li&gt;&lt;p&gt;C2. Does the project have CI for unit coverage? Provide proof (links to
logs.openstack.org)&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/g/project/openstack~2Fneutron-vpnaas"&gt;http://status.openstack.org/openstack-health/#/g/project/openstack~2Fneutron-vpnaas&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c3"&gt;
&lt;li&gt;&lt;p&gt;C3. Does the project have CI for functional coverage? If so, does it include
DB migration and sync validation?&lt;/p&gt;
&lt;p&gt;Yes. We have gate-neutron-vpnaas-dsvm-functional-sswan-ubuntu-xenial for
functional coverage and DB migration tests are running as a part of it.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/job/gate-neutron-vpnaas-dsvm-functional-sswan-ubuntu-xenial"&gt;http://status.openstack.org/openstack-health/#/job/gate-neutron-vpnaas-dsvm-functional-sswan-ubuntu-xenial&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c4"&gt;
&lt;li&gt;&lt;p&gt;C4. Does the project have CI for fullstack coverage?&lt;/p&gt;
&lt;p&gt;No. We consider it as lower priority and it has none at the moment.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c5"&gt;
&lt;li&gt;&lt;p&gt;C5. Does the project have CI for Tempest coverage? If so, specify nature
(API and/or Scenario).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/89/475289/1/gate/gate-neutron-dsvm-tempest-vpnaas-ubuntu-xenial/4096e05/testr_results.html.gz"&gt;http://logs.openstack.org/89/475289/1/gate/gate-neutron-dsvm-tempest-vpnaas-ubuntu-xenial/4096e05/testr_results.html.gz&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c6"&gt;
&lt;li&gt;&lt;p&gt;C6. Does the project require CI for Grenade coverage?&lt;/p&gt;
&lt;p&gt;Yes. But it has none.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c7"&gt;
&lt;li&gt;&lt;p&gt;C7. Does the project provide multinode CI?&lt;/p&gt;
&lt;p&gt;No. But it is needed to support L3-HA (and/or DVR) and unnecessary until then.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c8"&gt;
&lt;li&gt;&lt;p&gt;C8. Does the project support Python 3.x? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/job/gate-neutron-vpnaas-python35"&gt;http://status.openstack.org/openstack-health/#/job/gate-neutron-vpnaas-python35&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="release-footprint"&gt;
&lt;h2&gt;Release footprint&lt;/h2&gt;
&lt;ul id="r1"&gt;
&lt;li&gt;&lt;p&gt;R1. Does the project adopt semver?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r2"&gt;
&lt;li&gt;&lt;p&gt;R2. Does the project have release deliverables? Provide proof as available
in the &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/"&gt;release repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://tarballs.openstack.org/neutron-vpnaas/neutron-vpnaas-10.0.0.tar.gz"&gt;https://tarballs.openstack.org/neutron-vpnaas/neutron-vpnaas-10.0.0.tar.gz&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r3"&gt;
&lt;li&gt;&lt;p&gt;R3. Does the project use upper-constraints?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini#L10"&gt;https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini#L10&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="r4"&gt;
&lt;li&gt;&lt;p&gt;R4. Does the project integrate with OpenStack Proposal Bot for requirements updates?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Yes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/requirements/commit/1d545edbebfff2e8983d6cab24a92c32636dd6bf"&gt;https://github.com/openstack/requirements/commit/1d545edbebfff2e8983d6cab24a92c32636dd6bf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="stable-backports"&gt;
&lt;h2&gt;Stable backports&lt;/h2&gt;
&lt;ul id="s1"&gt;
&lt;li&gt;&lt;p&gt;S1. Does the project have stable branches and/or tags? Provide history of
backports.&lt;/p&gt;
&lt;p&gt;Yes. For example: &lt;a class="reference external" href="https://git.openstack.org/cgit/openstack/neutron-vpnaas/log/?h=stable/ocata"&gt;https://git.openstack.org/cgit/openstack/neutron-vpnaas/log/?h=stable/ocata&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="client-library"&gt;
&lt;h2&gt;Client library&lt;/h2&gt;
&lt;ul id="l1"&gt;
&lt;li&gt;&lt;p&gt;L1. If the project requires a client library, how does it implement CLI and
API bindings?&lt;/p&gt;
&lt;p&gt;Yes. There are Neutron CLI and API bindings. OSC is going to be done, see:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/439978/"&gt;https://review.openstack.org/#/c/439978/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="scorecard"&gt;
&lt;h2&gt;Scorecard&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Scorecard&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n0"&gt;N0&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n1"&gt;N1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n2"&gt;N2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n4"&gt;N4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n5"&gt;N5&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d1"&gt;D1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d3"&gt;D3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c2"&gt;C2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c3"&gt;C3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c4"&gt;C4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c6"&gt;C6&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c7"&gt;C7&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c8"&gt;C8&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r1"&gt;R1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r2"&gt;R2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r3"&gt;R3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r4"&gt;R4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#s1"&gt;S1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="final-remarks"&gt;
&lt;h2&gt;Final remarks&lt;/h2&gt;
&lt;p&gt;At the time of writing the project scores changed to positively if compared
with the last assessment &lt;a class="footnote-reference brackets" href="#id3" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id4" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; for following 6 criteria: &lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt;, &lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt;, &lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt;,
&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt;, &lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt;, &lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt;. It makes the project scores positively in 19 out of 24 criteria.
The subproject does not seem to lack the resources recently and the remaining
gaps can be focused to make timely progress when required.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata/neutron-vpnaas.html#scorecard"&gt;https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata/neutron-vpnaas.html#scorecard&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata.html#summary"&gt;https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata.html#summary&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Fri, 31 Mar 2017 00:00:00 </pubDate></item><item><title>&amp;lt;Project&amp;gt; Scorecard</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stadium/pike/placeholder.html</link><description>

&lt;p&gt;This document template is meant to be used as a scorecard to assess how
a project eligible for inclusion meets the Neutron Stadium requirements
as defined in this &lt;a class="reference external" href="http://specs.openstack.org/openstack/neutron-specs/specs/newton/neutron-stadium.html"&gt;specification&lt;/a&gt;.
If the outcome of the assessment is negative, the project inclusion is
rejected.&lt;/p&gt;
&lt;section id="neutron-integration"&gt;
&lt;h2&gt;Neutron integration&lt;/h2&gt;
&lt;ul class="simple" id="n0"&gt;
&lt;li&gt;&lt;p&gt;N0. Does the project use the Neutron REST API or rely on proprietary backends?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="n1"&gt;
&lt;li&gt;&lt;p&gt;N1. Does the project integrate/use neutron-lib?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="n2"&gt;
&lt;li&gt;&lt;p&gt;N2. Do project members actively contribute to help neutron-lib achieve its
goal?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="n3"&gt;
&lt;li&gt;&lt;p&gt;N3. Do project members collaborate with the core team to enable subprojects
to loosely integrate with the Neutron core platform by helping with the definition
of modular interfaces?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="n4"&gt;
&lt;li&gt;&lt;p&gt;N4. How does the project provide networking services? Does it use modular interfaces
as provided by the core platform?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="n5"&gt;
&lt;li&gt;&lt;p&gt;N5. If the project provides new API extensions, have API extensions been discussed
and accepted by the Neutron drivers team? Please provide links to API specs, if
required.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul class="simple" id="d1"&gt;
&lt;li&gt;&lt;p&gt;D1. Does the project have a doc tox target, functional and continuously
working? Provide proof (e.g. links to logs.openstack.org).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="d2"&gt;
&lt;li&gt;&lt;p&gt;D2. If the project provides API extensions, does the project have an
api-ref tox target, functional and continuously working? Provide proof
(e.g. links to logs.openstack.org).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="d3"&gt;
&lt;li&gt;&lt;p&gt;D3. Does the project have a releasenotes tox target, functional and
continuously working? Provide proof.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="d4"&gt;
&lt;li&gt;&lt;p&gt;D4. Describe the types of documentation available: developer, end user,
administrator, deployer.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="continuous-integration"&gt;
&lt;h2&gt;Continuous Integration&lt;/h2&gt;
&lt;ul class="simple" id="c1"&gt;
&lt;li&gt;&lt;p&gt;C1. Does the project have a Grafana dashboard showing historical trends of
all the jobs available? Provide proof (links to grafana.openstack.org).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="c2"&gt;
&lt;li&gt;&lt;p&gt;C2. Does the project have CI for unit coverage? Provide proof (links to
logs.openstack.org).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="c3"&gt;
&lt;li&gt;&lt;p&gt;C3. Does the project have CI for functional coverage? If so, does it include
DB migration and sync validation?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="c4"&gt;
&lt;li&gt;&lt;p&gt;C4. Does the project have CI for fullstack coverage?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="c5"&gt;
&lt;li&gt;&lt;p&gt;C5. Does the project have CI for Tempest coverage? If so, specify nature
(API and/or Scenario).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="c6"&gt;
&lt;li&gt;&lt;p&gt;C6. How does a project validate upgrades on a continuous basis? Does
the project require or support CI for Grenade coverage?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="c7"&gt;
&lt;li&gt;&lt;p&gt;C7. Does the project provide multinode CI?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="c8"&gt;
&lt;li&gt;&lt;p&gt;C8. Does the project support Python 3.x? Provide proof.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="release-footprint"&gt;
&lt;h2&gt;Release footprint&lt;/h2&gt;
&lt;ul class="simple" id="r1"&gt;
&lt;li&gt;&lt;p&gt;R1. Does the project adopt &lt;a class="reference external" href="http://semver.org/"&gt;SemVer&lt;/a&gt;?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="r2"&gt;
&lt;li&gt;&lt;p&gt;R2. Does the project have release deliverables? Provide proof as available
in the &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/"&gt;release repo&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="r3"&gt;
&lt;li&gt;&lt;p&gt;R3. Does the project use upper-constraints?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="r4"&gt;
&lt;li&gt;&lt;p&gt;Does the project integrate with OpenStack Proposal Bot for requirements updates?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="stable-backports"&gt;
&lt;h2&gt;Stable backports&lt;/h2&gt;
&lt;ul class="simple" id="s1"&gt;
&lt;li&gt;&lt;p&gt;S1. Does the project have stable branches and/or tags? Provide history of
backports.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="client-library"&gt;
&lt;h2&gt;Client library&lt;/h2&gt;
&lt;ul class="simple" id="l1"&gt;
&lt;li&gt;&lt;p&gt;L1. If the project requires a client library, how does it implement CLI and
API bindings?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="scorecard"&gt;
&lt;h2&gt;Scorecard&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Scorecard&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n0"&gt;N0&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n1"&gt;N1&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n2"&gt;N2&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n4"&gt;N4&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n5"&gt;N5&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d1"&gt;D1&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d3"&gt;D3&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c2"&gt;C2&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c3"&gt;C3&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c4"&gt;C4&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c6"&gt;C6&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c7"&gt;C7&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c8"&gt;C8&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r1"&gt;R1&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r2"&gt;R2&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r3"&gt;R3&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r4"&gt;R4&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#s1"&gt;S1&lt;/a&gt; |&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Final remarks: (To be compiled by PTL).&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 14 Mar 2017 00:00:00 </pubDate></item><item><title>Networking-midonet Scorecard</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata/networking-midonet.html</link><description>

&lt;section id="neutron-integration"&gt;
&lt;h2&gt;Neutron integration&lt;/h2&gt;
&lt;ul id="n0"&gt;
&lt;li&gt;&lt;p&gt;N0. Does the project use the Neutron REST API or relies on proprietary backends?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n1"&gt;
&lt;li&gt;&lt;p&gt;N1. Does the project integrate/use neutron-lib?&lt;/p&gt;
&lt;p&gt;Yes. Of the total ~200 neutron related imports, neutron-lib is imported
roughly ~20% of the time. The project has a periodic job against
master neutron-lib changes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/job/periodic-networking-midonet-py35-with-neutron-lib-master"&gt;http://status.openstack.org/openstack-health/#/job/periodic-networking-midonet-py35-with-neutron-lib-master&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n2"&gt;
&lt;li&gt;&lt;p&gt;N2. Do project members actively contribute to help neutron-lib achieve its
goal?&lt;/p&gt;
&lt;p&gt;No, besides occasional review.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n3"&gt;
&lt;li&gt;&lt;p&gt;N3. Do project members collaborate with the core team to enable subprojects
to loosely integrate with the Neutron core platform by helping with the definition
of modular interfaces?&lt;/p&gt;
&lt;p&gt;Yes, on some areas like QoS.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n4"&gt;
&lt;li&gt;&lt;p&gt;N4. How does the project provide networking services? Does it use modular interfaces
as provided by the core platform?&lt;/p&gt;
&lt;p&gt;It provides ML2 driver and a set of service plugins including L3, which communicate
with midonet using via midonet REST API. Midonet and its agents provide networking
services accordingly. Optionally it can be configured to work with neutron agents
(like neutron dhcp/metadata agents) at the time of writing it also provides monolithic
core plugins but they are planned to be replaced by the ML2 driver.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n5"&gt;
&lt;li&gt;&lt;p&gt;N5. If the project provides new API extensions, have API extensions been discussed
and accepted by the Neutron drivers team? Please provide links to API specs, if
required.&lt;/p&gt;
&lt;p&gt;It has several extensions: &lt;a class="reference external" href="http://docs.openstack.org/developer/networking-midonet/specs/kilo/agent_membership.html"&gt;agent-management&lt;/a&gt;
is planned to be deprecated and removed; &lt;a class="reference external" href="http://docs.openstack.org/developer/networking-midonet/specs/mitaka/bgp-speaker-router-insertion.html"&gt;bgp-speaker-router-insertion&lt;/a&gt;
is an extension to neutron-dynamic-routing. It is being tracked by RFE
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1583184"&gt;https://bugs.launchpad.net/neutron/+bug/1583184&lt;/a&gt;; &lt;a class="reference external" href="http://docs.openstack.org/developer/networking-midonet/specs/mitaka/router-interface-fip.html"&gt;router-interface-fip&lt;/a&gt;.
It is being tracked by RFE &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1566191"&gt;https://bugs.launchpad.net/neutron/+bug/1566191&lt;/a&gt;.
&lt;a class="reference external" href="http://docs.openstack.org/developer/networking-midonet/specs/mitaka/logging-API-for-firewall-rules.html"&gt;logging-resource&lt;/a&gt;
is slightly matching spec proposal &lt;a class="reference external" href="https://review.openstack.org/#/c/203509"&gt;https://review.openstack.org/#/c/203509&lt;/a&gt;; finally,
&lt;a class="reference external" href="http://docs.openstack.org/developer/networking-midonet/specs/kilo/device_management.html"&gt;gateway-device&lt;/a&gt;
which may match L2GW’s l2-border-gateway api instead. None of these extensions have been
reviewed and accepted by the Neutron drivers team.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/networking-midonet/specs/index.html"&gt;http://docs.openstack.org/developer/networking-midonet/specs/index.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul id="d1"&gt;
&lt;li&gt;&lt;p&gt;D1. Does the project have a doc tox target, functional and continuously
working? Provide proof (links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/networking-midonet/"&gt;http://docs.openstack.org/developer/networking-midonet/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d2"&gt;
&lt;li&gt;&lt;p&gt;D2. If the project provide API extensions, does the project have an
api-ref tox target, functional and continously working? Provide proof
(links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d3"&gt;
&lt;li&gt;&lt;p&gt;D3. Does the project have a releasenotes tox target, functional and
continously working? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/releasenotes/networking-midonet/"&gt;http://docs.openstack.org/releasenotes/networking-midonet/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d4"&gt;
&lt;li&gt;&lt;p&gt;D4. Describe the types of documentation available: developer, end user,
administrator, deployer.&lt;/p&gt;
&lt;p&gt;Developer and admin documentation is available. End user documentation
for client extensions does not seem to be available.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/networking-midonet/"&gt;http://docs.openstack.org/developer/networking-midonet/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="continuous-integration"&gt;
&lt;h2&gt;Continuous Integration&lt;/h2&gt;
&lt;ul id="c1"&gt;
&lt;li&gt;&lt;p&gt;C1. Does the project have a Grafana dashboard showing historical trends of
all the jobs available? Provide proof (links to grafana.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://grafana.openstack.org/dashboard/db/networking-midonet-failure-rate"&gt;http://grafana.openstack.org/dashboard/db/networking-midonet-failure-rate&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c2"&gt;
&lt;li&gt;&lt;p&gt;C2. Does the project have CI for unit coverage? Provide proof (links to
logs.openstack.org)&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/g/project/openstack~2Fnetworking-midonet"&gt;http://status.openstack.org/openstack-health/#/g/project/openstack~2Fnetworking-midonet&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c3"&gt;
&lt;li&gt;&lt;p&gt;C3. Does the project have CI for functional coverage? If so, does it include
DB migration and sync validation?&lt;/p&gt;
&lt;p&gt;No, but DB migration and validation is achieved via unit testing job.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c4"&gt;
&lt;li&gt;&lt;p&gt;C4. Does the project have CI for fullstack coverage?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c5"&gt;
&lt;li&gt;&lt;p&gt;C5. Does the project have CI for Tempest coverage? If so, specify nature
(API and/or Scenario).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/job/gate-tempest-dsvm-networking-midonet-v2"&gt;http://status.openstack.org/openstack-health/#/job/gate-tempest-dsvm-networking-midonet-v2&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c6"&gt;
&lt;li&gt;&lt;p&gt;C6. Does the project require CI for Grenade coverage?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c7"&gt;
&lt;li&gt;&lt;p&gt;C7. Does the project provide multinode CI?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c8"&gt;
&lt;li&gt;&lt;p&gt;C8. Does the project support Python 3.x? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/job/gate-networking-midonet-python35-db"&gt;http://status.openstack.org/openstack-health/#/job/gate-networking-midonet-python35-db&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="release-footprint"&gt;
&lt;h2&gt;Release footprint&lt;/h2&gt;
&lt;ul class="simple" id="r1"&gt;
&lt;li&gt;&lt;p&gt;R1. Does the project adopt semver?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul id="r2"&gt;
&lt;li&gt;&lt;p&gt;R2. Does the project have release deliverables? Provide proof as available
in the &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/"&gt;release repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/deliverables/_independent/networking-midonet.yaml"&gt;http://git.openstack.org/cgit/openstack/releases/tree/deliverables/_independent/networking-midonet.yaml&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r3"&gt;
&lt;li&gt;&lt;p&gt;R3. Does the project use upper-constraints?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/networking-midonet/blob/master/tox.ini#L10"&gt;https://github.com/openstack/networking-midonet/blob/master/tox.ini#L10&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r4"&gt;
&lt;li&gt;&lt;p&gt;Does the project integrate with OpenStack Proposal Bot for requirements updates?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/requirements/commit/6f6bf9bfb70e22141041ce61f17c932c9c110d90"&gt;https://github.com/openstack/requirements/commit/6f6bf9bfb70e22141041ce61f17c932c9c110d90&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="stable-backports"&gt;
&lt;h2&gt;Stable backports&lt;/h2&gt;
&lt;ul id="s1"&gt;
&lt;li&gt;&lt;p&gt;S1. Does the project have stable branches and/or tags? Provide history of
backports.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/q/project:openstack/networking-midonet+branch:stable/mitaka"&gt;https://review.openstack.org/#/q/project:openstack/networking-midonet+branch:stable/mitaka&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/q/project:openstack/networking-midonet+branch:stable/liberty"&gt;https://review.openstack.org/#/q/project:openstack/networking-midonet+branch:stable/liberty&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="client-library"&gt;
&lt;h2&gt;Client library&lt;/h2&gt;
&lt;ul id="l1"&gt;
&lt;li&gt;&lt;p&gt;L1. If the project requires a client library, how does it implement CLI and
API bindings?&lt;/p&gt;
&lt;p&gt;There are neutronclient extensions but no OSC mapping.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="scorecard"&gt;
&lt;h2&gt;Scorecard&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Scorecard&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n0"&gt;N0&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n1"&gt;N1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n2"&gt;N2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n4"&gt;N4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n5"&gt;N5&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d1"&gt;D1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d3"&gt;D3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c2"&gt;C2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c3"&gt;C3&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c4"&gt;C4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c6"&gt;C6&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c7"&gt;C7&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c8"&gt;C8&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r1"&gt;R1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r2"&gt;R2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r3"&gt;R3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r4"&gt;R4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#s1"&gt;S1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Final remarks: overall networking-midonet is well managed. Its scope is a lot
wider than other subprojects as it covers almost the entirety of the networking
spectrum that Neutron provides. Some may consider networking-midonet a lot
closer to Dragonflow and Astara in terms of scope than networking-ovn or
neutron-dynamic-routing to name a few examples. Gaps in API documentation,
specs approval and client mappings will need to be addressed.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 23 Jan 2017 00:00:00 </pubDate></item><item><title>A10 Networks LBaaS Driver</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/a10networks-lbaas-driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/a10networks-lbaas-driver"&gt;https://blueprints.launchpad.net/neutron/+spec/a10networks-lbaas-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Resubmitting Icehouse BP.  Neutron/LBaaS driver for A10 Networks appliances.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The new driver would allow using A10 Networks ADC appliances (hardware or
software) as backends for Neutron/LBaaS functionality.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The driver will implement the interfaces in the lbaas abstract_driver, using
axAPI version 2.1, a JSON HTTP interface for configuring A10 appliances.  The
currently implemented methods are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create_vip&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update_vip&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete_vip&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create_pool&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update_pool&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete_pool&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;stats&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create_member&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update_member&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete_member&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update_pool_health_monitor&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create_pool_health_monitor&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete_pool_health_monitor&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Among the current LBaaS functionality (as of Icehouse), the only unsupported
feature is APP_COOKIE persistence.&lt;/p&gt;
&lt;p&gt;Driver will support  the upcoming Juno LBaaS object model changes.  Juno TLS support will be included in a future blueprint.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee: &lt;a class="reference external" href="https://launchpad.net/~dougwig"&gt;https://launchpad.net/~dougwig&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A10 driver code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Voting CI&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Driver likely affected by LBaaS model and TLS changes for Juno:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-ssl-termination"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-ssl-termination&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A10 QA&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Existing LBaaS tests provide complete coverage, if driver is installed
and configured (as our CI will do.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Not testable in gate, requires hardware.  Third party CI will be in place.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Github repo: &lt;a class="reference external" href="https://github.com/a10networks/a10_lbaas_driver"&gt;https://github.com/a10networks/a10_lbaas_driver&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;axAPI reference and examples: &lt;a class="reference external" href="http://www.a10networks.com/products/axseries-aXAPI.php"&gt;http://www.a10networks.com/products/axseries-aXAPI.php&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Old description doc: &lt;a class="reference external" href="https://docs.google.com/file/d/0B2tCOk4L0wErdEpfdGtPMXpqM0k/edit"&gt;https://docs.google.com/file/d/0B2tCOk4L0wErdEpfdGtPMXpqM0k/edit&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Fri, 20 Jan 2017 00:00:00 </pubDate></item><item><title>IPv6 support in Metadata service</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/ussuri/metadata-add-ipv6-support.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1460177"&gt;https://bugs.launchpad.net/neutron/+bug/1460177&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Adding IPv6 support for Metadata service.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The metadata service uses the well-known IP 169.254.169.254 as its endpoint
address. This doesn’t work in an IPv6-only environment.&lt;/p&gt;
&lt;p&gt;169.254.169.254 is not accessible from an IPv6-only Virtual Machine (VM).
It is possible to add 169.254.0.0/16 to a port’s allowed_address_pairs list
and use an IPv6 link-local address for interface configuration, but the
metadata proxy doesn’t even start if there are no DHCP-enabled IPv4 subnets,
and IPv6 link-local addresses are unknown for Neutron and can’t be used for
instance identification.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The metadata proxy starts unconditionally when a network is assigned to a DHCP
agent or L3 router.&lt;/p&gt;
&lt;p&gt;The metadata proxy listens on a dual-stack socket (::).&lt;/p&gt;
&lt;p&gt;In the case of IPv4, the metadata proxy uses IP address 169.254.169.254 which
belongs to the IPv4 link-local subnet (169.254.0.0/16 according to [1]).
In the case of IPv6, the metadata proxy joins the anycast group fe80::a9fe:a9fe
on all available interfaces.
The fe80::a9fe:a9fe IP address is equivalent of 169.254.169.254 in the IPv6
link-local subnet which is fe80::/10 according to [2].
It is valid to do this because it is running inside a router or dhcp namespace.&lt;/p&gt;
&lt;p&gt;The L3 agent will add a firewall rule that redirects traffic sent to
the proposed anycast IP (fe80::a9fe:a9fe) to the metadata proxy port.
In the case of the DHCP agent, a new IP address (fe80::a9fe:a9fe) will be
configured on the tap port which belongs to the DHCP agent, the same way it is
currently done for the IPv4 address (169.254.169.254).&lt;/p&gt;
&lt;p&gt;The VM uses the address fe80::a9fe:a9fe to access Metadata service. Software
like cloud-init used inside VMs must be aware of this new IPv6 address. So
images used in Openstack clouds will have to be updated as well.&lt;/p&gt;
&lt;p&gt;When the metadata proxy processes a request, it gathers the L2 addresses of a
VM, and the source interface, and passes it to the metadata service.&lt;/p&gt;
&lt;p&gt;The Metadata service, instead of using the VM IP, uses the “VM MAC” and
“Gateway MAC” to identify the instance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;As this new IPv6 address proposed for metadata service isn’t currently used by
any other cloud provider, we need to update our documentation to make it very
clear what IPv6 address is used by the metadata service and how to configure
it in at least the most popular metadata consumer, which is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cloud-init&lt;/span&gt;&lt;/code&gt;.
In the case of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cloud-init&lt;/span&gt;&lt;/code&gt;, this new IP address can be set using the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;metadata_urls&lt;/span&gt;&lt;/code&gt; config option [3].&lt;/p&gt;
&lt;p&gt;In the future we can update the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;cloud-init&lt;/span&gt;&lt;/code&gt; code to make this IPv6 address
be one of the default IPs it uses for the OpenStack Datasource, or propose a
new datasource, for example, OpenStackIPv6.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://tools.ietf.org/html/rfc3927"&gt;https://tools.ietf.org/html/rfc3927&lt;/a&gt;
[2] &lt;a class="reference external" href="https://tools.ietf.org/html/rfc4291"&gt;https://tools.ietf.org/html/rfc4291&lt;/a&gt;
[3] &lt;a class="reference external" href="https://github.com/canonical/cloud-init/blob/4f940bd1f76f50f947af533661ba6fafa3e60e59/doc/rtd/topics/datasources/openstack.rst"&gt;https://github.com/canonical/cloud-init/blob/4f940bd1f76f50f947af533661ba6fafa3e60e59/doc/rtd/topics/datasources/openstack.rst&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 14 Oct 2016 00:00:00 </pubDate></item><item><title>Networking-bagpipe Scorecard</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata/networking-bagpipe.html</link><description>

&lt;section id="neutron-integration"&gt;
&lt;h2&gt;Neutron integration&lt;/h2&gt;
&lt;ul id="n0"&gt;
&lt;li&gt;&lt;p&gt;N0. Does the project use the Neutron REST API or relies on proprietary backends?&lt;/p&gt;
&lt;p&gt;No. The repo relies on &lt;a class="reference external" href="https://github.com/Orange-OpenSource/bagpipe-bgp"&gt;https://github.com/Orange-OpenSource/bagpipe-bgp&lt;/a&gt;, which
is released under the Apache license.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n1"&gt;
&lt;li&gt;&lt;p&gt;N1. Does the project integrate/use neutron-lib?&lt;/p&gt;
&lt;p&gt;Yes. So far the import ratio is ~13%. The neutron-lib periodic integration is
not available, but in progress.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/385337/"&gt;https://review.openstack.org/#/c/385337/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/385445/"&gt;https://review.openstack.org/#/c/385445/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n2"&gt;
&lt;li&gt;&lt;p&gt;N2. Do project members actively contribute to help neutron-lib achieve its
goal?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n3"&gt;
&lt;li&gt;&lt;p&gt;N3. Do project members collaborate with the core team to enable subprojects
to loosely integrate with the Neutron core platform by helping with the definition
of modular interfaces?&lt;/p&gt;
&lt;p&gt;The team proactively adopted L2 extensions where required, as shown by commits
below.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n4"&gt;
&lt;li&gt;&lt;p&gt;N4. How does the project provide networking services? Does it use modular interfaces
as provided by the core platform?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/networking-bgpvpn/blob/753fa2410639dca3957f0bffbb2e632181f00f77/setup.cfg#L42"&gt;https://github.com/openstack/networking-bgpvpn/blob/753fa2410639dca3957f0bffbb2e632181f00f77/setup.cfg#L42&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/networking-bagpipe/blob/382a6a6930bb77764b40c65724b53ab1901132ba/setup.cfg#L58"&gt;https://github.com/openstack/networking-bagpipe/blob/382a6a6930bb77764b40c65724b53ab1901132ba/setup.cfg#L58&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n5"&gt;
&lt;li&gt;&lt;p&gt;N5. If the project provides new API extensions, have API extensions been discussed
and accepted by the Neutron drivers team? Please provide links to API specs, if
required.&lt;/p&gt;
&lt;p&gt;networking-bagpipe contains (a) a driver for networking-bgpvpn, and (b) an ML2 mech
driver to deliver Neutron L2 that (1) is not necessary for the BGPVPN part and (2)
does not require an other ML2 mech driver to deliver Neutron ML2.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul id="d1"&gt;
&lt;li&gt;&lt;p&gt;D1. Does the project have a doc tox target, functional and continuously
working? Provide proof (links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/networking-bagpipe/"&gt;http://docs.openstack.org/developer/networking-bagpipe/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d2"&gt;
&lt;li&gt;&lt;p&gt;D2. If the project provide API extensions, does the project have an
api-ref tox target, functional and continously working? Provide proof
(links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d3"&gt;
&lt;li&gt;&lt;p&gt;D3. Does the project have a releasenotes tox target, functional and
continously working? Provide proof.&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/394423"&gt;https://review.openstack.org/#/c/394423&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/394339"&gt;https://review.openstack.org/#/c/394339&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d4"&gt;
&lt;li&gt;&lt;p&gt;D4. Describe the types of documentation available: developer, end user,
administrator, deployer.&lt;/p&gt;
&lt;p&gt;Just deployer documentation.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="continuous-integration"&gt;
&lt;h2&gt;Continuous Integration&lt;/h2&gt;
&lt;ul id="c1"&gt;
&lt;li&gt;&lt;p&gt;C1. Does the project have a Grafana dashboard showing historical trends of
all the jobs available? Provide proof (links to grafana.openstack.org).&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/385337/"&gt;https://review.openstack.org/#/c/385337/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c2"&gt;
&lt;li&gt;&lt;p&gt;C2. Does the project have CI for unit coverage? Provide proof (links to
logs.openstack.org)&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/g/project/openstack~2Fnetworking-bagpipe"&gt;http://status.openstack.org/openstack-health/#/g/project/openstack~2Fnetworking-bagpipe&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c3"&gt;
&lt;li&gt;&lt;p&gt;C3. Does the project have CI for functional coverage? If so, does it include
DB migration and sync validation?&lt;/p&gt;
&lt;p&gt;No, and no DB migration and sync validation even though the mech driver has DB
migrations (last one available for the Liberty release). The roadmap is to get
rid of DB models, and instead use the VXLAN type driver and derive BGPVPN
identifiers from that, in a way similar to IETF draft &lt;a class="reference external" href="https://tools.ietf.org/html/draft-ietf-bess-evpn-overlay-04#section-5.1.2.1"&gt;draft-ietf-bess-evpn-overlay&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c4"&gt;
&lt;li&gt;&lt;p&gt;C4. Does the project have CI for fullstack coverage?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c5"&gt;
&lt;li&gt;&lt;p&gt;C5. Does the project have CI for Tempest coverage? If so, specify nature
(API and/or Scenario).&lt;/p&gt;
&lt;p&gt;Non-voting and experimental.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/97/392097/1/experimental/gate-tempest-dsvm-networking-bagpipe-full/9b4cafb/"&gt;http://logs.openstack.org/97/392097/1/experimental/gate-tempest-dsvm-networking-bagpipe-full/9b4cafb/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/97/392097/1/experimental/gate-tempest-dsvm-networking-bgpvpn-bagpipe/961fd47/"&gt;http://logs.openstack.org/97/392097/1/experimental/gate-tempest-dsvm-networking-bgpvpn-bagpipe/961fd47/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c6"&gt;
&lt;li&gt;&lt;p&gt;C6. How does a project validate upgrades on a continuous basis? Does
the project require or support CI for Grenade coverage?&lt;/p&gt;
&lt;p&gt;No evidence of Grenade testing.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c7"&gt;
&lt;li&gt;&lt;p&gt;C7. Does the project provide multinode CI?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c8"&gt;
&lt;li&gt;&lt;p&gt;C8. Does the project support Python 3.x? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/97/392097/1/experimental/gate-networking-bagpipe-python35-db/b26d70c/testr_results.html.gz"&gt;http://logs.openstack.org/97/392097/1/experimental/gate-networking-bagpipe-python35-db/b26d70c/testr_results.html.gz&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="release-footprint"&gt;
&lt;h2&gt;Release footprint&lt;/h2&gt;
&lt;ul id="r1"&gt;
&lt;li&gt;&lt;p&gt;R1. Does the project adopt semver?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r2"&gt;
&lt;li&gt;&lt;p&gt;R2. Does the project have release deliverables? Provide proof as available
in the &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/"&gt;release repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/releases/blob/master/deliverables/_independent/networking-bagpipe.yaml"&gt;https://github.com/openstack/releases/blob/master/deliverables/_independent/networking-bagpipe.yaml&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r3"&gt;
&lt;li&gt;&lt;p&gt;R3. Does the project use upper-constraints?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/networking-bagpipe/blob/master/tox.ini#L8"&gt;https://github.com/openstack/networking-bagpipe/blob/master/tox.ini#L8&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r4"&gt;
&lt;li&gt;&lt;p&gt;Does the project integrate with OpenStack Proposal Bot for requirements updates?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/requirements/commit/3a8bcda570d1dc129518ca8c10752f837af07a39"&gt;https://github.com/openstack/requirements/commit/3a8bcda570d1dc129518ca8c10752f837af07a39&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="stable-backports"&gt;
&lt;h2&gt;Stable backports&lt;/h2&gt;
&lt;ul id="s1"&gt;
&lt;li&gt;&lt;p&gt;S1. Does the project have stable branches and/or tags? Provide history of
backports.&lt;/p&gt;
&lt;p&gt;Yes. Stable liberty, mitaka and newton look aligned with Neutron’s.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="client-library"&gt;
&lt;h2&gt;Client library&lt;/h2&gt;
&lt;ul id="l1"&gt;
&lt;li&gt;&lt;p&gt;L1. If the project requires a client library, how does it implement CLI and
API bindings?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="scorecard"&gt;
&lt;h2&gt;Scorecard&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Scorecard&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n0"&gt;N0&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n1"&gt;N1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n2"&gt;N2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n4"&gt;N4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n5"&gt;N5&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d1"&gt;D1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d3"&gt;D3&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c2"&gt;C2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c3"&gt;C3&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c4"&gt;C4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c6"&gt;C6&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c7"&gt;C7&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c8"&gt;C8&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r1"&gt;R1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r2"&gt;R2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r3"&gt;R3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r4"&gt;R4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#s1"&gt;S1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Final remarks: neutron-lib integration, more documentation and better coverage
are the main gaps identified in this project.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 07 Oct 2016 00:00:00 </pubDate></item><item><title>Networking-bgpvpn Scorecard</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata/networking-bgpvpn.html</link><description>

&lt;section id="neutron-integration"&gt;
&lt;h2&gt;Neutron integration&lt;/h2&gt;
&lt;ul id="n0"&gt;
&lt;li&gt;&lt;p&gt;N0. Does the project use the Neutron REST API or relies on proprietary backends?&lt;/p&gt;
&lt;p&gt;No. The project provides an API and Framework to interconnect BGP/MPLS VPNs to
Openstack Neutron networks, routers and ports. It represents the server-side
(plus its client-side mappings) to provide such a functionality. The server-side
provides a driver-based mechanism to supply implementations of the API, which
include an agent-based solution as available by the related project
networking-bagpipe, as well as OpenDaylight and OpenContrail.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n1"&gt;
&lt;li&gt;&lt;p&gt;N1. Does the project integrate/use neutron-lib?&lt;/p&gt;
&lt;p&gt;Yes. So far the import ratio is ~15%. The neutron-lib periodic integration is
available with periodic-networking-bgpvpn-py27-with-neutron-lib-master, though
the switch to py35 has happened recently, so the project should switch too.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/377738/"&gt;https://review.openstack.org/#/c/377738/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n2"&gt;
&lt;li&gt;&lt;p&gt;N2. Do project members actively contribute to help neutron-lib achieve its
goal?&lt;/p&gt;
&lt;p&gt;No evidence of that.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n3"&gt;
&lt;li&gt;&lt;p&gt;N3. Do project members collaborate with the core team to enable subprojects
to loosely integrate with the Neutron core platform by helping with the definition
of modular interfaces?&lt;/p&gt;
&lt;p&gt;Team memembers have been particularly active in reviewing patches affecting
the OVS pipeline.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n4"&gt;
&lt;li&gt;&lt;p&gt;N4. How does the project provide networking services? Does it use modular interfaces
as provided by the core platform?&lt;/p&gt;
&lt;p&gt;The project adopts a service plugin model to plug into the API framework and provide
driver extensions a la’ ML2 pattern. The decomposition between bgpvpn and bagpipe
especially in relation to where the L2 agent extension is located may need some
rethinking.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n5"&gt;
&lt;li&gt;&lt;p&gt;N5. If the project provides new API extensions, have API extensions been discussed
and accepted by the Neutron drivers team? Please provide links to API specs, if
required.&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul id="d1"&gt;
&lt;li&gt;&lt;p&gt;D1. Does the project have a doc tox target, functional and continuously
working? Provide proof (links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/networking-bgpvpn/blob/master/tox.ini"&gt;https://github.com/openstack/networking-bgpvpn/blob/master/tox.ini&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d2"&gt;
&lt;li&gt;&lt;p&gt;D2. If the project provide API extensions, does the project have an
api-ref tox target, functional and continously working? Provide proof
(links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;No. There is some API documentation but it is not in the required format.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/390196/"&gt;https://review.openstack.org/#/c/390196/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d3"&gt;
&lt;li&gt;&lt;p&gt;D3. Does the project have a releasenotes tox target, functional and
continously working? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/releasenotes/networking-bgpvpn/"&gt;http://docs.openstack.org/releasenotes/networking-bgpvpn/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/networking-bgpvpn/blob/master/tox.ini"&gt;https://github.com/openstack/networking-bgpvpn/blob/master/tox.ini&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d4"&gt;
&lt;li&gt;&lt;p&gt;D4. Describe the types of documentation available: developer, end user,
administrator, deployer.&lt;/p&gt;
&lt;p&gt;There is developer, and user documentation available.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/networking-bgpvpn/"&gt;http://docs.openstack.org/developer/networking-bgpvpn/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="continuous-integration"&gt;
&lt;h2&gt;Continuous Integration&lt;/h2&gt;
&lt;ul id="c1"&gt;
&lt;li&gt;&lt;p&gt;C1. Does the project have a Grafana dashboard showing historical trends of
all the jobs available? Provide proof (links to grafana.openstack.org).&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/385335/"&gt;https://review.openstack.org/#/c/385335/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c2"&gt;
&lt;li&gt;&lt;p&gt;C2. Does the project have CI for unit coverage? Provide proof (links to
logs.openstack.org)&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/g/project/openstack~2Fnetworking-bgpvpn"&gt;http://status.openstack.org/openstack-health/#/g/project/openstack~2Fnetworking-bgpvpn&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c3"&gt;
&lt;li&gt;&lt;p&gt;C3. Does the project have CI for functional coverage? If so, does it include
DB migration and sync validation?&lt;/p&gt;
&lt;p&gt;There is functional coverage, but it is experimental. DB migration and sync
validation is provided via unit testing.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/g/project/openstack~2Fnetworking-bgpvpn"&gt;http://status.openstack.org/openstack-health/#/g/project/openstack~2Fnetworking-bgpvpn&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c4"&gt;
&lt;li&gt;&lt;p&gt;C4. Does the project have CI for fullstack coverage?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c5"&gt;
&lt;li&gt;&lt;p&gt;C5. Does the project have CI for Tempest coverage? If so, specify nature
(API and/or Scenario).&lt;/p&gt;
&lt;p&gt;Only API tests available.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/networking-bgpvpn/tree/master/networking_bgpvpn_tempest/tests"&gt;https://github.com/openstack/networking-bgpvpn/tree/master/networking_bgpvpn_tempest/tests&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c6"&gt;
&lt;li&gt;&lt;p&gt;C6. How does a project validate upgrades on a continuous basis? Does
the project require or support CI for Grenade coverage?&lt;/p&gt;
&lt;p&gt;No Grenade testing is available.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c7"&gt;
&lt;li&gt;&lt;p&gt;C7. Does the project provide multinode CI?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c8"&gt;
&lt;li&gt;&lt;p&gt;C8. Does the project support Python 3.x? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/85/387885/16/experimental/gate-networking-bgpvpn-python35-db/5459830/testr_results.html.gz"&gt;http://logs.openstack.org/85/387885/16/experimental/gate-networking-bgpvpn-python35-db/5459830/testr_results.html.gz&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="release-footprint"&gt;
&lt;h2&gt;Release footprint&lt;/h2&gt;
&lt;ul id="r1"&gt;
&lt;li&gt;&lt;p&gt;R1. Does the project adopt semver?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r2"&gt;
&lt;li&gt;&lt;p&gt;R2. Does the project have release deliverables? Provide proof as available
in the &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/"&gt;release repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yes, though the project notes do not seem to show up.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://releases.openstack.org/newton/index.html"&gt;https://releases.openstack.org/newton/index.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/releases/blob/master/deliverables/_independent/networking-bgpvpn.yaml"&gt;https://github.com/openstack/releases/blob/master/deliverables/_independent/networking-bgpvpn.yaml&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r3"&gt;
&lt;li&gt;&lt;p&gt;R3. Does the project use upper-constraints?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/networking-bgpvpn/blob/master/tox.ini#L8"&gt;https://github.com/openstack/networking-bgpvpn/blob/master/tox.ini#L8&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r4"&gt;
&lt;li&gt;&lt;p&gt;Does the project integrate with OpenStack Proposal Bot for requirements updates?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/391505/"&gt;https://review.openstack.org/#/c/391505/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="stable-backports"&gt;
&lt;h2&gt;Stable backports&lt;/h2&gt;
&lt;ul id="s1"&gt;
&lt;li&gt;&lt;p&gt;S1. Does the project have stable branches and/or tags? Provide history of
backports.&lt;/p&gt;
&lt;p&gt;Yes. Stable liberty, mitaka and newton look aligned with Neutron’s&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="client-library"&gt;
&lt;h2&gt;Client library&lt;/h2&gt;
&lt;ul id="l1"&gt;
&lt;li&gt;&lt;p&gt;L1. If the project requires a client library, how does it implement CLI and
API bindings?&lt;/p&gt;
&lt;p&gt;There are client mappings but no OSC transition yet.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/388870/"&gt;https://review.openstack.org/#/c/388870/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="scorecard"&gt;
&lt;h2&gt;Scorecard&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Scorecard&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n0"&gt;N0&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n1"&gt;N1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n2"&gt;N2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n4"&gt;N4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n5"&gt;N5&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d1"&gt;D1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d3"&gt;D3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c2"&gt;C2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c3"&gt;C3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c4"&gt;C4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c6"&gt;C6&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c7"&gt;C7&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c8"&gt;C8&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r1"&gt;R1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r2"&gt;R2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r3"&gt;R3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r4"&gt;R4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#s1"&gt;S1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Final remarks: There are some gaps that need attention most notably API
documentation, client mappings and functional/scenario testing.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 07 Oct 2016 00:00:00 </pubDate></item><item><title>Networking-calico Scorecard</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata/networking-calico.html</link><description>

&lt;section id="neutron-integration"&gt;
&lt;h2&gt;Neutron integration&lt;/h2&gt;
&lt;ul id="n0"&gt;
&lt;li&gt;&lt;p&gt;N0. Does the project use the Neutron REST API or relies on proprietary backends?&lt;/p&gt;
&lt;p&gt;No. The project implements Neutron plugins.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n1"&gt;
&lt;li&gt;&lt;p&gt;N1. Does the project integrate/use neutron-lib?&lt;/p&gt;
&lt;p&gt;No. Of the total ~200 total imports, neutron-lib is imported 0 times whereas
Neutron is imported a few dozens. Some in flight, more needed.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/387536/"&gt;https://review.openstack.org/#/c/387536/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n2"&gt;
&lt;li&gt;&lt;p&gt;N2. Do project members actively contribute to help neutron-lib achieve its
goal?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n3"&gt;
&lt;li&gt;&lt;p&gt;N3. Do project members collaborate with the core team to enable subprojects
to loosely integrate with the Neutron core platform by helping with the definition
of modular interfaces?&lt;/p&gt;
&lt;p&gt;No, as the next point demonstrates.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n4"&gt;
&lt;li&gt;&lt;p&gt;N4. How does the project provide networking services? Does it use modular interfaces
as provided by the core platform?&lt;/p&gt;
&lt;p&gt;The project has adopted some &lt;a class="reference external" href="https://github.com/openstack/networking-calico/commit/2c302e6bafe5cfe564b9816aa2a67a3a65508807"&gt;questionable patterns&lt;/a&gt;.
These patterns not only defeat the point of modularity but may lead to solutions that
may be incredibly brittle. Team working to address this.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/396427/"&gt;https://review.openstack.org/#/c/396427/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n5"&gt;
&lt;li&gt;&lt;p&gt;N5. If the project provides new API extensions, have API extensions been discussed
and accepted by the Neutron drivers team? Please provide links to API specs, if
required.&lt;/p&gt;
&lt;p&gt;It does not look like the project introduces new APIs.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul id="d1"&gt;
&lt;li&gt;&lt;p&gt;D1. Does the project have a doc tox target, functional and continuously
working? Provide proof (links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/networking-calico/"&gt;http://docs.openstack.org/developer/networking-calico/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d2"&gt;
&lt;li&gt;&lt;p&gt;D2. If the project provide API extensions, does the project have an
api-ref tox target, functional and continously working? Provide proof
(links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d3"&gt;
&lt;li&gt;&lt;p&gt;D3. Does the project have a releasenotes tox target, functional and
continously working? Provide proof.&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d4"&gt;
&lt;li&gt;&lt;p&gt;D4. Describe the types of documentation available: developer, end user,
administrator, deployer.&lt;/p&gt;
&lt;p&gt;There is some developer and deployer documentation. More being added.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/388789/"&gt;https://review.openstack.org/#/c/388789/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="continuous-integration"&gt;
&lt;h2&gt;Continuous Integration&lt;/h2&gt;
&lt;ul id="c1"&gt;
&lt;li&gt;&lt;p&gt;C1. Does the project have a Grafana dashboard showing historical trends of
all the jobs available? Provide proof (links to grafana.openstack.org).&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c2"&gt;
&lt;li&gt;&lt;p&gt;C2. Does the project have CI for unit coverage? Provide proof (links to
logs.openstack.org)&lt;/p&gt;
&lt;p&gt;Yes. Though, it is puzzling why some test code is available under non-test
modulee, &lt;a class="reference external" href="https://github.com/openstack/networking-calico/blob/d6c3dbf95f111827d63073150a719ea74a03c9ea/networking_calico/plugins/ml2/drivers/calico/test/test_election.py"&gt;test_election&lt;/a&gt; being an example.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/62/383462/2/check/gate-networking-calico-python27-ubuntu-xenial/9e979e7/"&gt;http://logs.openstack.org/62/383462/2/check/gate-networking-calico-python27-ubuntu-xenial/9e979e7/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c3"&gt;
&lt;li&gt;&lt;p&gt;C3. Does the project have CI for functional coverage? If so, does it include
DB migration and sync validation?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c4"&gt;
&lt;li&gt;&lt;p&gt;C4. Does the project have CI for fullstack coverage?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c5"&gt;
&lt;li&gt;&lt;p&gt;C5. Does the project have CI for Tempest coverage? If so, specify nature
(API and/or Scenario).&lt;/p&gt;
&lt;p&gt;No, at the time of writing.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/390908/"&gt;https://review.openstack.org/#/c/390908/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/34/361134/5/check/gate-tempest-dsvm-networking-calico-nv/1b4d652/logs/testr_results.html.gz"&gt;http://logs.openstack.org/34/361134/5/check/gate-tempest-dsvm-networking-calico-nv/1b4d652/logs/testr_results.html.gz&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/392184/"&gt;https://review.openstack.org/#/c/392184/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c6"&gt;
&lt;li&gt;&lt;p&gt;C6. Does the project require CI for Grenade coverage?&lt;/p&gt;
&lt;p&gt;Potentially, but currently there is none.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c7"&gt;
&lt;li&gt;&lt;p&gt;C7. Does the project provide multinode CI?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c8"&gt;
&lt;li&gt;&lt;p&gt;C8. Does the project support Python 3.x? Provide proof.&lt;/p&gt;
&lt;p&gt;No. In progress.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/365466/"&gt;https://review.openstack.org/#/c/365466/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/365466/"&gt;https://review.openstack.org/#/c/365466/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="release-footprint"&gt;
&lt;h2&gt;Release footprint&lt;/h2&gt;
&lt;ul id="r1"&gt;
&lt;li&gt;&lt;p&gt;R1. Does the project adopt semver?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r2"&gt;
&lt;li&gt;&lt;p&gt;R2. Does the project have release deliverables? Provide proof as available
in the &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/"&gt;release repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/releases/blob/master/deliverables/_independent/networking-calico.yaml"&gt;https://github.com/openstack/releases/blob/master/deliverables/_independent/networking-calico.yaml&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r3"&gt;
&lt;li&gt;&lt;p&gt;R3. Does the project use upper-constraints?&lt;/p&gt;
&lt;p&gt;No. In progress.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/392165/"&gt;https://review.openstack.org/#/c/392165/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/392168/"&gt;https://review.openstack.org/#/c/392168/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r4"&gt;
&lt;li&gt;&lt;p&gt;Does the project integrate with OpenStack Proposal Bot for requirements updates?&lt;/p&gt;
&lt;p&gt;No. In progress.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="stable-backports"&gt;
&lt;h2&gt;Stable backports&lt;/h2&gt;
&lt;ul id="s1"&gt;
&lt;li&gt;&lt;p&gt;S1. Does the project have stable branches and/or tags? Provide history of
backports.&lt;/p&gt;
&lt;p&gt;The lack of stable branches and the fact that the code somewhat handles
branching &lt;a class="reference external" href="https://github.com/openstack/networking-calico/blob/master/networking_calico/plugins/ml2/drivers/calico/mech_calico.py#L52"&gt;in code&lt;/a&gt;
is concerning.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="client-library"&gt;
&lt;h2&gt;Client library&lt;/h2&gt;
&lt;ul id="l1"&gt;
&lt;li&gt;&lt;p&gt;L1. If the project requires a client library, how does it implement CLI and
API bindings?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="scorecard"&gt;
&lt;h2&gt;Scorecard&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Scorecard&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n0"&gt;N0&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n1"&gt;N1&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n2"&gt;N2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n4"&gt;N4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n5"&gt;N5&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d1"&gt;D1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d3"&gt;D3&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c2"&gt;C2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c3"&gt;C3&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c4"&gt;C4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c6"&gt;C6&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c7"&gt;C7&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c8"&gt;C8&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r1"&gt;R1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r2"&gt;R2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r3"&gt;R3&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r4"&gt;R4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#s1"&gt;S1&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Final remarks: the modularity and maturity of the networking-calico codebase is substantially
subpar compared to other Neutron subprojects. The absence of testing besides unit coverage is
problematic to say the least. Some of the patterns chosen to provide networking solutions are
an exemplification of the disconnect between the networking-calico and the Neutron core team.
Work required is not insurmountable but it takes time.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 07 Oct 2016 00:00:00 </pubDate></item><item><title>Networking-l2gw Scorecard</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata/networking-l2gw.html</link><description>

&lt;section id="neutron-integration"&gt;
&lt;h2&gt;Neutron integration&lt;/h2&gt;
&lt;ul id="n0"&gt;
&lt;li&gt;&lt;p&gt;N0. Does the project use the Neutron REST API or relies on proprietary backends?&lt;/p&gt;
&lt;p&gt;Networking-l2gw implements its own set of Neutron API extensions on top of
the Neutron core framework and it does so by using the service plugin model.
The API exposed has open source implementations, and it provides a pluggable
mechanism for proprietary backends.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n1"&gt;
&lt;li&gt;&lt;p&gt;N1. Does the project integrate/use neutron-lib?&lt;/p&gt;
&lt;p&gt;Yes. The migration report shows that there are currently ~450 total imports.
Neutron is imported ~100 times and Neutron-lib only ~10 times, for a migration
percentage of 11.2000%. No periodic job against neutron-lib seems available.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n2"&gt;
&lt;li&gt;&lt;p&gt;N2. Do project members actively contribute to help neutron-lib achieve its
goal?&lt;/p&gt;
&lt;p&gt;None of the project core members have merged anything meaningful into neutron-lib
(source: &lt;a class="reference external" href="https://review.openstack.org/#/q/project:openstack/neutron-lib+status:merged,75"&gt;https://review.openstack.org/#/q/project:openstack/neutron-lib+status:merged,75&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n3"&gt;
&lt;li&gt;&lt;p&gt;N3. Do project members collaborate with the core team to enable subprojects
to loosely integrate with the Neutron core platform by helping with the definition
of modular interfaces?&lt;/p&gt;
&lt;p&gt;Not particularly.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n4"&gt;
&lt;li&gt;&lt;p&gt;N4. How does the project provide networking services? Does it use modular interfaces
as provided by the core platform?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n5"&gt;
&lt;li&gt;&lt;p&gt;N5. If the project provides new API extensions, have API extensions been discussed
and accepted by the Neutron drivers team? Please provide links to API specs, if
required.&lt;/p&gt;
&lt;p&gt;Not exactly. The project was one of the initial projects created during the early
days of the Big Tent and Neutron decomposition. The API was accepted/approved by
a smaller group of people who wanted to make progress on a topic that was largely
stalled due to lack of community consensus.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul id="d1"&gt;
&lt;li&gt;&lt;p&gt;D1. Does the project have a doc tox target, functional and continuously
working? Provide proof (links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/networking-l2gw/blob/master/tox.ini"&gt;https://github.com/openstack/networking-l2gw/blob/master/tox.ini&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d2"&gt;
&lt;li&gt;&lt;p&gt;D2. If the project provide API extensions, does the project have an
api-ref tox target, functional and continously working? Provide proof
(links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;There is no API reference published, though the API is detailed in
its spec document.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://raw.githubusercontent.com/openstack/networking-l2gw/master/specs/kilo/l2-gateway-api.rst"&gt;https://raw.githubusercontent.com/openstack/networking-l2gw/master/specs/kilo/l2-gateway-api.rst&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d3"&gt;
&lt;li&gt;&lt;p&gt;D3. Does the project have a releasenotes tox target, functional and
continously working? Provide proof.&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d4"&gt;
&lt;li&gt;&lt;p&gt;D4. Describe the types of documentation available: developer, end user,
administrator, deployer.&lt;/p&gt;
&lt;p&gt;There is not a lot of documentation available.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/networking-l2gw/"&gt;http://docs.openstack.org/developer/networking-l2gw/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="continuous-integration"&gt;
&lt;h2&gt;Continuous Integration&lt;/h2&gt;
&lt;ul id="c1"&gt;
&lt;li&gt;&lt;p&gt;C1. Does the project have a Grafana dashboard showing historical trends of
all the jobs available? Provide proof (links to grafana.openstack.org).&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c2"&gt;
&lt;li&gt;&lt;p&gt;C2. Does the project have CI for unit coverage? Provide proof (links to
logs.openstack.org)&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/g/project/openstack~2Fnetworking-l2gw"&gt;http://status.openstack.org/openstack-health/#/g/project/openstack~2Fnetworking-l2gw&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c3"&gt;
&lt;li&gt;&lt;p&gt;C3. Does the project have CI for functional coverage? If so, does it include
DB migration and sync validation?&lt;/p&gt;
&lt;p&gt;No. but DB migration and sync validation is provided by its unit job.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/99/380899/1/gate/gate-networking-l2gw-python35-db/f3af348/testr_results.html.gz"&gt;http://logs.openstack.org/99/380899/1/gate/gate-networking-l2gw-python35-db/f3af348/testr_results.html.gz&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c4"&gt;
&lt;li&gt;&lt;p&gt;C4. Does the project have CI for fullstack coverage?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c5"&gt;
&lt;li&gt;&lt;p&gt;C5. Does the project have CI for Tempest coverage? If so, specify nature
(API and/or Scenario).&lt;/p&gt;
&lt;p&gt;Latest Bot proposal shows only unit validation. Even though the project has
API and scenario tests they are exercised with downstream CI because of lack
of an pure software implementation of L2GW services.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/357703/"&gt;https://review.openstack.org/#/c/357703/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c6"&gt;
&lt;li&gt;&lt;p&gt;C6. How does a project validate upgrades on a continuous basis? Does
the project require or support CI for Grenade coverage?&lt;/p&gt;
&lt;p&gt;Yes. But it has none.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c7"&gt;
&lt;li&gt;&lt;p&gt;C7. Does the project provide multinode CI?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c8"&gt;
&lt;li&gt;&lt;p&gt;C8. Does the project support Python 3.x? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/03/357703/7/gate/gate-networking-l2gw-python35-db/b834ee7/testr_results.html.gz"&gt;http://logs.openstack.org/03/357703/7/gate/gate-networking-l2gw-python35-db/b834ee7/testr_results.html.gz&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="release-footprint"&gt;
&lt;h2&gt;Release footprint&lt;/h2&gt;
&lt;ul id="r1"&gt;
&lt;li&gt;&lt;p&gt;R1. Does the project adopt semver?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r2"&gt;
&lt;li&gt;&lt;p&gt;R2. Does the project have release deliverables? Provide proof as available
in the &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/"&gt;release repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yes, the release is responsibility of the neutron-release team.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r3"&gt;
&lt;li&gt;&lt;p&gt;R3. Does the project use upper-constraints?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/networking-l2gw/blob/master/tox.ini#L10"&gt;https://github.com/openstack/networking-l2gw/blob/master/tox.ini#L10&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r4"&gt;
&lt;li&gt;&lt;p&gt;Does the project integrate with OpenStack Proposal Bot for requirements updates?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/requirements/commit/574736a84b9218e1d7ea860f82cb248975b7c1ca"&gt;https://github.com/openstack/requirements/commit/574736a84b9218e1d7ea860f82cb248975b7c1ca&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="stable-backports"&gt;
&lt;h2&gt;Stable backports&lt;/h2&gt;
&lt;ul id="s1"&gt;
&lt;li&gt;&lt;p&gt;S1. Does the project have stable branches and/or tags? Provide history of
backports.&lt;/p&gt;
&lt;p&gt;Yes, stable maintainance is responsibility of the neutron-stable team.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="client-library"&gt;
&lt;h2&gt;Client library&lt;/h2&gt;
&lt;ul id="l1"&gt;
&lt;li&gt;&lt;p&gt;L1. If the project requires a client library, how does it implement CLI and
API bindings?&lt;/p&gt;
&lt;p&gt;There are Neutron CLI extensions but they have not been ported over to OSC.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/networking-l2gw/tree/master/networking_l2gw/l2gatewayclient"&gt;https://github.com/openstack/networking-l2gw/tree/master/networking_l2gw/l2gatewayclient&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="scorecard"&gt;
&lt;h2&gt;Scorecard&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Scorecard&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n0"&gt;N0&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n1"&gt;N1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n2"&gt;N2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n4"&gt;N4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n5"&gt;N5&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d1"&gt;D1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d3"&gt;D3&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c2"&gt;C2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c3"&gt;C3&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c4"&gt;C4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c6"&gt;C6&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c7"&gt;C7&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c8"&gt;C8&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r1"&gt;R1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r2"&gt;R2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r3"&gt;R3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r4"&gt;R4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#s1"&gt;S1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="final-remarks"&gt;
&lt;h2&gt;Final remarks&lt;/h2&gt;
&lt;p&gt;Closing the gap on all the remaining unmet criteria in time for Ocata-1
(Nov 14 2016) seems challenging. Progress lacked during the Newton cycle.
It is probably time for the core team to be rebooted.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 07 Oct 2016 00:00:00 </pubDate></item><item><title>Networking-odl Scorecard</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata/networking-odl.html</link><description>

&lt;section id="neutron-integration"&gt;
&lt;h2&gt;Neutron integration&lt;/h2&gt;
&lt;ul class="simple" id="n0"&gt;
&lt;li&gt;&lt;p&gt;N0. Does the project use the Neutron REST API or relies on proprietary backends?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No, the project maps the various Neutron APIs on top of the OpenDayLight SDN controller.&lt;/p&gt;
&lt;ul id="n1"&gt;
&lt;li&gt;&lt;p&gt;N1. Does the project integrate/use neutron-lib?&lt;/p&gt;
&lt;p&gt;Yes. Roughly only 10% of the imports have been migrated over.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n2"&gt;
&lt;li&gt;&lt;p&gt;N2. Do project members actively contribute to help neutron-lib achieve its
goal?&lt;/p&gt;
&lt;p&gt;No. There is no evidence of that.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n3"&gt;
&lt;li&gt;&lt;p&gt;N3. Do project members collaborate with the core team to enable subprojects
to loosely integrate with the Neutron core platform by helping with the definition
of modular interfaces?&lt;/p&gt;
&lt;p&gt;There is some evidence of that, especially in relation to how the registry component
has been defined.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n4"&gt;
&lt;li&gt;&lt;p&gt;N4. How does the project provide networking services? Does it use modular interfaces
as provided by the core platform?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n5"&gt;
&lt;li&gt;&lt;p&gt;N5. If the project provides new API extensions, have API extensions been discussed
and accepted by the Neutron drivers team? Please provide links to API specs, if
required.&lt;/p&gt;
&lt;p&gt;The project currently provides driver for various APIs like SFC, L2GW, QoS, etc.
Some of these APIs need closer scrutiny by the neutron drivers team. Please,
read assessment for the relevant projects.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul id="d1"&gt;
&lt;li&gt;&lt;p&gt;D1. Does the project have a doc tox target, functional and continuously
working? Provide proof (links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/networking-odl/"&gt;http://docs.openstack.org/developer/networking-odl/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d2"&gt;
&lt;li&gt;&lt;p&gt;D2. If the project provide API extensions, does the project have an
api-ref tox target, functional and continously working? Provide proof
(links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;The project does not propose new APIs.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d3"&gt;
&lt;li&gt;&lt;p&gt;D3. Does the project have a releasenotes tox target, functional and
continously working? Provide proof.&lt;/p&gt;
&lt;p&gt;The target seems set up but no release notes are available.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/networking-odl/tree/master/releasenotes/notes"&gt;https://github.com/openstack/networking-odl/tree/master/releasenotes/notes&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/releasenotes/networking-odl/"&gt;http://docs.openstack.org/releasenotes/networking-odl/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d4"&gt;
&lt;li&gt;&lt;p&gt;D4. Describe the types of documentation available: developer, end user,
administrator, deployer.&lt;/p&gt;
&lt;p&gt;The documentation is available but content is bare bone. Host Configuration
is all there seems to be available. If OpenDaylight-hosted content is available,
this should at least be referenced.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/networking-odl/devref/hostconfig.html"&gt;http://docs.openstack.org/developer/networking-odl/devref/hostconfig.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="continuous-integration"&gt;
&lt;h2&gt;Continuous Integration&lt;/h2&gt;
&lt;ul id="c1"&gt;
&lt;li&gt;&lt;p&gt;C1. Does the project have a Grafana dashboard showing historical trends of
all the jobs available? Provide proof (links to grafana.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://grafana.openstack.org/dashboard/db/networking-odl-failure-rate"&gt;http://grafana.openstack.org/dashboard/db/networking-odl-failure-rate&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c2"&gt;
&lt;li&gt;&lt;p&gt;C2. Does the project have CI for unit coverage? Provide proof (links to
logs.openstack.org)&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/94/376994/1/check/gate-networking-odl-python27-ubuntu-xenial/b4d0ae2/"&gt;http://logs.openstack.org/94/376994/1/check/gate-networking-odl-python27-ubuntu-xenial/b4d0ae2/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c3"&gt;
&lt;li&gt;&lt;p&gt;C3. Does the project have CI for functional coverage? If so, does it include
DB migration and sync validation?&lt;/p&gt;
&lt;p&gt;No. There seems there is no DB migration and sync validation as the project
introduces its own data models. &lt;a class="reference external" href="https://review.openstack.org/#/c/384509/"&gt;Review&lt;/a&gt;
is eloquent.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c4"&gt;
&lt;li&gt;&lt;p&gt;C4. Does the project have CI for fullstack coverage?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c5"&gt;
&lt;li&gt;&lt;p&gt;C5. Does the project have CI for Tempest coverage? If so, specify nature
(API and/or Scenario).&lt;/p&gt;
&lt;p&gt;Yes, voting, though exercising only a subset of API tests and none of the
scenario tests affecting networking.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/383124/"&gt;https://review.openstack.org/#/c/383124/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c6"&gt;
&lt;li&gt;&lt;p&gt;C6. How does a project validate upgrades on a continuous basis? Does
the project require or support CI for Grenade coverage?&lt;/p&gt;
&lt;p&gt;The plan is to require it in early Ocata for openstack upgrade. Upgrading
CI runs against each supported ODL releases (berrylium, boron and carbon)
in order to guarantee the compatibility between neutron master vs ODL
versions. On the other hand, neutron stables + ODL master is tested by
opendaylight test infra.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c7"&gt;
&lt;li&gt;&lt;p&gt;C7. Does the project provide multinode CI?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c8"&gt;
&lt;li&gt;&lt;p&gt;C8. Does the project support Python 3.x? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/94/376994/1/check/gate-networking-odl-python35/4c26a70/testr_results.html.gz"&gt;http://logs.openstack.org/94/376994/1/check/gate-networking-odl-python35/4c26a70/testr_results.html.gz&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="release-footprint"&gt;
&lt;h2&gt;Release footprint&lt;/h2&gt;
&lt;ul id="r1"&gt;
&lt;li&gt;&lt;p&gt;R1. Does the project adopt semver?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r2"&gt;
&lt;li&gt;&lt;p&gt;R2. Does the project have release deliverables? Provide proof as available
in the &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/"&gt;release repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/releases/blob/master/deliverables/_independent/networking-odl.yaml"&gt;https://github.com/openstack/releases/blob/master/deliverables/_independent/networking-odl.yaml&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r3"&gt;
&lt;li&gt;&lt;p&gt;R3. Does the project use upper-constraints?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/networking-odl/blob/master/tox.ini#L11"&gt;https://github.com/openstack/networking-odl/blob/master/tox.ini#L11&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r4"&gt;
&lt;li&gt;&lt;p&gt;Does the project integrate with OpenStack Proposal Bot for requirements updates?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/requirements/commit/87f95992bf7b419b71faa52590edef8b7ee37f1a"&gt;https://github.com/openstack/requirements/commit/87f95992bf7b419b71faa52590edef8b7ee37f1a&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="stable-backports"&gt;
&lt;h2&gt;Stable backports&lt;/h2&gt;
&lt;ul id="s1"&gt;
&lt;li&gt;&lt;p&gt;S1. Does the project have stable branches and/or tags? Provide history of
backports.&lt;/p&gt;
&lt;p&gt;The stable backports have been historically managed by the Neutron team.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="client-library"&gt;
&lt;h2&gt;Client library&lt;/h2&gt;
&lt;ul id="l1"&gt;
&lt;li&gt;&lt;p&gt;L1. If the project requires a client library, how does it implement CLI and
API bindings?&lt;/p&gt;
&lt;p&gt;It does not seem like client extensions are required.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="scorecard"&gt;
&lt;h2&gt;Scorecard&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Scorecard&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n0"&gt;N0&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n1"&gt;N1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n2"&gt;N2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n4"&gt;N4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n5"&gt;N5&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d1"&gt;D1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d3"&gt;D3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c2"&gt;C2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c3"&gt;C3&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c4"&gt;C4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c6"&gt;C6&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c7"&gt;C7&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c8"&gt;C8&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r1"&gt;R1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r2"&gt;R2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r3"&gt;R3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r4"&gt;R4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#s1"&gt;S1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Final remarks: better coverage and more exhaustive documentation are the gaps
identified with this project.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 07 Oct 2016 00:00:00 </pubDate></item><item><title>Networking-onos Scorecard</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata/networking-onos.html</link><description>

&lt;section id="neutron-integration"&gt;
&lt;h2&gt;Neutron integration&lt;/h2&gt;
&lt;ul id="n0"&gt;
&lt;li&gt;&lt;p&gt;N0. Does the project use the Neutron REST API or relies on proprietary backends?&lt;/p&gt;
&lt;p&gt;No, the project maps the various Neutron APIs on top of the ONOS SDN controller.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n1"&gt;
&lt;li&gt;&lt;p&gt;N1. Does the project integrate/use neutron-lib?&lt;/p&gt;
&lt;p&gt;No. The project imports Neutron only a couple of dozen times. That said,
neutron-lib looks to be included in the requirements.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n2"&gt;
&lt;li&gt;&lt;p&gt;N2. Do project members actively contribute to help neutron-lib achieve its
goal?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n3"&gt;
&lt;li&gt;&lt;p&gt;N3. Do project members collaborate with the core team to enable subprojects
to loosely integrate with the Neutron core platform by helping with the definition
of modular interfaces?&lt;/p&gt;
&lt;p&gt;There is no evidence of that.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n4"&gt;
&lt;li&gt;&lt;p&gt;N4. How does the project provide networking services? Does it use modular interfaces
as provided by the core platform?&lt;/p&gt;
&lt;p&gt;Yes, though there are some &lt;a class="reference external" href="https://github.com/openstack/networking-onos/commit/d6b982c37c3809157b9265cf6000cf6735007b80"&gt;code smells&lt;/a&gt; that may need clean up.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n5"&gt;
&lt;li&gt;&lt;p&gt;N5. If the project provides new API extensions, have API extensions been discussed
and accepted by the Neutron drivers team? Please provide links to API specs, if
required.&lt;/p&gt;
&lt;p&gt;The project currently provides a driver for the SFC API (though the requirement seems
&lt;a class="reference external" href="https://github.com/openstack/networking-onos/blob/9df5b664deeada9557183c03189ce6ee40d81a5f/test-requirements.txt"&gt;misplaced&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul id="d1"&gt;
&lt;li&gt;&lt;p&gt;D1. Does the project have a doc tox target, functional and continuously
working? Provide proof (links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/networking-onos/"&gt;http://docs.openstack.org/developer/networking-onos/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d2"&gt;
&lt;li&gt;&lt;p&gt;D2. If the project provide API extensions, does the project have an
api-ref tox target, functional and continously working? Provide proof
(links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;The project does not propose new APIs.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d3"&gt;
&lt;li&gt;&lt;p&gt;D3. Does the project have a releasenotes tox target, functional and
continously working? Provide proof.&lt;/p&gt;
&lt;p&gt;The target seems set up but no release notes are available.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/347209/"&gt;https://review.openstack.org/#/c/347209/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d4"&gt;
&lt;li&gt;&lt;p&gt;D4. Describe the types of documentation available: developer, end user,
administrator, deployer.&lt;/p&gt;
&lt;p&gt;The documentation is available but content is bare bone.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="continuous-integration"&gt;
&lt;h2&gt;Continuous Integration&lt;/h2&gt;
&lt;ul id="c1"&gt;
&lt;li&gt;&lt;p&gt;C1. Does the project have a Grafana dashboard showing historical trends of
all the jobs available? Provide proof (links to grafana.openstack.org).&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c2"&gt;
&lt;li&gt;&lt;p&gt;C2. Does the project have CI for unit coverage? Provide proof (links to
logs.openstack.org)&lt;/p&gt;
&lt;p&gt;Yes. Broken at the time of writing.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/91/361491/3/check/gate-networking-onos-python27-ubuntu-xenial/7e1a4a5/testr_results.html.gz"&gt;http://logs.openstack.org/91/361491/3/check/gate-networking-onos-python27-ubuntu-xenial/7e1a4a5/testr_results.html.gz&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c3"&gt;
&lt;li&gt;&lt;p&gt;C3. Does the project have CI for functional coverage? If so, does it include
DB migration and sync validation?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c4"&gt;
&lt;li&gt;&lt;p&gt;C4. Does the project have CI for fullstack coverage?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c5"&gt;
&lt;li&gt;&lt;p&gt;C5. Does the project have CI for Tempest coverage? If so, specify nature
(API and/or Scenario).&lt;/p&gt;
&lt;p&gt;Yes, but non-voting and broken.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/91/361491/3/check/gate-tempest-dsvm-networking-onos/81dae2c/logs"&gt;http://logs.openstack.org/91/361491/3/check/gate-tempest-dsvm-networking-onos/81dae2c/logs&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c6"&gt;
&lt;li&gt;&lt;p&gt;C6. Does the project require CI for Grenade coverage?&lt;/p&gt;
&lt;p&gt;That does not seem like a Grenade style job be required, but there is no
hint that the plugins would be able to talk to controllers running with
different versions.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c7"&gt;
&lt;li&gt;&lt;p&gt;C7. Does the project provide multinode CI?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c8"&gt;
&lt;li&gt;&lt;p&gt;C8. Does the project support Python 3.x? Provide proof.&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="release-footprint"&gt;
&lt;h2&gt;Release footprint&lt;/h2&gt;
&lt;ul id="r1"&gt;
&lt;li&gt;&lt;p&gt;R1. Does the project adopt semver?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r2"&gt;
&lt;li&gt;&lt;p&gt;R2. Does the project have release deliverables? Provide proof as available
in the &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/"&gt;release repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/releases/blob/master/deliverables/_independent/networking-onos.yaml"&gt;https://github.com/openstack/releases/blob/master/deliverables/_independent/networking-onos.yaml&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r3"&gt;
&lt;li&gt;&lt;p&gt;R3. Does the project use upper-constraints?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/networking-onos/blob/master/tox.ini#L11"&gt;https://github.com/openstack/networking-onos/blob/master/tox.ini#L11&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r4"&gt;
&lt;li&gt;&lt;p&gt;Does the project integrate with OpenStack Proposal Bot for requirements updates?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/requirements/commit/0fabc239e2a9d5453e17ac18b8b4b6c22412cfb0"&gt;https://github.com/openstack/requirements/commit/0fabc239e2a9d5453e17ac18b8b4b6c22412cfb0&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="stable-backports"&gt;
&lt;h2&gt;Stable backports&lt;/h2&gt;
&lt;ul id="s1"&gt;
&lt;li&gt;&lt;p&gt;S1. Does the project have stable branches and/or tags? Provide history of
backports.&lt;/p&gt;
&lt;p&gt;At the time of writing there is a stable mitaka branch, with no substantial
history.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/q/project:openstack/networking-onos+branch:stable/mitaka"&gt;https://review.openstack.org/#/q/project:openstack/networking-onos+branch:stable/mitaka&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="client-library"&gt;
&lt;h2&gt;Client library&lt;/h2&gt;
&lt;ul id="l1"&gt;
&lt;li&gt;&lt;p&gt;L1. If the project requires a client library, how does it implement CLI and
API bindings?&lt;/p&gt;
&lt;p&gt;It does not seem like client extensions are required.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="scorecard"&gt;
&lt;h2&gt;Scorecard&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Scorecard&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n0"&gt;N0&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n1"&gt;N1&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n2"&gt;N2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n4"&gt;N4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n5"&gt;N5&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d1"&gt;D1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d3"&gt;D3&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c2"&gt;C2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c3"&gt;C3&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c4"&gt;C4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c6"&gt;C6&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c7"&gt;C7&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c8"&gt;C8&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r1"&gt;R1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r2"&gt;R2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r3"&gt;R3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r4"&gt;R4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#s1"&gt;S1&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Final remarks: the networking-onos project is not well managed, it lacks in
many areas and is considerably subpar compared to other Neutron subprojects.
Steering it in the right direction in time of the Ocata-1 deadline would
require an herculean effort. That said, at the time of writing (October
2016), the project has not seen active development since the end of August
2016. The project will be removed from the Stadium for the Ocata release.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 07 Oct 2016 00:00:00 </pubDate></item><item><title>Networking-ovn Scorecard</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata/networking-ovn.html</link><description>

&lt;section id="neutron-integration"&gt;
&lt;h2&gt;Neutron integration&lt;/h2&gt;
&lt;ul id="n0"&gt;
&lt;li&gt;&lt;p&gt;N0. Does the project use the Neutron REST API or relies on proprietary backends?&lt;/p&gt;
&lt;p&gt;networking-ovn implements a backend for the existing Neutron REST API.  It
is not a client of Neutron REST APIs.  It also does not rely on any proprietary
backends.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n1"&gt;
&lt;li&gt;&lt;p&gt;N1. Does the project integrate/use neutron-lib?&lt;/p&gt;
&lt;p&gt;Yes. The project uses neutron-lib with an overall migration status of 11.66% as of
October 10, 2016.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n2"&gt;
&lt;li&gt;&lt;p&gt;N2. Do project members actively contribute to help neutron-lib achieve its
goal?&lt;/p&gt;
&lt;p&gt;No. The project core team members are not actively contributing to neutron-lib.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n3"&gt;
&lt;li&gt;&lt;p&gt;N3. Do project members collaborate with the core team to enable subprojects
to loosely integrate with the Neutron core platform by helping with the definition
of modular interfaces?&lt;/p&gt;
&lt;p&gt;The project team members have helped in this area by opening bug reports and
providing fixes as appropriate (e.g. &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1597898"&gt;https://bugs.launchpad.net/neutron/+bug/1597898&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n4"&gt;
&lt;li&gt;&lt;p&gt;N4. How does the project provide networking services? Does it use modular interfaces
as provided by the core platform?&lt;/p&gt;
&lt;p&gt;The project uses the modular interfaces (ML2 and L3) provided by the core platform to
enable networking services. Some of the project’s networking services are provided via
native services instead of via neutron agents.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n5"&gt;
&lt;li&gt;&lt;p&gt;N5. If the project provides new API extensions, have API extensions been discussed
and accepted by the Neutron drivers team? Please provide links to API specs, if
required.&lt;/p&gt;
&lt;p&gt;The project does not provide new API extensions.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul id="d1"&gt;
&lt;li&gt;&lt;p&gt;D1. Does the project have a doc tox target, functional and continuously
working? Provide proof (links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/networking-ovn/tree/tox.ini"&gt;http://git.openstack.org/cgit/openstack/networking-ovn/tree/tox.ini&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/networking-ovn/"&gt;http://docs.openstack.org/developer/networking-ovn/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d2"&gt;
&lt;li&gt;&lt;p&gt;D2. If the project provide API extensions, does the project have an
api-ref tox target, functional and continously working? Provide proof
(links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d3"&gt;
&lt;li&gt;&lt;p&gt;D3. Does the project have a releasenotes tox target, functional and
continously working? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/networking-ovn/tree/tox.ini"&gt;http://git.openstack.org/cgit/openstack/networking-ovn/tree/tox.ini&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/releasenotes/networking-ovn/"&gt;http://docs.openstack.org/releasenotes/networking-ovn/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d4"&gt;
&lt;li&gt;&lt;p&gt;D4. Describe the types of documentation available: developer, end user,
administrator, deployer.&lt;/p&gt;
&lt;p&gt;The project itself provides primarily developer, administrator and
deployer documention at &lt;a class="reference external" href="http://docs.openstack.org/developer/networking-ovn/"&gt;http://docs.openstack.org/developer/networking-ovn/&lt;/a&gt;,
and relies on community OpenStack neutron documentation for end user
documentation.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="continuous-integration"&gt;
&lt;h2&gt;Continuous Integration&lt;/h2&gt;
&lt;ul id="c1"&gt;
&lt;li&gt;&lt;p&gt;C1. Does the project have a Grafana dashboard showing historical trends of
all the jobs available? Provide proof (links to grafana.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://grafana.openstack.org/dashboard/db/networking-ovn-failure-rates"&gt;http://grafana.openstack.org/dashboard/db/networking-ovn-failure-rates&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c2"&gt;
&lt;li&gt;&lt;p&gt;C2. Does the project have CI for unit coverage? Provide proof (links to
logs.openstack.org)&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/g/project/openstack~2Fnetworking-ovn"&gt;http://status.openstack.org/openstack-health/#/g/project/openstack~2Fnetworking-ovn&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c3"&gt;
&lt;li&gt;&lt;p&gt;C3. Does the project have CI for functional coverage? If so, does it include
DB migration and sync validation?&lt;/p&gt;
&lt;p&gt;Yes. The project does not introduce any Data Model at the moment and hence it does
not require DB migration and sync validation.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/job/gate-networking-ovn-dsvm-functional"&gt;http://status.openstack.org/openstack-health/#/job/gate-networking-ovn-dsvm-functional&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c4"&gt;
&lt;li&gt;&lt;p&gt;C4. Does the project have CI for fullstack coverage?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c5"&gt;
&lt;li&gt;&lt;p&gt;C5. Does the project have CI for Tempest coverage? If so, specify nature
(API and/or Scenario).&lt;/p&gt;
&lt;p&gt;Yes. The jobs test both native and conventional networking services with both
API and scenario tests as taken by the Tempest project.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/g/project/openstack~2Fnetworking-ovn"&gt;http://status.openstack.org/openstack-health/#/g/project/openstack~2Fnetworking-ovn&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/networking-ovn/tree/devstack/devstackgatenativeservicesrc"&gt;http://git.openstack.org/cgit/openstack/networking-ovn/tree/devstack/devstackgatenativeservicesrc&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/networking-ovn/tree/devstack/devstackgaterc"&gt;http://git.openstack.org/cgit/openstack/networking-ovn/tree/devstack/devstackgaterc&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c6"&gt;
&lt;li&gt;&lt;p&gt;C6. Does the project require CI for Grenade coverage?&lt;/p&gt;
&lt;p&gt;A non-voting job is available. More is needed.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/65/378065/7/check/gate-grenade-dsvm-networking-ovn-nv/06fda71/logs/"&gt;http://logs.openstack.org/65/378065/7/check/gate-grenade-dsvm-networking-ovn-nv/06fda71/logs/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/networking-ovn/+bug/1464283"&gt;https://bugs.launchpad.net/networking-ovn/+bug/1464283&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/networking-ovn/+bug/1627810"&gt;https://bugs.launchpad.net/networking-ovn/+bug/1627810&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c7"&gt;
&lt;li&gt;&lt;p&gt;C7. Does the project provide multinode CI?&lt;/p&gt;
&lt;p&gt;This area is under active development. Some pointers below.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/378032/"&gt;https://review.openstack.org/#/c/378032/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/networking-ovn/+bug/1621627"&gt;https://bugs.launchpad.net/networking-ovn/+bug/1621627&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/networking-ovn/+bug/1634511"&gt;https://bugs.launchpad.net/networking-ovn/+bug/1634511&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c8"&gt;
&lt;li&gt;&lt;p&gt;C8. Does the project support Python 3.x? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes. Some pointers below.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/65/378065/7/check/gate-networking-ovn-python35/67049ca/"&gt;http://logs.openstack.org/65/378065/7/check/gate-networking-ovn-python35/67049ca/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="release-footprint"&gt;
&lt;h2&gt;Release footprint&lt;/h2&gt;
&lt;ul id="r1"&gt;
&lt;li&gt;&lt;p&gt;R1. Does the project adopt semver?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r2"&gt;
&lt;li&gt;&lt;p&gt;R2. Does the project have release deliverables? Provide proof as available
in the &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/"&gt;release repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yes. The project has release deliverables with newton being the first.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/deliverables/newton/networking-ovn.yaml"&gt;http://git.openstack.org/cgit/openstack/releases/tree/deliverables/newton/networking-ovn.yaml&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r3"&gt;
&lt;li&gt;&lt;p&gt;R3. Does the project use upper-constraints?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/networking-ovn/blob/master/tox.ini#L8"&gt;https://github.com/openstack/networking-ovn/blob/master/tox.ini#L8&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r4"&gt;
&lt;li&gt;&lt;p&gt;Does the project integrate with OpenStack Proposal Bot for requirements updates?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/requirements/commit/c8f5860a70a7dd7b5a87ff4c88ffac0bd466c609"&gt;https://github.com/openstack/requirements/commit/c8f5860a70a7dd7b5a87ff4c88ffac0bd466c609&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="stable-backports"&gt;
&lt;h2&gt;Stable backports&lt;/h2&gt;
&lt;ul id="s1"&gt;
&lt;li&gt;&lt;p&gt;S1. Does the project have stable branches and/or tags? Provide history of
backports.&lt;/p&gt;
&lt;p&gt;Yes. The project has stable branches with stable/newton being the first.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/networking-ovn"&gt;http://git.openstack.org/cgit/openstack/networking-ovn&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="client-library"&gt;
&lt;h2&gt;Client library&lt;/h2&gt;
&lt;ul id="l1"&gt;
&lt;li&gt;&lt;p&gt;L1. If the project requires a client library, how does it implement CLI and
API bindings?&lt;/p&gt;
&lt;p&gt;The project does not require a client library.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="scorecard"&gt;
&lt;h2&gt;Scorecard&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Scorecard&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n0"&gt;N0&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n1"&gt;N1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n2"&gt;N2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n4"&gt;N4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n5"&gt;N5&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d1"&gt;D1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d3"&gt;D3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c2"&gt;C2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c3"&gt;C3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c4"&gt;C4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c6"&gt;C6&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c7"&gt;C7&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c8"&gt;C8&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r1"&gt;R1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r2"&gt;R2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r3"&gt;R3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r4"&gt;R4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#s1"&gt;S1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Final remarks: networking-ovn is a well managed project. It would be nice if
members of the project would pay some of the neutron-lib tax for the wellbeing
of the wider Neutron community but one can only wish for so much. The project
lacks in area of upgrade and multinode testing, but the team is actively
working to fill these gaps.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 07 Oct 2016 00:00:00 </pubDate></item><item><title>Networking-sfc Scorecard</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata/networking-sfc.html</link><description>

&lt;section id="neutron-integration"&gt;
&lt;h2&gt;Neutron integration&lt;/h2&gt;
&lt;ul id="n0"&gt;
&lt;li&gt;&lt;p&gt;N0. Does the project use the Neutron REST API or relies on proprietary backends?&lt;/p&gt;
&lt;p&gt;Networking-sfc implements its own set of Neutron API extensions on top of
the Neutron core framework and it does so by using the service plugin model,
The API exposed has open source implementations, and it provides a pluggable
driver mechanism for multiple backends.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n1"&gt;
&lt;li&gt;&lt;p&gt;N1. Does the project integrate/use neutron-lib?&lt;/p&gt;
&lt;p&gt;Yes. It only imports ~10% of the neutron-related imports required. There is no
periodic job to test against neutron-lib master changes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n2"&gt;
&lt;li&gt;&lt;p&gt;N2. Do project members actively contribute to help neutron-lib achieve its
goal?&lt;/p&gt;
&lt;p&gt;No, there is no tangible evidence.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n3"&gt;
&lt;li&gt;&lt;p&gt;N3. Do project members collaborate with the core team to enable subprojects
to loosely integrate with the Neutron core platform by helping with the definition
of modular interfaces?&lt;/p&gt;
&lt;p&gt;Team members helped review some of the L2 extensions related specs and patches.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n4"&gt;
&lt;li&gt;&lt;p&gt;N4. How does the project provide networking services? Does it use modular interfaces
as provided by the core platform?&lt;/p&gt;
&lt;p&gt;Yes, only recently the team managed to kill the OVS agent fork they were relying on.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/351789/"&gt;https://review.openstack.org/#/c/351789/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n5"&gt;
&lt;li&gt;&lt;p&gt;N5. If the project provides new API extensions, have API extensions been discussed
and accepted by the Neutron drivers team? Please provide links to API specs, if
required.&lt;/p&gt;
&lt;p&gt;The project currently exposes two APIs: flow classification and Port chaining both
via two separate service plugins. Minimal oversight on the latter was provided by
the Neutron team at the project inception.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul id="d1"&gt;
&lt;li&gt;&lt;p&gt;D1. Does the project have a doc tox target, functional and continuously
working? Provide proof (links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/networking-sfc/"&gt;http://docs.openstack.org/developer/networking-sfc/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d2"&gt;
&lt;li&gt;&lt;p&gt;D2. If the project provide API extensions, does the project have an
api-ref tox target, functional and continously working? Provide proof
(links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/networking-sfc/blob/master/tox.ini#L136"&gt;https://github.com/openstack/networking-sfc/blob/master/tox.ini#L136&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d3"&gt;
&lt;li&gt;&lt;p&gt;D3. Does the project have a releasenotes tox target, functional and
continously working? Provide proof.&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d4"&gt;
&lt;li&gt;&lt;p&gt;D4. Describe the types of documentation available: developer, end user,
administrator, deployer.&lt;/p&gt;
&lt;p&gt;There is some developer documentation (in the form of design documents),
deployment documentation, and some user documentation in the form of a
list of client side extensions. Some material is available on the
wiki.o.o, which ideally would be migrated over and put under version control.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/networking-sfc/"&gt;http://docs.openstack.org/developer/networking-sfc/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/newton/networking-guide/config-sfc.html"&gt;http://docs.openstack.org/newton/networking-guide/config-sfc.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="continuous-integration"&gt;
&lt;h2&gt;Continuous Integration&lt;/h2&gt;
&lt;ul id="c1"&gt;
&lt;li&gt;&lt;p&gt;C1. Does the project have a Grafana dashboard showing historical trends of
all the jobs available? Provide proof (links to grafana.openstack.org).&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/386081/"&gt;https://review.openstack.org/#/c/386081/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c2"&gt;
&lt;li&gt;&lt;p&gt;C2. Does the project have CI for unit coverage? Provide proof (links to
logs.openstack.org)&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/g/project/openstack~2Fnetworking-sfc"&gt;http://status.openstack.org/openstack-health/#/g/project/openstack~2Fnetworking-sfc&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c3"&gt;
&lt;li&gt;&lt;p&gt;C3. Does the project have CI for functional coverage? If so, does it include
DB migration and sync validation?&lt;/p&gt;
&lt;p&gt;Yes. DB migration and sync validation introduced recently.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/354359/"&gt;https://review.openstack.org/#/c/354359/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/59/354359/3/check/gate-networking-sfc-python35-db/cf7dd20/testr_results.html.gz"&gt;http://logs.openstack.org/59/354359/3/check/gate-networking-sfc-python35-db/cf7dd20/testr_results.html.gz&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c4"&gt;
&lt;li&gt;&lt;p&gt;C4. Does the project have CI for fullstack coverage?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c5"&gt;
&lt;li&gt;&lt;p&gt;C5. Does the project have CI for Tempest coverage? If so, specify nature
(API and/or Scenario).&lt;/p&gt;
&lt;p&gt;API and Scenario. Non voting.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c6"&gt;
&lt;li&gt;&lt;p&gt;C6. How does a project validates upgrades on a continuous basis? Does
the project require or support CI for Grenade coverage?&lt;/p&gt;
&lt;p&gt;No upgrade testing on a continuous basis.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c7"&gt;
&lt;li&gt;&lt;p&gt;C7. Does the project provide multinode CI?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c8"&gt;
&lt;li&gt;&lt;p&gt;C8. Does the project support Python 3.x? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/38/376538/3/check/gate-networking-sfc-python35-db/c05fa62/"&gt;http://logs.openstack.org/38/376538/3/check/gate-networking-sfc-python35-db/c05fa62/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="release-footprint"&gt;
&lt;h2&gt;Release footprint&lt;/h2&gt;
&lt;ul id="r1"&gt;
&lt;li&gt;&lt;p&gt;R1. Does the project adopt semver?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r2"&gt;
&lt;li&gt;&lt;p&gt;R2. Does the project have release deliverables? Provide proof as available
in the &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/"&gt;release repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/deliverables/_independent/networking-sfc.yaml"&gt;http://git.openstack.org/cgit/openstack/releases/tree/deliverables/_independent/networking-sfc.yaml&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r3"&gt;
&lt;li&gt;&lt;p&gt;R3. Does the project use upper-constraints?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/networking-sfc/blob/master/tox.ini#L10"&gt;https://github.com/openstack/networking-sfc/blob/master/tox.ini#L10&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r4"&gt;
&lt;li&gt;&lt;p&gt;Does the project integrate with OpenStack Proposal Bot for requirements updates?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/requirements/commit/2afcaea9a8c0363173f215c2316b59985a981d0e"&gt;https://github.com/openstack/requirements/commit/2afcaea9a8c0363173f215c2316b59985a981d0e&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="stable-backports"&gt;
&lt;h2&gt;Stable backports&lt;/h2&gt;
&lt;ul id="s1"&gt;
&lt;li&gt;&lt;p&gt;S1. Does the project have stable branches and/or tags? Provide history of
backports.&lt;/p&gt;
&lt;p&gt;Liberty and Mitaka available. Backports are under the control of the neutron
stable team. The subproject follows some release cadence that is not in sync
with neutron, and this must be rectified, ASAP.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="client-library"&gt;
&lt;h2&gt;Client library&lt;/h2&gt;
&lt;ul id="l1"&gt;
&lt;li&gt;&lt;p&gt;L1. If the project requires a client library, how does it implement CLI and
API bindings?&lt;/p&gt;
&lt;p&gt;Yes. No OSC transition yet.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="scorecard"&gt;
&lt;h2&gt;Scorecard&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Scorecard&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n0"&gt;N0&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n1"&gt;N1&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n2"&gt;N2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n4"&gt;N4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n5"&gt;N5&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d1"&gt;D1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d3"&gt;D3&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c2"&gt;C2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c3"&gt;C3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c4"&gt;C4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c6"&gt;C6&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c7"&gt;C7&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c8"&gt;C8&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r1"&gt;R1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r2"&gt;R2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r3"&gt;R3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r4"&gt;R4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#s1"&gt;S1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Final remarks: the subproject has made great progress lately. There are still
gaps to be filled, like lack of exhaustive coverage in the gate queue (current
tempest test is non-voting), and aligning with master. Client side extensions
will need to be rewritten in due course. However the subproject does not seem
to lack the resources and the focus to make timely progress when required.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 07 Oct 2016 00:00:00 </pubDate></item><item><title>Neutron-dynamic-routing Scorecard</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata/neutron-dynamic-routing.html</link><description>

&lt;section id="neutron-integration"&gt;
&lt;h2&gt;Neutron integration&lt;/h2&gt;
&lt;ul id="n0"&gt;
&lt;li&gt;&lt;p&gt;N0. Does the project use the Neutron REST API or relies on proprietary backends?&lt;/p&gt;
&lt;p&gt;The project implements its own set of Neutron API extensions on top of
the Neutron core framework and it does so by using the service plugin model.
The API exposed has open source implementations, and it provides a pluggable
mechanism for other backends.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n1"&gt;
&lt;li&gt;&lt;p&gt;N1. Does the project integrate/use neutron-lib?&lt;/p&gt;
&lt;p&gt;Yes. The migration report shows that there are currently ~300 total imports.
Neutron is imported ~80 times and Neutron-lib only ~10 times, for a migration
percentage of 13.0400%&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n2"&gt;
&lt;li&gt;&lt;p&gt;N2. Do project members actively contribute to help neutron-lib achieve its
goal?&lt;/p&gt;
&lt;p&gt;None of the project core members have merged anything meaningful into neutron-lib
(source: &lt;a class="reference external" href="https://review.openstack.org/#/q/project:openstack/neutron-lib+status:merged,75"&gt;https://review.openstack.org/#/q/project:openstack/neutron-lib+status:merged,75&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n3"&gt;
&lt;li&gt;&lt;p&gt;N3. Do project members collaborate with the core team to enable subprojects
to loosely integrate with the Neutron core platform by helping with the definition
of modular interfaces?&lt;/p&gt;
&lt;p&gt;Not particularly.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n4"&gt;
&lt;li&gt;&lt;p&gt;N4. How does the project provide networking services? Does it use modular interfaces
as provided by the core platform?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n5"&gt;
&lt;li&gt;&lt;p&gt;N5. If the project provides new API extensions, have API extensions been discussed
and accepted by the Neutron drivers team? Please provide links to API specs, if
required.&lt;/p&gt;
&lt;p&gt;The BGP extensions have been widely discussed and accepted.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://specs.openstack.org/openstack/neutron-specs/specs/mitaka/bgp-dynamic-routing.html"&gt;http://specs.openstack.org/openstack/neutron-specs/specs/mitaka/bgp-dynamic-routing.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-dynamic-routing/tree/master/neutron_dynamic_routing/extensions"&gt;https://github.com/openstack/neutron-dynamic-routing/tree/master/neutron_dynamic_routing/extensions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul id="d1"&gt;
&lt;li&gt;&lt;p&gt;D1. Does the project have a doc tox target, functional and continuously
working? Provide proof (links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-dynamic-routing/blob/master/tox.ini"&gt;https://github.com/openstack/neutron-dynamic-routing/blob/master/tox.ini&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/openstack-projects.html"&gt;http://docs.openstack.org/developer/openstack-projects.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d2"&gt;
&lt;li&gt;&lt;p&gt;D2. If the project provide API extensions, does the project have an
api-ref tox target, functional and continously working? Provide proof
(links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;No api-ref target, but the project has API documentation in tree. This
should migrate over to neutron-lib’s api-ref.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/neutron-dynamic-routing/design/api.html"&gt;http://docs.openstack.org/developer/neutron-dynamic-routing/design/api.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d3"&gt;
&lt;li&gt;&lt;p&gt;D3. Does the project have a releasenotes tox target, functional and
continously working? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes. Though nothing has been release noted.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-dynamic-routing/blob/master/tox.ini"&gt;https://github.com/openstack/neutron-dynamic-routing/blob/master/tox.ini&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/releasenotes/neutron-dynamic-routing/"&gt;http://docs.openstack.org/releasenotes/neutron-dynamic-routing/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d4"&gt;
&lt;li&gt;&lt;p&gt;D4. Describe the types of documentation available: developer, end user,
administrator, deployer.&lt;/p&gt;
&lt;p&gt;Developer documentation is rather rich for a project of this age, user
and deployer documentation is provided in the networking guide.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/neutron-dynamic-routing/"&gt;http://docs.openstack.org/developer/neutron-dynamic-routing/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/mitaka/networking-guide/adv-config-bgp-dynamic-routing.html"&gt;http://docs.openstack.org/mitaka/networking-guide/adv-config-bgp-dynamic-routing.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="continuous-integration"&gt;
&lt;h2&gt;Continuous Integration&lt;/h2&gt;
&lt;ul id="c1"&gt;
&lt;li&gt;&lt;p&gt;C1. Does the project have a Grafana dashboard showing historical trends of
all the jobs available? Provide proof (links to grafana.openstack.org).&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c2"&gt;
&lt;li&gt;&lt;p&gt;C2. Does the project have CI for unit coverage? Provide proof (links to
logs.openstack.org)&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/g/project/openstack~2Fneutron-dynamic-routing"&gt;http://status.openstack.org/openstack-health/#/g/project/openstack~2Fneutron-dynamic-routing&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c3"&gt;
&lt;li&gt;&lt;p&gt;C3. Does the project have CI for functional coverage? If so, does it include
DB migration and sync validation?&lt;/p&gt;
&lt;p&gt;Yes, but it lacks DB migration and sync validation.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/job/gate-neutron-dynamic-routing-dsvm-functional"&gt;http://status.openstack.org/openstack-health/#/job/gate-neutron-dynamic-routing-dsvm-functional&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c4"&gt;
&lt;li&gt;&lt;p&gt;C4. Does the project have CI for fullstack coverage?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c5"&gt;
&lt;li&gt;&lt;p&gt;C5. Does the project have CI for Tempest coverage? If so, specify nature
(API and/or Scenario).&lt;/p&gt;
&lt;p&gt;Yes. Though it looks like there is only basic API coverage.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/job/gate-neutron-dynamic-routing-dsvm-tempest"&gt;http://status.openstack.org/openstack-health/#/job/gate-neutron-dynamic-routing-dsvm-tempest&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c6"&gt;
&lt;li&gt;&lt;p&gt;C6. Does the project require CI for Grenade coverage?&lt;/p&gt;
&lt;p&gt;Yes. But it has none.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c7"&gt;
&lt;li&gt;&lt;p&gt;C7. Does the project provide multinode CI?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c8"&gt;
&lt;li&gt;&lt;p&gt;C8. Does the project support Python 3.x? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="release-footprint"&gt;
&lt;h2&gt;Release footprint&lt;/h2&gt;
&lt;ul id="r1"&gt;
&lt;li&gt;&lt;p&gt;R1. Does the project adopt semver?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r2"&gt;
&lt;li&gt;&lt;p&gt;R2. Does the project have release deliverables? Provide proof as available
in the &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/"&gt;release repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yes, the release is responsibility of the neutron-release team.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r3"&gt;
&lt;li&gt;&lt;p&gt;R3. Does the project use upper-constraints?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-dynamic-routing/blob/master/tox.ini#L11"&gt;https://github.com/openstack/neutron-dynamic-routing/blob/master/tox.ini#L11&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r4"&gt;
&lt;li&gt;&lt;p&gt;Does the project integrate with OpenStack Proposal Bot for requirements updates?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/requirements/commit/d722a8add81bb20943564146904e202dda85a526"&gt;https://github.com/openstack/requirements/commit/d722a8add81bb20943564146904e202dda85a526&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="stable-backports"&gt;
&lt;h2&gt;Stable backports&lt;/h2&gt;
&lt;ul id="s1"&gt;
&lt;li&gt;&lt;p&gt;S1. Does the project have stable branches and/or tags? Provide history of
backports.&lt;/p&gt;
&lt;p&gt;Yes, stable maintenance is responsibility of the neutron-stable-maint team.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="client-library"&gt;
&lt;h2&gt;Client library&lt;/h2&gt;
&lt;ul id="l1"&gt;
&lt;li&gt;&lt;p&gt;L1. If the project requires a client library, how does it implement CLI and
API bindings?&lt;/p&gt;
&lt;p&gt;There are client extensions. It looks like OSC transition has stalled badly.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/340763/"&gt;https://review.openstack.org/#/c/340763/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="scorecard"&gt;
&lt;h2&gt;Scorecard&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Scorecard&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n0"&gt;N0&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n1"&gt;N1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n2"&gt;N2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n4"&gt;N4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n5"&gt;N5&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d1"&gt;D1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d3"&gt;D3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c2"&gt;C2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c3"&gt;C3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c4"&gt;C4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c6"&gt;C6&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c7"&gt;C7&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c8"&gt;C8&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r1"&gt;R1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r2"&gt;R2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r3"&gt;R3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r4"&gt;R4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#s1"&gt;S1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="final-remarks"&gt;
&lt;h2&gt;Final remarks&lt;/h2&gt;
&lt;p&gt;Since the project setup at the beginning of Newton, lots has been achieved.
There are some gaps that need to be filled, and a focussed team should have
no problem on achieving those in time of the Ocata-1 deadline.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 07 Oct 2016 00:00:00 </pubDate></item><item><title>Neutron-fwaas Scorecard</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata/neutron-fwaas.html</link><description>

&lt;section id="neutron-integration"&gt;
&lt;h2&gt;Neutron integration&lt;/h2&gt;
&lt;ul id="n0"&gt;
&lt;li&gt;&lt;p&gt;N0. Does the project use the Neutron REST API or rely on proprietary backends?&lt;/p&gt;
&lt;p&gt;Neutron-fwaas implements its own set of Neutron API extensions on top of
the Neutron core framework and it does so by using the service plugin model.
The API exposed has open source implementations, and it provides a pluggable
mechanism for proprietary backends.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n1"&gt;
&lt;li&gt;&lt;p&gt;N1. Does the project integrate/use neutron-lib?&lt;/p&gt;
&lt;p&gt;Yes. The migration report shows that there are currently ~400 total imports.
Neutron is imported ~100 times and Neutron-lib only ~20 times, for a migration
percentage of 18.045%. The project has periodic validation with neutron-lib.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/neutron_lib_fwaas_punchlist"&gt;https://etherpad.openstack.org/p/neutron_lib_fwaas_punchlist&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n2"&gt;
&lt;li&gt;&lt;p&gt;N2. Do project members actively contribute to help neutron-lib achieve its
goal?&lt;/p&gt;
&lt;p&gt;Yes.  For example: &lt;a class="reference external" href="https://review.openstack.org/389825"&gt;https://review.openstack.org/389825&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n3"&gt;
&lt;li&gt;&lt;p&gt;N3. Do project members collaborate with the core team to enable subprojects
to loosely integrate with the Neutron core platform by helping with the definition
of modular interfaces?&lt;/p&gt;
&lt;p&gt;The team has worked successfully in delivering the &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/l3-agent-extensions"&gt;L3 agent extension framework&lt;/a&gt;, that
enabled the team to break the fork of the L3 agent. However, this framework
should be contributed to neutron-lib to help increase the positive score of
N2, which is in progress.  See:
&lt;cite&gt;Migrate neutron agent extensions to neutron-lib &amp;lt;https://review.openstack.org/#/c/385045/_&amp;gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n4"&gt;
&lt;li&gt;&lt;p&gt;N4. How does the project provide networking services? Does it use modular interfaces
as provided by the core platform?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n5"&gt;
&lt;li&gt;&lt;p&gt;N5. If the project provides new API extensions, have API extensions been discussed
and accepted by the Neutron drivers team? Please provide links to API specs, if
required.&lt;/p&gt;
&lt;p&gt;The fwaas v1 and v2 API have been widely discussed and accepted.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul id="d1"&gt;
&lt;li&gt;&lt;p&gt;D1. Does the project have a doc tox target, functional and continuously
working? Provide proof (links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-fwaas/blob/master/tox.ini"&gt;https://github.com/openstack/neutron-fwaas/blob/master/tox.ini&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d2"&gt;
&lt;li&gt;&lt;p&gt;D2. If the project provide API extensions, does the project have an
api-ref tox target, functional and continously working? Provide proof
(links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;The API reference for the v2 API has not merged at the time of writing, see
&lt;a class="reference external" href="https://review.openstack.org/#/c/391338/"&gt;FWaaS v2 API reference&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://developer.openstack.org/api-ref/networking/"&gt;http://developer.openstack.org/api-ref/networking/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d3"&gt;
&lt;li&gt;&lt;p&gt;D3. Does the project have a releasenotes tox target, functional and
continously working? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-fwaas/blob/master/tox.ini"&gt;https://github.com/openstack/neutron-fwaas/blob/master/tox.ini&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/releasenotes/neutron-fwaas/"&gt;http://docs.openstack.org/releasenotes/neutron-fwaas/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d4"&gt;
&lt;li&gt;&lt;p&gt;D4. Describe the types of documentation available: developer, end user,
administrator, deployer.&lt;/p&gt;
&lt;p&gt;Developer documentation is sparse, user documentation is stale.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/neutron-fwaas/"&gt;http://docs.openstack.org/developer/neutron-fwaas/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="continuous-integration"&gt;
&lt;h2&gt;Continuous Integration&lt;/h2&gt;
&lt;ul id="c1"&gt;
&lt;li&gt;&lt;p&gt;C1. Does the project have a Grafana dashboard showing historical trends of
all the jobs available? Provide proof (links to grafana.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://grafana.openstack.org/dashboard/db/neutron-fwaas-failure-rates"&gt;http://grafana.openstack.org/dashboard/db/neutron-fwaas-failure-rates&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c2"&gt;
&lt;li&gt;&lt;p&gt;C2. Does the project have CI for unit coverage? Provide proof (links to
logs.openstack.org)&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/g/project/openstack~2Fneutron-fwaas"&gt;http://status.openstack.org/openstack-health/#/g/project/openstack~2Fneutron-fwaas&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c3"&gt;
&lt;li&gt;&lt;p&gt;C3. Does the project have CI for functional coverage? If so, does it include
DB migration and sync validation?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/job/gate-neutron-fwaas-dsvm-functional"&gt;http://status.openstack.org/openstack-health/#/job/gate-neutron-fwaas-dsvm-functional&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c4"&gt;
&lt;li&gt;&lt;p&gt;C4. Does the project have CI for fullstack coverage?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c5"&gt;
&lt;li&gt;&lt;p&gt;C5. Does the project have CI for Tempest coverage? If so, specify nature
(API and/or Scenario).&lt;/p&gt;
&lt;p&gt;Latest Bot proposal shows a &lt;a class="reference external" href="https://review.openstack.org/#/c/378852/"&gt;grim picture&lt;/a&gt;.
No API/Scenario coverage for the v2 API, though v1 has it.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/52/378852/1/check/gate-neutron-fwaas-dsvm-tempest/68423cd/testr_results.html.gz"&gt;http://logs.openstack.org/52/378852/1/check/gate-neutron-fwaas-dsvm-tempest/68423cd/testr_results.html.gz&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Coverage for v2 API tests: &lt;a class="reference external" href="https://review.openstack.org/#/c/391320/"&gt;https://review.openstack.org/#/c/391320/&lt;/a&gt; (WIP)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Coverage for v2 scenario tests: &lt;a class="reference external" href="https://review.openstack.org/#/c/391392/"&gt;https://review.openstack.org/#/c/391392/&lt;/a&gt; (WIP)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c6"&gt;
&lt;li&gt;&lt;p&gt;C6. How does a project validate upgrades on a continuous basis? Does
the project require or support CI for Grenade coverage?&lt;/p&gt;
&lt;p&gt;No, but it does in the experimental queue.  Some tests need to be identified as smoke tests.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c7"&gt;
&lt;li&gt;&lt;p&gt;C7. Does the project provide multinode CI?&lt;/p&gt;
&lt;p&gt;No, but it is in progress.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/386933/"&gt;https://review.openstack.org/#/c/386933/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c8"&gt;
&lt;li&gt;&lt;p&gt;C8. Does the project support Python 3.x? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/52/378852/1/check/gate-neutron-fwaas-python35/b321bc5/testr_results.html.gz"&gt;http://logs.openstack.org/52/378852/1/check/gate-neutron-fwaas-python35/b321bc5/testr_results.html.gz&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="release-footprint"&gt;
&lt;h2&gt;Release footprint&lt;/h2&gt;
&lt;ul id="r1"&gt;
&lt;li&gt;&lt;p&gt;R1. Does the project adopt semver?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r2"&gt;
&lt;li&gt;&lt;p&gt;R2. Does the project have release deliverables? Provide proof as available
in the &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/"&gt;release repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yes, the release is responsibility of the neutron-release team.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r3"&gt;
&lt;li&gt;&lt;p&gt;R3. Does the project use upper-constraints?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-fwaas/blob/master/tox.ini#L11"&gt;https://github.com/openstack/neutron-fwaas/blob/master/tox.ini#L11&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r4"&gt;
&lt;li&gt;&lt;p&gt;Does the project integrate with OpenStack Proposal Bot for requirements updates?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/requirements/commit/1d545edbebfff2e8983d6cab24a92c32636dd6bf"&gt;https://github.com/openstack/requirements/commit/1d545edbebfff2e8983d6cab24a92c32636dd6bf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="stable-backports"&gt;
&lt;h2&gt;Stable backports&lt;/h2&gt;
&lt;ul id="s1"&gt;
&lt;li&gt;&lt;p&gt;S1. Does the project have stable branches and/or tags? Provide history of
backports.&lt;/p&gt;
&lt;p&gt;Yes, stable maintenance is responsibility of the neutron-stable-maint team.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="client-library"&gt;
&lt;h2&gt;Client library&lt;/h2&gt;
&lt;ul id="l1"&gt;
&lt;li&gt;&lt;p&gt;L1. If the project requires a client library, how does it implement CLI and
API bindings?&lt;/p&gt;
&lt;p&gt;There are Neutron CLI and API bindings for v1, none released for v2 yet.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="scorecard"&gt;
&lt;h2&gt;Scorecard&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Scorecard&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n0"&gt;N0&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n1"&gt;N1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n2"&gt;N2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n4"&gt;N4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n5"&gt;N5&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d1"&gt;D1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d3"&gt;D3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c2"&gt;C2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c3"&gt;C3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c4"&gt;C4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c6"&gt;C6&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c7"&gt;C7&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c8"&gt;C8&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r1"&gt;R1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r2"&gt;R2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r3"&gt;R3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r4"&gt;R4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#s1"&gt;S1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="final-remarks"&gt;
&lt;h2&gt;Final remarks&lt;/h2&gt;
&lt;p&gt;At the time of writing the project scores positively in 17 out of 22
criteria. Even though the fwaas team has made quite a progress during the
Newton cycle, closing the gap on all the remaining unmet criteria in time
for Ocata-1 (Nov 14 2016) seems challenging.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 07 Oct 2016 00:00:00 </pubDate></item><item><title>Neutron-vpnaas Scorecard</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/stadium/ocata/neutron-vpnaas.html</link><description>

&lt;section id="neutron-integration"&gt;
&lt;h2&gt;Neutron integration&lt;/h2&gt;
&lt;ul id="n0"&gt;
&lt;li&gt;&lt;p&gt;N0. Does the project use the Neutron REST API or relies on proprietary backends?&lt;/p&gt;
&lt;p&gt;Neutron-vpnaas implements its own set of Neutron API extensions on top of
the Neutron core framework and it does so by using the service plugin model.
The API exposed has open source implementations, and it provides a pluggable
mechanism for proprietary backends.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n1"&gt;
&lt;li&gt;&lt;p&gt;N1. Does the project integrate/use neutron-lib?&lt;/p&gt;
&lt;p&gt;Yes. The migration report shows that there are currently ~600 total imports.
Neutron is imported ~150 times and Neutron-lib only ~15 times, for a migration
percentage of 10.0500%&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n2"&gt;
&lt;li&gt;&lt;p&gt;N2. Do project members actively contribute to help neutron-lib achieve its
goal?&lt;/p&gt;
&lt;p&gt;None of the project core members have merged anything meaningful into neutron-lib
(source: &lt;a class="reference external" href="https://review.openstack.org/#/q/project:openstack/neutron-lib+status:merged,75"&gt;https://review.openstack.org/#/q/project:openstack/neutron-lib+status:merged,75&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n3"&gt;
&lt;li&gt;&lt;p&gt;N3. Do project members collaborate with the core team to enable subprojects
to loosely integrate with the Neutron core platform by helping with the definition
of modular interfaces?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n4"&gt;
&lt;li&gt;&lt;p&gt;N4. How does the project provide networking services? Does it use modular interfaces
as provided by the core platform?&lt;/p&gt;
&lt;p&gt;Yes, for the most part, but as far as the agent side is concerned, the project relies
on the use of a VPN agent that specializes the base L3 agent, this is prone to breakage,
and leads to deployment complications when VPN and L3 services are deployed together.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-vpnaas/blob/master/neutron_vpnaas/services/vpn/agent.py#L46"&gt;https://github.com/openstack/neutron-vpnaas/blob/master/neutron_vpnaas/services/vpn/agent.py#L46&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://logs.openstack.org/64/385664/1/check/gate-neutron-vpnaas-dsvm-api-nv/a2f4f78/logs/screen-neutron-vpnaas.txt.gz"&gt;http://logs.openstack.org/64/385664/1/check/gate-neutron-vpnaas-dsvm-api-nv/a2f4f78/logs/screen-neutron-vpnaas.txt.gz&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="n5"&gt;
&lt;li&gt;&lt;p&gt;N5. If the project provides new API extensions, have API extensions been discussed
and accepted by the Neutron drivers team? Please provide links to API specs, if
required.&lt;/p&gt;
&lt;p&gt;The vpnaas API has been widely discussed and accepted.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation"&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul id="d1"&gt;
&lt;li&gt;&lt;p&gt;D1. Does the project have a doc tox target, functional and continuously
working? Provide proof (links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini"&gt;https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d2"&gt;
&lt;li&gt;&lt;p&gt;D2. If the project provide API extensions, does the project have an
api-ref tox target, functional and continously working? Provide proof
(links to logs.openstack.org).&lt;/p&gt;
&lt;p&gt;There is an API reference but no-one has confirmed its accuracy at the
time of writing.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://developer.openstack.org/api-ref/networking/"&gt;http://developer.openstack.org/api-ref/networking/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-lib/blob/master/api-ref/source/v2/vpnaas.inc"&gt;https://github.com/openstack/neutron-lib/blob/master/api-ref/source/v2/vpnaas.inc&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d3"&gt;
&lt;li&gt;&lt;p&gt;D3. Does the project have a releasenotes tox target, functional and
continously working? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini"&gt;https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/releasenotes/neutron-vpnaas/"&gt;http://docs.openstack.org/releasenotes/neutron-vpnaas/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="d4"&gt;
&lt;li&gt;&lt;p&gt;D4. Describe the types of documentation available: developer, end user,
administrator, deployer.&lt;/p&gt;
&lt;p&gt;Developer documentation is sparse, user documentation is virtually non-existent.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/neutron-vpnaas/"&gt;http://docs.openstack.org/developer/neutron-vpnaas/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/mitaka/networking-guide/adv-config-vpnaas.html"&gt;http://docs.openstack.org/mitaka/networking-guide/adv-config-vpnaas.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="continuous-integration"&gt;
&lt;h2&gt;Continuous Integration&lt;/h2&gt;
&lt;ul id="c1"&gt;
&lt;li&gt;&lt;p&gt;C1. Does the project have a Grafana dashboard showing historical trends of
all the jobs available? Provide proof (links to grafana.openstack.org).&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c2"&gt;
&lt;li&gt;&lt;p&gt;C2. Does the project have CI for unit coverage? Provide proof (links to
logs.openstack.org)&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/g/project/openstack~2Fneutron-vpnaas"&gt;http://status.openstack.org/openstack-health/#/g/project/openstack~2Fneutron-vpnaas&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c3"&gt;
&lt;li&gt;&lt;p&gt;C3. Does the project have CI for functional coverage? If so, does it include
DB migration and sync validation?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://status.openstack.org/openstack-health/#/job/gate-neutron-vpnaas-dsvm-functional"&gt;http://status.openstack.org/openstack-health/#/job/gate-neutron-vpnaas-dsvm-functional&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c4"&gt;
&lt;li&gt;&lt;p&gt;C4. Does the project have CI for fullstack coverage?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c5"&gt;
&lt;li&gt;&lt;p&gt;C5. Does the project have CI for Tempest coverage? If so, specify nature
(API and/or Scenario).&lt;/p&gt;
&lt;p&gt;Latest Bot proposal shows a &lt;a class="reference external" href="https://review.openstack.org/#/c/377475/"&gt;mixed picture&lt;/a&gt;,
API coverage is non-voting.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c6"&gt;
&lt;li&gt;&lt;p&gt;C6. Does the project require CI for Grenade coverage?&lt;/p&gt;
&lt;p&gt;Yes. But it has none.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c7"&gt;
&lt;li&gt;&lt;p&gt;C7. Does the project provide multinode CI?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="c8"&gt;
&lt;li&gt;&lt;p&gt;C8. Does the project support Python 3.x? Provide proof.&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="release-footprint"&gt;
&lt;h2&gt;Release footprint&lt;/h2&gt;
&lt;ul id="r1"&gt;
&lt;li&gt;&lt;p&gt;R1. Does the project adopt semver?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r2"&gt;
&lt;li&gt;&lt;p&gt;R2. Does the project have release deliverables? Provide proof as available
in the &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/releases/tree/"&gt;release repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yes, the release is responsibility of the neutron-release team.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id="r3"&gt;
&lt;li&gt;&lt;p&gt;R3. Does the project use upper-constraints?&lt;/p&gt;
&lt;p&gt;Yes.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini#L10"&gt;https://github.com/openstack/neutron-vpnaas/blob/master/tox.ini#L10&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple" id="r4"&gt;
&lt;li&gt;&lt;p&gt;Does the project integrate with OpenStack Proposal Bot for requirements updates?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Yes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/requirements/commit/1d545edbebfff2e8983d6cab24a92c32636dd6bf"&gt;https://github.com/openstack/requirements/commit/1d545edbebfff2e8983d6cab24a92c32636dd6bf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="stable-backports"&gt;
&lt;h2&gt;Stable backports&lt;/h2&gt;
&lt;ul id="s1"&gt;
&lt;li&gt;&lt;p&gt;S1. Does the project have stable branches and/or tags? Provide history of
backports.&lt;/p&gt;
&lt;p&gt;Yes, stable maintainance is responsibility of the neutron-stable team.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="client-library"&gt;
&lt;h2&gt;Client library&lt;/h2&gt;
&lt;ul id="l1"&gt;
&lt;li&gt;&lt;p&gt;L1. If the project requires a client library, how does it implement CLI and
API bindings?&lt;/p&gt;
&lt;p&gt;There are Neutron CLI and API bindings, but none for OSC.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="scorecard"&gt;
&lt;h2&gt;Scorecard&lt;/h2&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head" colspan="2"&gt;&lt;p&gt;Scorecard&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n0"&gt;N0&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n1"&gt;N1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n2"&gt;N2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n3"&gt;N3&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n4"&gt;N4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#n5"&gt;N5&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d1"&gt;D1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d2"&gt;D2&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d3"&gt;D3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#d4"&gt;D4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c1"&gt;C1&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c2"&gt;C2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c3"&gt;C3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c4"&gt;C4&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c5"&gt;C5&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c6"&gt;C6&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c7"&gt;C7&lt;/a&gt; |    N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#c8"&gt;C8&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r1"&gt;R1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r2"&gt;R2&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r3"&gt;R3&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#r4"&gt;R4&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td colspan="2"&gt;&lt;p&gt;&lt;a class="reference internal" href="#s1"&gt;S1&lt;/a&gt; |    Y&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;a class="reference internal" href="#l1"&gt;L1&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="final-remarks"&gt;
&lt;h2&gt;Final remarks&lt;/h2&gt;
&lt;p&gt;At the time of writing the project scores positively in about half of the
criteria. The neutron-vpnaas project has been in the doldrums for quite a
while and the release notes show it. Closing the gap on all the remaining
unmet criteria in time for Ocata-1 (Nov 14 2016) knowing the level of
commitment required and lack of resources available makes it clear that
this project is ready to be left to its own destiny.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 07 Oct 2016 00:00:00 </pubDate></item><item><title>Extend Quota API to report usage statistics</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/pike/extend-quota-api-to-send-usage-stats.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1599488"&gt;https://bugs.launchpad.net/neutron/+bug/1599488&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The current Neutron Quota API does not provide extensive information about quotas.
Providing a detailed information about quotas will be beneficial to Horizon web
app.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The current Neutron Quota API just reports the resources and their limits for
a tenant. This current approach is inefficient for Horizon and quota users in general.
Quota APIs of other projects(nova and cinder) include usage details for
resources under a specific tenant.&lt;/p&gt;
&lt;p&gt;There is a problem of manually counting all of neutron resources [1],
instead of using one Quota API call to get all detailed information
for resources under a specific project.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The “Quota Sets” extension provided by Nova[2] and Cinder[3]
should be adopted by Neutron, in order to provide better cross-project APIs
when it comes to resource quotas and more features.&lt;/p&gt;
&lt;p&gt;The existing quota extension lists the current set of quota limits for a specified project.
We propose to add a new extension, quota_detail, which is available via the same endpoint.
This new extension will have a new action “detail” which lists quota details for a project.
Details like reserved, used and limit for a resource will be available.&lt;/p&gt;
&lt;p&gt;Possible use cases of extended quota API is to simplify and provide
improvements in Horizon and OpenStack/Neutron client.&lt;/p&gt;
&lt;p&gt;The new “Quota Extension” API extension in neutron will not have ‘user-id’ as part of the
arguments to list detail quotas.
This is because neutron supports only simple per-project quotas&lt;/p&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Currently, the Quota API provides the following REST API endpoint for
quota details for a specific tenant/project.&lt;/p&gt;
&lt;p&gt;GET /v2.0/quotas/{tenant_id}&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"quota"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"network"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"floatingip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"subnetpool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"security_group_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"router"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"rbac_policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In the new Quotas API extension, a more featureful API would be introduced
that provides the &lt;em&gt;limit&lt;/em&gt;, &lt;em&gt;reserved&lt;/em&gt; and &lt;em&gt;in_use&lt;/em&gt; counts for resources under
a specific project.
The current implementation of reservation in neutron is ephemeral and will not
up but show a default value of “0” to users.&lt;/p&gt;
&lt;p&gt;GET /v2.0/quotas/{tenant_id}/detail&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"quota"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"subnet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"reserved"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"in_use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"network"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"reserved"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"in_use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"floatingip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"reserved"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"in_use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"subnetpool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"reserved"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"in_use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"security_group_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"reserved"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"in_use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"security_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"reserved"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"in_use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"router"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"reserved"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"in_use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"rbac_policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"reserved"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"in_use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"reserved"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"in_use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="command-line-client-impact"&gt;
&lt;h3&gt;Command Line Client Impact&lt;/h3&gt;
&lt;p&gt;A new optional argument will be added to the openstack client,
for example:
$ openstack quota show {tenant_id/project_id} –detail&lt;/p&gt;
&lt;p&gt;Horizon uses neutronclient to get quotas from neutron api.
Since CLI end of neutronclient will be deprecated soon, only the HTTP
side of neutronclient will be implemented for horizon use.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;Changes in Horizon&lt;/p&gt;
&lt;p&gt;out of scope for this spec.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Prince Boateng(&lt;a class="reference external" href="mailto:prince.a.owusu.boateng%40intel.com"&gt;prince&lt;span&gt;.&lt;/span&gt;a&lt;span&gt;.&lt;/span&gt;owusu&lt;span&gt;.&lt;/span&gt;boateng&lt;span&gt;@&lt;/span&gt;intel&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)
Aradhana Singh(&lt;a class="reference external" href="mailto:aradhana1.singh%40intel.com"&gt;aradhana1&lt;span&gt;.&lt;/span&gt;singh&lt;span&gt;@&lt;/span&gt;intel&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Extend Quota DB driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend current API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create new Quota extension&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add CLI openstackclient&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Write tests to verify the correct data model is returned from API&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Write tests to check responses for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;reserved&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;in_use&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;limits&lt;/span&gt;&lt;/code&gt; parameters for
resources are consistent with the changes introduced.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1]: &lt;a class="reference external" href="https://github.com/openstack/horizon/blob/10.0.0.0b1/openstack_dashboard/usage/quotas.py#L313-L336"&gt;https://github.com/openstack/horizon/blob/10.0.0.0b1/openstack_dashboard/usage/quotas.py#L313-L336&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[2]: &lt;a class="reference external" href="http://developer.openstack.org/api-ref-compute-v2.1.html#listDetailQuotas"&gt;http://developer.openstack.org/api-ref-compute-v2.1.html#listDetailQuotas&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[3]: &lt;a class="reference external" href="http://developer.openstack.org/api-ref-blockstorage-v2.html#showQuota"&gt;http://developer.openstack.org/api-ref-blockstorage-v2.html#showQuota&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[4]: &lt;a class="reference external" href="https://review.openstack.org/#/c/383673"&gt;https://review.openstack.org/#/c/383673&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 29 Jul 2016 00:00:00 </pubDate></item><item><title>Routed Networks</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/newton/routed-networks.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/routed-networks"&gt;https://blueprints.launchpad.net/neutron/+spec/routed-networks&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;section id="desired-use-case"&gt;
&lt;h3&gt;Desired Use Case&lt;/h3&gt;
&lt;p&gt;In many cases, physical data center networks are architected with a
differentiation between layers 2 and 3.  Said another way, there are distinct
L2 network segments which are only available to a subset of compute hosts.
Routing allows traffic to cross these boundaries.  These topologies are used to
manage network resource capacity (IP addresses, broadcast domain size, ARP
tables, etc.) to allow for large scale networks.&lt;/p&gt;
&lt;p&gt;Operators from the &lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-operators/2015-May/007080.html"&gt;Large Deployers Team&lt;/a&gt; (LDT) and others would like an
operator-provisioned Neutron construct that is exposed to users and maps onto
this kind of physical network.  They would like this construct to represent an
L3 domain, in general having a larger scope than each of the physical L2
segments that contribute to it.  Users must be able to specify that VMs are
booted anywhere in such a domain - as opposed to on a particular physical L2
segment.  Consequently the only guaranteed connectivity between VMs on this
construct/domain is at L3; as the data path between any two VMs may involve IP
routing hops.  Fortunately many workloads only require L3 connectivity.&lt;/p&gt;
&lt;p&gt;These operators would like tenants to continue to think about and choose
Neutron networks (e.g. named like “dev” and “prod”, “red” and “blue”, etc.),
though ensuring that only L3 semantics are preserved.  Then, it would be up to
Nova and Neutron to work together to schedule the instance to a host and an L2
segment that is both L2 reachable from that host and has routable IPs
available.&lt;/p&gt;
&lt;p&gt;Specifically, operators would like to solve this problem &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1458890"&gt;without the use of
overlay networks&lt;/a&gt;.  Overlays work well with many smaller to medium scale L2
networks (in terms of number of ports) and can be overlayed on top of an L3
domain.  However, putting a large scale L2 overlay on top of an L3 domain
defeats the purpose of using an L3 domain in the first place.  They don’t want
to require users to use individual L2 domains.  Consequently, to the users’
point of view, this use case looks like booting to a single shared network with
direct external connectivity.  It does not involve self-service topologies with
individual tenant networks and virtual routers.  These may come in the future
some of which is described in &lt;a class="reference internal" href="#potential-future-work"&gt;Potential Future Work&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="why-current-model-is-insufficient"&gt;
&lt;h3&gt;Why Current Model is Insufficient&lt;/h3&gt;
&lt;p&gt;In Neutron, a Network (either a provider or a logical tenant network) is
currently assumed to represent an L2 broadcast domain.  This may make it
well-suited to modeling L2 segments as individual provider networks or when the
l2 segment is indeed a logical representation physically realized through an
overlay (i.e tunnels).  In the former case, the problem is that the user will
see a potentially long list of individual Networks without any clear reason to
distinguish them.  This is bad practice from a user experience point of view.
And, really, these segments are an implementation detail that doesn’t need to
be exposed to users.&lt;/p&gt;
&lt;p&gt;If we decide to break the above assumption and use a Network to model an L3
domain then we run in to other problems.  This spec details the solution for
these problems.  The problems and proposed solutions are detailed in the
&lt;a class="reference internal" href="#proposed-change"&gt;Proposed Change&lt;/a&gt; section.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="overview"&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
&lt;p&gt;The proposed solution begins with Neutron’s &lt;a class="reference external" href="https://github.com/openstack/neutron/blob/master/neutron/extensions/multiprovidernet.py"&gt;existing extension mechanism&lt;/a&gt;
for defining &lt;a class="reference external" href="https://bugs.launchpad.net/openstack-api-site/+bug/1242019"&gt;multi-segment networks&lt;/a&gt;.  In short, these kinds of networks are
admin provisioned networks made by a collection of segments of potentially
different layer 2 technologies (vxlan, vlan, flat, gre, …).  It can just as
easily be a collection of homogeneous segments (i.e. a single technology like
all vlans).&lt;/p&gt;
&lt;p&gt;These multi-segment networks are not widely implemented by many plugins yet.
ML2 implements them but many others do not.  Other plugins will need to
implement model changes to support multiple segments as described in this
specification.  The model currently provides no way to determine (let alone
control) whether or not the segments are bridged together to provide L2
reachability between them.&lt;/p&gt;
&lt;section id="segments"&gt;
&lt;h4&gt;Segments&lt;/h4&gt;
&lt;p&gt;The Network provides no way to model the affinity of Subnets to particular L2
segments.  All subnets are associated with the Network (the collection of
segments).&lt;/p&gt;
&lt;p&gt;This spec proposes making the Segment a first-class object in Neutron, one with
an id.  This will allow Subnets to associate with it.  The association from the
Subnet to the Network will remain but an optional &lt;em&gt;segment_id&lt;/em&gt; field will be
added to the Subnet to associate it with a particular segment.&lt;/p&gt;
&lt;p&gt;A subnet without any segment id is still assumed to span all segments.  In
general, when provisioning a routed network, all of the subnets will be
associated with a segment.&lt;/p&gt;
&lt;p&gt;When a provider Network is created, and the plugin supports the ‘segments’
extension, a Segment object is automatically created to reflect how that
Network is implemented – or a set of Segment objects, if the Network creation
used the multi-provider extension.&lt;/p&gt;
&lt;p&gt;Subsequently, those Segment objects may be updated or destroyed by the cloud
admin, and further Segment objects may be added for the same Network, and the
underlying implementation of that Network should adjust accordingly.  In
practice not all possible ‘adjustments’ will be feasible, so we may need a way
of describing the Segment object changes that a given plugin can actually
support.&lt;/p&gt;
&lt;p&gt;When a Network object is read, the ‘provider:’ and ‘segments’ properties
returned should reflect the Segment objects that are present at the time of the
read.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="l2-adjacency"&gt;
&lt;h4&gt;L2 Adjacency&lt;/h4&gt;
&lt;p&gt;An attribute called &lt;em&gt;l2-adjacency&lt;/em&gt; will be added to Neutron Networks.  This is
a boolean value where true means that you can expect L2 connectivity throughout
the Network and false means that there is no guarantee of L2 connectivity.
This attribute should be user visible to set that expectation.  The
implementation will not depend on this value, it is merely user facing.&lt;/p&gt;
&lt;p&gt;This value will be read-only and derived from the current state of Segments
within the Network.  The value will be false if subnets on the network are
attached directly to segments.  It will be true otherwise.&lt;/p&gt;
&lt;p&gt;Other plugins will be free to implement this according to their need.  For
example, Calico may just hard-code this to false and be done.  Plugins that
implement routed networks may make use of or mimick the reference
implementation’s behavior.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="dhcp-scheduling"&gt;
&lt;h4&gt;DHCP Scheduling&lt;/h4&gt;
&lt;p&gt;DHCP scheduling is currently unaware of Subnet to Segment affinity.&lt;/p&gt;
&lt;p&gt;The spec proposes changes to the DHCP scheduler when subnets are associated
with segments.  The scheduler will take care to ensure that all such segments
have a DHCP server.  If multiple DHCP servers are desired for redundancy, it
will schedule the desired number of servers to each segment.&lt;/p&gt;
&lt;p&gt;For subnets that are not associated directly to a segment, scheduling will work
just like today, assuming that any segment in the network will suffice.  There
is a possibility with some plugins that such subnets exist when L2 adjacency is
False.  This spec doesn’t solve this at this time.  Calico, one such plugin,
has solved this by running a DHCP on each compute host and some special
plumbing.&lt;/p&gt;
&lt;p&gt;It is up to the operator to ensure that a DHCP agent is available with physical
connectivity on each of the segments.&lt;/p&gt;
&lt;p&gt;Each server will be aware of the Subnets with affinity to its assigned segment.
The metadata proxy service will be available from each.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="segment-host-mapping"&gt;
&lt;h4&gt;Segment Host Mapping&lt;/h4&gt;
&lt;p&gt;Until now, Neutron Networks have generally been assumed to reach all of the
compute hosts in the deployment.  With this proposal, that will continue to be
generally true.  However, for this use case, a given segment within the network
will only reach a subset of the hosts.  This is already possible with the ML2
plugin.  Further, there is already work being done to &lt;a class="reference external" href="https://review.openstack.org/#/c/205631"&gt;utilize the mapping to
make DHCP aware of segments&lt;/a&gt;.  However, this needs to be formalized in a way
that any plugin or mechanism driver can provide it.&lt;/p&gt;
&lt;p&gt;Maintaining mappings between compute hosts and Segments will be the
responsibility of the Neutron plugin.  It could be handled using backend
specific configuration, or API primitives may be provided.&lt;/p&gt;
&lt;p&gt;At a high level, we need to be able to do some form of the following mappings
efficiently.  These operations will be reflected in new optional plugin API
methods which can be implemented by any plugin.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Segment -&amp;gt; hosts with L2 reachability to it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;host -&amp;gt; Segment(s) it can reach over L2&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, for agent-based ML2 deployments, the existing bridge mappings can
be leveraged.  In the current ML2 implementation, the necessary data is buried
in a JSON blob in a column making it opaque to DB queries.  This will have to
change.&lt;/p&gt;
&lt;p&gt;To be precise, the &lt;em&gt;configurations&lt;/em&gt; column in the &lt;a class="reference external" href="https://github.com/openstack/neutron/blob/b1999202b8/neutron/db/agents_db.py#L100"&gt;*agents* table&lt;/a&gt; holds a
json blob.  The blob looks something like this (with extraneous data trimmed
out):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
 &lt;span class="s2"&gt;"bridge_mappings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Each bridge mapping is (physnet, bridge).  The bridge can be ignored at this
point, but the physnet can be paired with the &lt;a class="reference external" href="https://github.com/openstack/neutron/blob/b1999202b8/neutron/db/agents_db.py#L87"&gt;host&lt;/a&gt; for a host / physnet
mapping.  We can join this with the &lt;a class="reference external" href="https://github.com/openstack/neutron/blob/b1999202b8/neutron/plugins/ml2/models.py#L40"&gt;network segment / physnet mapping&lt;/a&gt; to
end up with a segment / host mapping.&lt;/p&gt;
&lt;p&gt;This spec introduces a new table, segment_host_mapping, to make this final
mapping explicit.  This table will be populated and updated as agents continue
to report reachability to physnets.  In ML2, this will only work for flat and
vlan type segments.&lt;/p&gt;
&lt;p&gt;For agent-less ML2 implementations, another mechanism may need to be provided
to populate this table.  Non-ML2 plugins will also need to provide this
possibly leveraging the work already done.  Currently, there is only interest
in creating routed networks with vlan or flat networks.  We may need to
consider what happens if someone does try using it with other segment types.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="nova-scheduling"&gt;
&lt;h4&gt;Nova Scheduling&lt;/h4&gt;
&lt;p&gt;The boot workflow perceived by the user won’t change regardless of whether
he/she chooses to boot from port or from network.  However, the user should be
aware that specifying an IP address at port creation time will constrain it to
the segment with the matching subnet thus limiting the set of compute hosts on
which they could land.  In most use cases, having a particular IP address won’t
be the first thing that users want constraining their VM placement.  This
should be clear in documentation that this trade-off exists.&lt;/p&gt;
&lt;p&gt;All subnets in a typical routed Network will be associated with a Segment.  So,
if no address is specified, Neutron will delay IP address allocation for this
port.  In other words, Neutron will not consider any Subnets with associations
to Segments for automatic IP allocation until the port is bound to a host.  It
will be okay to have a port without an IP address until then.&lt;/p&gt;
&lt;p&gt;This work is under much more detailed discussion in a &lt;a class="reference external" href="https://review.openstack.org/#/c/263898/"&gt;Nova backlog spec&lt;/a&gt;.
This includes discussion of scheduling for live migration and how the scheduler
will consider IP subnets as resource pools.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="binding"&gt;
&lt;h4&gt;Binding&lt;/h4&gt;
&lt;p&gt;When scheduling is done, the port will be bound to the chosen host.  At this
point, Neutron can pick a suitable Subnet for the Port’s address and do IP
allocation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="potential-future-work"&gt;
&lt;h4&gt;Potential Future Work&lt;/h4&gt;
&lt;p&gt;This section describes some potential follow-on work that is out of the scope
of this specification.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Connecting Neutron routers to routed networks as their external gateway.
This gets really fun with DVR routers.  It could also enable dropping the FIP
namespace since the scale of each L2 network will be small (large scale L2
networks was one motivation for having the FIP namespace)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Segment api could have a DHCP enabled flag to allow disabling DHCP for
particular segments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DHCP relay could be implemented as an alternative to running a DHCP agent in
each segment.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Multi-provider network extension is foundation for modeling segmented L3
networks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Segments are first class objects with Subnets associated to them&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Migration will be provided for ML2 static segments (maybe no migration is
required, &lt;a class="reference external" href="https://github.com/openstack/neutron/blob/b1999202b8/neutron/plugins/ml2/models.py#L26"&gt;ML2 segments&lt;/a&gt; already have all the data)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Explicit denotation of l2 adjacency of segments within the same network&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Read-only attribute derived from current state of segments&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;True for single segment networks, false otherwise&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implementation changes required to make DHCP work in non-adjacent
multi-segment networks&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;May not require further modeling changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Formal modeling of host-to-segment mappings&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New table with migration from agents/configurations json blob&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deferral of IP allocation for ports of multi-segment networks&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;May not require any new model changes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;section id="segment"&gt;
&lt;h4&gt;Segment&lt;/h4&gt;
&lt;p&gt;Normal CRUD&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;For admins, ability to list the hosts reachable on a Segment&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List Subnets associated with the Segment&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="network"&gt;
&lt;h4&gt;Network&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;l2-adjacency attribute described in &lt;a class="reference internal" href="#l2-adjacency"&gt;L2 Adjacency&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="subnet"&gt;
&lt;h4&gt;Subnet&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;segment_id attribute described in &lt;a class="reference internal" href="#segments"&gt;Segments&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="port"&gt;
&lt;h4&gt;Port&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;segment_id (An unbound port with an IP may still have affinity to a Segment)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;This change isn’t expected to pose any new security concerns.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;I think we can handle these as they come up.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;The client will be enhanced to support changes in the API.  Horizon will need
to at least expose the l2-adjacency attribute on the network.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;I don’t expect this to effect performance significantly.  It enables an
L3-centric physical network topology that is proven to perform better at scale.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;This change will consider IPv4 and IPv6 equally.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Deployers will not be required to do anything when upgrade code until they want
to make use of the new features provided by this spec.  In that case, they will
need to begin with their network architecture.&lt;/p&gt;
&lt;p&gt;This spec is mostly targeted at greenfield deployments where operators have
ultimate flexibility to define the physical network topology in an L3-centric
manner.&lt;/p&gt;
&lt;p&gt;Having said that, existing deployments can make use of this new feature after
upgrading their code by deploying a new Neutron network.  They might create new
VLANs, turn on routing features in their top-of-rack switches, add routers, and
whatever else needs to be done to create an L3 network for the new network.  In
some cases, it can be done just by configuring existing physical devices.&lt;/p&gt;
&lt;p&gt;Either way, I consider this a greenfield deployment from the perspective of the
Network.&lt;/p&gt;
&lt;p&gt;There will be operators who have a large flat network, or a collection of
Neutron networks already routed together who want to convert to using a single
multi-segmented Neutron Network with &lt;em&gt;l2-adjacency&lt;/em&gt; set to false.  I would like
to discuss a migration plan with those operators.  For now, I don’t have a
complete picture for this.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;This change will have an effect on developers.  This blueprint contains API and
model changes that plugin providers will need to look at implementing.
Specifically, they will want to look at implementing &lt;a class="reference internal" href="#l2-adjacency"&gt;L2 Adjacency&lt;/a&gt;,
&lt;a class="reference internal" href="#segments"&gt;Segments&lt;/a&gt;, &lt;a class="reference internal" href="#segment-host-mapping"&gt;Segment Host Mapping&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;Yes.  This change is already a highly visible change that has been discussed on
the ML, in Neutron meetings (especially L3), and at various design summits.
Most notably, in a large deployment team session in Vancouver and in a design
session in Tokyo.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The community had a lengthy discussion about an alternative.  It avoided adding
a new object to the model by using instances of a Network for an L3 domain.  A
Neutron router would’ve been created to associate a “front” L3-only network to
any number of “backing” networks representing the L2 segments.  This
alternative acknowledged that there was L2 and L3 mingled together in the same
object.&lt;/p&gt;
&lt;p&gt;Provider networks allow much of what is described in this specification.  In
fact, the kind of Network described here is a lot like a provider network.
This spec needs to enhance the provider network idea to support the kind of L3
architecture described.&lt;/p&gt;
&lt;p&gt;Another alternative discussed at length was to add a new IpNetwork construct to
represent L3 networks.  This is how I would do it if I were to model Neutron
all over again but there isn’t a smooth path to get there from where we are
now.  The current proposal is a compromise which appears to have a much better
migration path.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~carl-baldwin"&gt;Carl Baldwin&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~minsel"&gt;Miguel Lavalle&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~neil-jerram"&gt;Neil Jerram&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~vikschw"&gt;Vikram&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~swaminathan-vasudevan"&gt;Swami&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~ryan-tidwell"&gt;Ryan Tidwell&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~reedip-banerjee"&gt;Reedip Banerjee&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~cbrandily"&gt;Cedric Brandily (ZZelle)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~kevinbenton"&gt;Kevin Benton&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~ichihara-hirofumi"&gt;Hirofumi Ichihara&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~brandon-logan"&gt;Brandon Logan&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~rtheis"&gt;Richard Theis&lt;/a&gt; (Openstack client)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please add your name here and attend the &lt;a class="reference external" href="https://wiki.openstack.org/wiki/Meetings/Neutron-Routed-Networks"&gt;Routed Networks Meeting&lt;/a&gt; if you’d
like to contribute.  If your name is here and you don’t have any time to
contribute, let me know.  This section is really just my sticky note of
contributors who can play a role in this effort.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Admin-only Segments extension&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;For ML2, use the multi-provider extension data model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add segment_id to Subnet&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Client support&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add segment_id to Port&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This represents the segment_id where IPs are allocated from and isn’t
quite the same as the Segment associated through port binding.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This should be consistent with any segment_id associated through an
&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/88b821c76e/neutron/db/models_v2.py#L92"&gt;IPAllocation&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Defer IP allocation for ports of multi-segment networks&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Without a segment, a Port should only get an IP address if there are
subnets with no segment association.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nova validates that the port has an IP.  This must be removed (preferred)
or deferred until after host binding.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Host / Segment Mapping&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update mapping when bridge mappings are received from the agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expose through API&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The list of hosts available to a Segment will be available through the
new segment API.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maintain host aggregates and create scheduler resource pools in Nova.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;These should be kept in lock-step with the Host / Segment mappings&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In Nova boot / live migrate, tie the segment_id of an existing Port to a
resource pool.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In the scheduler table, there is an “external id” in the resource pool
which needs to be matched with the segment_id in the existing Port.  I’m
not sure how Nova will notice the existing segment_id on a Port and match
it.  See the &lt;a class="reference external" href="https://review.openstack.org/#/c/263898/4/specs/backlog/approved/neutron-routed-networks.rst@148"&gt;Nova spec&lt;/a&gt; for more details.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;DHCP scheduler and agent&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Schedule segments with associated subnets to agents with reachability&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ideally, an agent should only be configured to serve subnets on the
segment its attached to (in addition to subnets without association to any
segment)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add L2 adjacency to Network&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Read-only attribute derived from current state of segments&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;True for single segment networks, false otherwise&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;The &lt;a class="reference external" href="https://review.openstack.org/#/c/263898/"&gt;Nova spec&lt;/a&gt;.  This will require coordination with Nova, especially with
the scheduler team.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;There will be changes to tempest tests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Unknown&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Segment resource (CRUD)
- its relationship to Subnets and Networks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Network l2-adjacency flag (read-only through API)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Host / Segment mapping (read-only through API)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Document the l2-adjacency flag on the Network&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Tue, 05 Jul 2016 00:00:00 </pubDate></item><item><title>Role-based Access Control for Networks</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/rbac-networks.html</link><description>

&lt;p&gt;URL of launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/rbac-networks"&gt;https://blueprints.launchpad.net/neutron/+spec/rbac-networks&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We need the ability to share Neutron networks to subsets of tenants instead
of the all-or-nothing choice we have now. This will enable many more network
management workflows encountered in enterprise/private-cloud deployments.&lt;/p&gt;
&lt;p&gt;This will be achieved through a new ‘role-based access control’ table with
entries that contain an object UUID, an object type, a target tenant, an
action and a tenant ID representing the owner of the policy.
In this generic format, it should be relatively easy to extend
role-based access control to other Neutron objects and actions.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The current option to share a Neutron network is binary. Networks are either
shared to every tenant or are not shared at all. This eliminates a lot of
grouping concepts that show up in ‘legacy’ network configurations where
classes of devices or users can access a network while others cannot.
While this is okay for many public cloud deployments where the network
abstractions serve only as L2 isolation tools, it fails to fulfill many
private cloud use cases.&lt;/p&gt;
&lt;p&gt;For example, there is no way for an administrator to define a network that
has access to a restricted resource (e.g. a multicast/broadcast feed of data)
and only allow certain tenants to attach servers to it. The same applies
for networks that may have special auditing requirements, security controls,
service guaruntees, floating IP pools, etc.&lt;/p&gt;
&lt;p&gt;In a similar context, a cloud administrator may want to completely eliminate
the ability for most tenants to create networks, subnets, and routers and
just have them attach to pre-created networks corresponding to their department
in an organization.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Introduce a new RBAC table that will control sharing of Neutron networks
between tenants. Also introduce a new API to work with RBAC entries that will
be generic enough to easily be extended to other resources that people want
controlled by RBAC.&lt;/p&gt;
&lt;p&gt;The logic surrounding shared networks will then be re-written to leverage the
new RBAC code as the first implementation. The current ‘shared’ attribute on
the network will be mapped into a wildcard entry in the new table to preserve
backwards compatibility (more details below).&lt;/p&gt;
&lt;p&gt;The forwarding semantics and ownership of objects will not be impacted by this
specification. This specification only impacts which users are allowed to
attach to networks - not how they attach or what happens afterwards.&lt;/p&gt;
&lt;p&gt;To keep things simple, this will be a whitelist-only model to begin with.
i.e. the action column can’t be a negative that states a certain tenant
can’t do something.&lt;/p&gt;
&lt;p&gt;Tenants will be able to delete ports on networks they own even if the port does
not belong to them. This is to allow tenants to have final say over networks
they own.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;Each RBAC entry will contain the following important pieces of information:
the object identifier, the object type, the tenant identifier, and the
allowed action. All entries are to allow the action they describe. There
won’t be any ‘deny’ rules at this time.&lt;/p&gt;
&lt;p&gt;The object ID is simply the UUID of the object to which the RBAC entry will be
applied.&lt;/p&gt;
&lt;p&gt;The object type simply describes the type of object to which the object ID
is a reference. For this specification, it will always be ‘network’ since
that’s the only object being introduced into RBAC right now. This information
is redundant since the object ID is unique; however, this will allow us to have
relationship tables for each type we want to support. These allow the cleaning up
of RBAC entries on an object deletion to be left to the database CASCADE
functionality. The object type isn’t stored in the database, it’s used to
determine which table to use.&lt;/p&gt;
&lt;p&gt;The target tenant will be the tenant (a.k.a. project) ID to which the RBAC entry
is granting permission to perform an action on the target object. This entry
may also be an asterisk to represent that it applies to all tenants.&lt;/p&gt;
&lt;p&gt;The action will describe what the tenant can do with the object.
For the sake of this specification, we will only have one action to start,
which will be something like ‘access_as_shared’ to indicate that the tenant
can access it like it would a shared network. This could then easily be
extended in the future to include something like ‘access_as_external’ to
provide RBAC for external networks as well. Actions will be discoverable
for each type via the API.&lt;/p&gt;
&lt;p&gt;Finally, each RBAC entry will also have a tenant ID that indicates the tenant
that created the policy itself. This will normally be the same tenant as the
object being shared, but it might not be in the case of admin-created policies
on other tenant’s networks.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="db-tables"&gt;
&lt;h3&gt;DB Tables&lt;/h3&gt;
&lt;p&gt;Each object type that RBAC applies to will get its own RBAC table.
The unique constraint will only be across all of the API fields. (i.e. Each
tenant could have multiple entries per object with different actions).
So for this spec there will just be one new networkrbacs table.&lt;/p&gt;
&lt;p&gt;The ‘shared’ column will be removed from the networks table and that will be
replaced with a query to the new table for the presence of the ‘*’ for that
network with the ‘access_as_shared’ action.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;These RBAC entries will be enabled at a new API endpoint (‘/rbac-policies’).
In order to create an entry for an object, the tenant must be the owner
of that object.&lt;/p&gt;
&lt;p&gt;In order to create an entry with a wildcard membership
tenants, the request will have to be performed in an admin context by
default but can be enabled for all tenants via policy.json.
This is done to prevent tenants from polluting every other
tenant’s network list by creating wildcard entries.&lt;/p&gt;
&lt;p&gt;In the future we can revisit to add a ‘reshare’ action or something similar if
we encounter a use case where the object owner wants to give the ability to
another tenant to share the object to more tenants.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;auto&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;id of RBAC entry&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;tenant_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;auto&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;owner of RBAC
entry&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;object_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;object
exists&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;object
affected by RBAC&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;object_type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;type has
rbac table&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;type of object&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;target_tenant&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RWU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul class="simple"&gt;
&lt;li/&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;tenant ID the
entry affects.
* for all&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;action&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;in actions
for object&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;allowed tenant
action on object&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="example-entries"&gt;
&lt;h3&gt;Example Entries&lt;/h3&gt;
&lt;p&gt;A legacy shared network:
* object_id = &amp;lt;some_net_id&amp;gt;
* object_type = network
* target_tenant = *
* action = ‘access_as_shared’
* id = &amp;lt;uuid&amp;gt;  # auto generated
* tenant_id = &amp;lt;uuid-of-policy-creator&amp;gt;  # generated by API&lt;/p&gt;
&lt;p&gt;A network shared to a specific tenant:
* object_id = &amp;lt;some_net_id&amp;gt;
* object_type = network
* target_tenant = &amp;lt;some_tenant_id&amp;gt;
* action = ‘access_as_shared’
* id = &amp;lt;uuid&amp;gt;  # auto generated
* tenant_id = &amp;lt;uuid-of-policy-creator&amp;gt;  # generated by API&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;Tenants will be able to share networks with each other. This shouldn’t be a
major issue since the ownership will never change so they will still have to
take responsibility for them when it comes to bandwidth accounting and incident
responses.&lt;/p&gt;
&lt;p&gt;If a user knows the tenant ID of someone they want to attack, they could share
networks with that tenant to pollute their network list with entries that may
be overwhelming or that may have names that trick the target tenant into
attaching VMs to it.&lt;/p&gt;
&lt;p&gt;This can likely be solved with a choice of default filtering for networks.
Unless requested by the user, the client can filter out shared networks. Then
a UI like Horizon could display the shared networks with a flag next to them
to distinguish them from the tenant’s networks. Thoughts?&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;New CLI workflow for setting these permissions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;neutron rbac-create &amp;lt;net-uuid|net-name&amp;gt; –type network –target-tenant &amp;lt;tenant-uuid&amp;gt; –action access_as_shared&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Update:
* neutron rbac-update &amp;lt;rbac-uuid&amp;gt; –target-tenant &amp;lt;other-tenant-uuid&amp;gt;&lt;/p&gt;
&lt;p&gt;List entries:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;neutron rbac-list&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Show entry:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;neutron rbac-show &amp;lt;object-id&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Deleting:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;neutron rbac-delete &amp;lt;rbac-uuid&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;List available actions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;neutron rbac-list-actions &amp;lt;object-type&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There should be no impact to the regular global shared network workflow. The
new API usage will only be required for fine-grained entries.&lt;/p&gt;
&lt;p&gt;From the perspective of a tenant that has a network shared to it, the network
will show up as ‘shared’ just like a globally shared network would.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Checking the shared attribute for the network will now involve a join to
another table. The impact to network listing will be quantified during code
review.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change shouldn’t impact the community in any major way. It will
introduce a new method of restricted sharing, but there isn’t anything major
that should hit out-of-tree drivers/plugins.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;kevinbenton
sballe&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add the DB model, REST API changes, UTs to the Neutron server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adjust existing ‘shared’ attribute to use rbac and add migration script&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the client to CRUD the RBACs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add API tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;N/A. API tests should be sufficient&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;No functional test is likely necessary for this work. All of this is
at the API layer without impacting the dataplane.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Excercise basic CRUD of RBAC entries&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure networks are revealed and hidden as RBAC entries are changed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete port of another tenant from tenant with shared network&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;The workflow for adding RBAC entries will need to be added.
The workflow for a normal shared network should be the same
so existing docs shouldn’t need to be changed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;The new sharing API will need to be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Here is a dragon breathing fire:&lt;/p&gt;
&lt;p&gt;__(‘)&amp;lt;~~~
____)&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 29 Jun 2016 00:00:00 </pubDate></item><item><title>QoS minimum egress bandwidth support</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/newton/ml2-qos-minimum-egress-bw-support.html</link><description>

&lt;p&gt;RFE: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1560963"&gt;https://bugs.launchpad.net/neutron/+bug/1560963&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The current &lt;a class="reference external" href="https://review.openstack.org/#/c/88599/"&gt;QoS API&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id1" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; does not provide functionality to define an assured
minimum egress bandwidth per port. This proposal talks about enhancing the
existing QoS API’s by adding assured minimum egress bandwidth.&lt;/p&gt;
&lt;p&gt;This functionality is currently supported in:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Open vSwitch: minimum bandwidth assurance is supported, although the traffic
shaping applies only to egress traffic, from the switch point of view. This
egress traffic (from the switch point of view) should not be mistaken with
the egress traffic from the tenant, which is the goal of this new feature.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Linux Bridge: using traffic control &lt;a class="reference external" href="http://linux.die.net/man/8/tc-htb"&gt;HTB&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id3" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; implementation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SR-IOV: it will depends on the NIC driver and the &lt;a class="reference external" href="http://manpages.ubuntu.com/manpages/xenial/en/man8/ip-link.8.html"&gt;ip-link&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id6" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; version, which
needs to have “min_tx_rate” option; this option was merged in version 3.16.0.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposed change is an update to the QoS API and the drivers mentioned
(Open vSwitch, Linux Bridge and SR-IOV) to support minimum egress bandwidth
assurance. The value of the bandwidth will be stored as an integer value, with
valid values greater than zero. The unit is kbps, the same unit used in
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;QosBandwidthLimitRule&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The scope of this feature is to enable the API access to the egress minimum
bandwidth value and to enable this feature in the previous commented drivers.
This feature doesn’t provide a method to inform about the backend capacity or
to check the bandwidth availability. These limitations will be documented in
user and developer guides.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;The model follows the way that the QoS Bandwidth Limiting functionality applies
to QoS policies by adding a QosMinimumBandwidthRule table.&lt;/p&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;QosMinimumBandwidthRule&lt;/span&gt;&lt;/code&gt; model would look like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+--------------+-------+----------+--------+-----------------+------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Attribute&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Access&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Default&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Validation&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Conversion&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+==============+=======+==========+========+=================+============+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;RO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;all&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;generat_&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;identity&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ed&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------+-------+----------+--------+-----------------+------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;qos_policy_id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;RO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;all&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;QoSPolicy&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;reference&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------+-------+----------+--------+-----------------+------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;min_kbps&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;integer&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;RW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tenant&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;negative&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Minimum&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;max_kbps&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;bandwidth&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------+-------+----------+--------+-----------------+------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;direction&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;enum&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;RW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tenant&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="s1"&gt;'egress'&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="s1"&gt;'egress'&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Traffic&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;direction&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------+-------+----------+--------+-----------------+------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If “max_kbps” is None, the validation check for “min_kbps” will not apply.&lt;/p&gt;
&lt;p&gt;This QoS rule can be used in combination with QoS bandwidth limit rule, defined
in &lt;a class="reference external" href="http://specs.openstack.org/openstack/neutron-specs/specs/liberty/qos-api-extension.html"&gt;Neutron QoS API Models and Extension&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id8" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Both “qos_policy_id” and “direction” will be linked as a unique constraint set,
because the combination of both parameters must be unique.&lt;/p&gt;
&lt;p&gt;This QoS rule will have a “direction” parameter to define the direction of the
traffic. This new feature will implement only egress traffic shaping. “ingress”
traffic direction won’t be allowed for the nonce.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Proposed attribute:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;SUB_RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s1"&gt;'minimum_bandwidth_rules'&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
        &lt;span class="s1"&gt;'parent'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'collection_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'policies'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'member_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'policy'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'parameters'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QOS_RULE_COMMON_FIELDS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'min_kbps'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:non_negative'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;max_kbps&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
              &lt;span class="p"&gt;}),&lt;/span&gt;
            &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'egress'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;common_constants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
                             &lt;span class="n"&gt;EGRESS_DIRECTION&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
              &lt;span class="p"&gt;}),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Sample REST calls:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;policies&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"TypeOne"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"This policy sets a minimum bandwidth for type one users"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"False"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;policies&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;tenant-id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"TypeOne"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"This policy sets a minimum bandwidth for type one users"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"shared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;policy-uuid&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"rule_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RULE_TYPE_MINIMUM_BANDWIDTH&lt;/span&gt;
            &lt;span class="s2"&gt;"min_kbps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"egress"&lt;/span&gt;
        &lt;span class="p"&gt;}]&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;policies&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;minimum_bandwidth_rules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"minimum_bandwidth_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"min_kbps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"egress"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"minimum_bandwidth_rule"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;policy-uuid&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"min_kbps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"egress"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;qos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;policies&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;minimum_bandwidth_rules&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"minimum_bandwidth_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"min_kbps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"egress"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"minimum_bandwidth_rule"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;id&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;policy-uuid&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"min_egress_kbps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"egress"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="command-line-client-impact"&gt;
&lt;h3&gt;Command Line Client Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;qos-minimum-bandwidth-rule-create &amp;lt;policy-id&amp;gt; –min-kbps &amp;lt;value&amp;gt; –direction &amp;lt;value&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;qos-minimum-bandwidth-rule-show &amp;lt;rule-id&amp;gt; &amp;lt;policy-id&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;qos-minimum-bandwidth-rule-list &amp;lt;policy-id&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;qos-minimum-bandwidth-rule-update &amp;lt;rule-id&amp;gt; &amp;lt;policy-id&amp;gt; –min-kbps &amp;lt;value&amp;gt;
–direction &amp;lt;value&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;qos-minimum-bandwidth-rule-delete &amp;lt;rule-id&amp;gt; &amp;lt;policy-id&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Deployers may need to configure the specific QoS driver / ML2 agent extension.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Rodolfo Alonso Hernandez&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Miguel Angel Ajo&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hirofumi Ichihara&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Moshe Levi&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Versioned DB objects for the new rule type&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API changes to allow for minimum egress bandwidth modifications&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client changes to allow minimum egress bandwidth values being set&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;QoS Openflow integration within the L2 agent extension for the Open vSwitch
driver to enable the minimum egress bandwidth support:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Added/modified switch flows to mark the packet processing queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Added/modified QoS rules and processing queues in the integration bridge,
physical bridges and tunnel bridge.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;QoS Traffic Control integration within the L2 agent extension for the Linux
Bridge driver to enable this feature.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;QoS ip-link integration within the L2 agent extension for the SR-IOV driver
to enable this feature. Add a sanity check to detect the version of ip-link
tool; minimum version required is 3.16.0.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="open-vswitch-driver"&gt;
&lt;h4&gt;Open vSwitch driver&lt;/h4&gt;
&lt;p&gt;The current Open vSwitch QoS implementation only shapes egress traffic.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="linux-bridge-driver"&gt;
&lt;h4&gt;Linux Bridge driver&lt;/h4&gt;
&lt;p&gt;The current Linux Bridge QoS implementation using Traffic Control (TC) only
shapes egress traffic (from the interface point of view). To shape ingress
traffic from the interface point of view (egress from the instance), what is
needed in this feature, the following steps are required:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;a class="reference external" href="http://www.linuxfoundation.org/collaborate/workgroups/networking/ifb"&gt;IFB&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id10" id="id11" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Send all ingress traffic to this IFB, mirroring it, using a TC rule. This
traffic will be sent to this IFB as egress traffic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a qdisc and a class in this IFB, with the QoS filter.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also the algorithm used, &lt;a class="reference external" href="http://linux.die.net/man/8/tc-tbf"&gt;TBF&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id12" id="id13" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, must be substituted by &lt;a class="reference external" href="http://linux.die.net/man/8/tc-htb"&gt;HTB&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id3" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, a classful
algorithm that allows to set a “rate” parameter, defined as the “maximum rate
this class and all its children are guaranteed”.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="future-work"&gt;
&lt;h3&gt;Future work&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement a method to report backend capacity to Neutron. Several methods to
enable this feature can be carried out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use an agent to periodically read the capacity of the backends, using
config files, monitoring systems, etc.
The agent state reports could be used for that purpose. The information
could come from system inspection also enabling an option to override the
details in the agent config file.
The bandwidth mapping should be per physical network, and there’s a
peculiarity we must consider: connection to physical networks can happen
by several unbound interfaces (like an SR-IOV card having several PFs
(with it’s separate cables) to the switch. That would effectively give
different connection resources to the same net which are exhausted
separately.
This is the best option.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Insert the backend capacity manually, using a static file during the
deployment process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable an API to manually insert the backend capacity. The API can be used
for testing and development purposes, but this option should be avoided.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inform Nova Scheduler about the total backend capacity and the QoS minimum
egress bandwidth rules, to improve the Scheduler decision. This feature is
being addressed by &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1578989"&gt;[RFE] Strict minimum bandwidth support (egress)&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id14" id="id15" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API-tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Creating minimum egress bandwidth values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updating minimum egress bandwidth values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deleting minimum egress bandwidth values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Listing minimum egress bandwidth values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Showing a minimum egress bandwidth value&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional tests will be used to verify system interactions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Setting minimun egress bandwidth values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updating minimun egress bandwidth values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deleting minimun egress bandwidth values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Listing minimun egress bandwidth values&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="fullstack-tests"&gt;
&lt;h3&gt;Fullstack Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Setting a QoS policy for minimum egress bandwidth on the port of the first
instance from the API, making a query to the backend and check the
correctness of the stored values.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updating QoS policy and checking again the values.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deleting QoS policy and verifying all the values related to the rule are
deleted.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are no benchmark tests.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Existing &lt;a class="reference external" href="https://github.com/openstack/openstack-manuals/blob/master/doc/networking-guide/source/adv-config-qos.rst"&gt;Networking Guide&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id16" id="id17" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; will be updated for this feature.&lt;/p&gt;
&lt;p&gt;Existing &lt;a class="reference external" href="https://github.com/openstack/openstack-manuals/blob/master/doc/cli-reference/source/neutron.rst"&gt;CLI guide&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id18" id="id19" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;9&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; will be updated for this feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Existing &lt;a class="reference external" href="https://github.com/openstack/neutron/blob/master/doc/source/devref/quality_of_service.rst"&gt;QoS devref document&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id20" id="id21" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;10&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; will be updated for this feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-documentation"&gt;
&lt;h3&gt;API Documentation&lt;/h3&gt;
&lt;p&gt;Existing &lt;a class="reference external" href="https://review.openstack.org/#/c/226834/"&gt;QoS API documentation&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id22" id="id23" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;11&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; will be updated for this feature.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id1" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/88599/"&gt;https://review.openstack.org/#/c/88599/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id4"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id5"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://linux.die.net/man/8/tc-htb"&gt;http://linux.die.net/man/8/tc-htb&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://manpages.ubuntu.com/manpages/xenial/en/man8/ip-link.8.html"&gt;http://manpages.ubuntu.com/manpages/xenial/en/man8/ip-link.8.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://specs.openstack.org/openstack/neutron-specs/specs/liberty/qos-api-extension.html"&gt;http://specs.openstack.org/openstack/neutron-specs/specs/liberty/qos-api-extension.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id11"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.linuxfoundation.org/collaborate/workgroups/networking/ifb"&gt;http://www.linuxfoundation.org/collaborate/workgroups/networking/ifb&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id13"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://linux.die.net/man/8/tc-tbf"&gt;http://linux.die.net/man/8/tc-tbf&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id14" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id15"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1578989"&gt;https://bugs.launchpad.net/neutron/+bug/1578989&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id16" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id17"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/openstack-manuals/blob/master/doc/networking-guide/source/adv-config-qos.rst"&gt;https://github.com/openstack/openstack-manuals/blob/master/doc/networking-guide/source/adv-config-qos.rst&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id18" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id19"&gt;9&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/openstack-manuals/blob/master/doc/cli-reference/source/neutron.rst"&gt;https://github.com/openstack/openstack-manuals/blob/master/doc/cli-reference/source/neutron.rst&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id20" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id21"&gt;10&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/master/doc/source/devref/quality_of_service.rst"&gt;https://github.com/openstack/neutron/blob/master/doc/source/devref/quality_of_service.rst&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id22" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id23"&gt;11&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/226834/"&gt;https://review.openstack.org/#/c/226834/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Fri, 13 May 2016 00:00:00 </pubDate></item><item><title>L3 Agent Extension Framework</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/newton/l3-agent-extension.html</link><description>

&lt;p&gt;RFE: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1580239"&gt;https://bugs.launchpad.net/neutron/+bug/1580239&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Neutron advanced services (*aaS) projects sometimes need access to resources
internal to the L3 agent.  For example, FWaaS needs:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The ability to map router_id to router info so we can program iptables to the
correct namespace.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The ability to load the Service Agent - so we have an RPC endpoint in the
context of L3Agent.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Currently, the accepted methodology is inheritance: the L3NATAgent inherits
from the advanced service. Only those extensions whose classes are inherited
from L3NATAgent have access to agent resources like router and namespace data.
This has several drawbacks:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The introduction of a new advanced service requires a patch to the agent code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Similarly, it is not possible to implement vendor-specific agent extensions
without changing the agent code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multiple agents cannot be run simultaneously.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It isn’t possible to arbitrarily enable an advanced services, as it is
hard-coded.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;To address these problems, we will decouple these services from the agent, so
that each *aaS is a separate extension that registers with the extension
manager and provides the extension manager a list of RPC messages it wishes to
consume, and handler functions to process those RPC messages.  The extension
manager will register each RPC message type with neutron’s callback registry as
a consumer and will use the existing RPC callback producer pattern to listen
for notifications about events of interest. When an RPC callback occurs, each
extension that registered to handle that type of RPC message will have its
handler function invoked.  Multiple *aaS services will be able to plug in
simultaneously without interfering with each other.  Vendor-specific
extensions can be written as agent extension drivers.&lt;/p&gt;
&lt;p&gt;This proposal will create the following new objects in the L3 agent:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;L3AgentExtension - This object will define a stable abstract interface for
agent extensions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L3AgentExtensionManager - This object will be a
stevedore.named.NamedExtensionManager, which is how extensions register and
interface into the agent.  There will be only one L3AgentExtensionManager
instantated at runtime; this is a limitation inherent to stevedore’s
NamedExtensionManager, but making the extension manager generalizable to
handle multiple situations is good practice.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This mechanism will be similar to the extension system implemented for the L2
agent in &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/manager.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/manager.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0&lt;/a&gt;
.  To the maximum extent possible, generalizable code will be moved to a common
location so that both the L2 and L3 agent can re-use it.&lt;/p&gt;
&lt;section id="comparable-implementation"&gt;
&lt;h3&gt;Comparable Implementation&lt;/h3&gt;
&lt;p&gt;This implementation is patterned upon the implementation for the QoS agent
extension in the L2 agent and the accompanying L2 notification driver on the
neutron server. This section describes that interaction with pointers to code
(stable/mitaka branch).  Examples of agent specifics are provided in the
context of the neutron-openvswitch-agent.&lt;/p&gt;
&lt;p&gt;The implementation in neutron-server flows thusly:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The QoSPlugin class initializes an instance of the
QosServiceNotificationDriverManager class and passes to it whenever a
QoSPolicy object needs to be created, updated, or deleted.
&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/services/qos/qos_plugin.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n37"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/services/qos/qos_plugin.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n37&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The QosServiceNotificationDriverManager class loads all instances of
configured notification drivers, and then calls appropriate methods in the
RpcQosServiceNotificationDriver class to send update or delete events.
&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/services/qos/notification_drivers/manager.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n30"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/services/qos/notification_drivers/manager.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n30&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When a QosPolicy update or delete event is received by the
RpcQosServiceNotificationDriver, the driver then submits the QosPolicy object
in question to the RPC callbacks registry
(neutron.api.rpc.callbacks.producer.registry).
&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/services/qos/notification_drivers/message_queue.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n40"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/services/qos/notification_drivers/message_queue.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n40&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The neutron-openvswitch-agent implements the flows thusly:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The AgentExtensionsManager class provides a method for agent extensions to be
initialized.
&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/manager.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n37"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/manager.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n37&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The AgentsExtensionManager class is instantiated inside the
init_extension_manager function within the OVSNeutronAgent class, which is the
primary class for the neutron-openvswitch-agent.
&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n397"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n397&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The QosAgentExtension subscribes–by submitting a callback method to the RPC
registry–as an interested party to QoS policy events. This is the mechanism
by which the agent receives notifications of events of interest.
&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/qos.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n203"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/qos.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n203&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The QosAgentExtension class handles incoming QoSPolicy objects.
&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/qos.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n188"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/qos.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n188&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inside the neutron-openvswitch-agent the QosOVSAgentDriver class implements
QoS actions against the resources available to the agent.
&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/plugins/ml2/drivers/openvswitch/agent/extension_drivers/qos_driver.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n26"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/plugins/ml2/drivers/openvswitch/agent/extension_drivers/qos_driver.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n26&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The QosOVSAgentDriver and all other agent extension drivers are children of
the QosAgentDriver metaclass, which defines the stable abstract interface for
the QoS Agent Driver.
&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/qos.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n37"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/qos.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n37&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To notify the the driver of incoming events, QosAgentExtension loads up the
QosAgentDriver
&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/qos.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n196"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/qos.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n196&lt;/a&gt;
and then calls it explicitly
&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/qos.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n255"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/qos.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n255&lt;/a&gt;
&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/qos.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n275"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/qos.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n275&lt;/a&gt;
&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/qos.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n282"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/qos.py?id=4821196f94d333cb4c310601776f9b2319a6ddf0#n282&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The idea to simply use and adapt the existing L2 implementation to handle L3
communications also was considered and rejected.  The QoS notification
mechanism needs to remain specific to port and network updates in order not to
crush the message queue.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="command-line-client-impact"&gt;
&lt;h3&gt;Command Line Client Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;The notifications proposed in this spec will override certain existing
notifications but should not dramatically increase the number of notifications.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Server- and agent-side configuration changes must be made.  For instance, for
FWaaS:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;On the server side, in neutron.conf, ‘firewall’ needs to be added to the
service_plugins list in neutron.conf, as before. Also in neutron.conf, the
needed notification_drivers in the [fwaas] section must be specified
(message_queue is the default).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On the L3 agent side, ‘firewall’ must be added to ‘extension_drivers’ in
l3_agent.ini.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L3 agent variants (i.e. neutron-vpn-agent) could be an alias of the base l3
agent but with a different set of default extension drivers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;This change introduces a standardized interface for developing advanced
services on top of the L3 agent, and thus eases adoption of new L3 advanced
services and facilitates developer experimentation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change expands the stability and standardization of extension hooks into
neutron, making the platform even more friendly to new technologies and
vendors.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;skandasw&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;german-eichberger&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;nate-johnston&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;emspiege&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;margaret-frances&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;y-furukawa-2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;victor-r-howard&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Generalize the extension management framework so that as much as possible
is common between the L2 and L3 agent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement new extension framework in L3 agent leveraging the code made common
in the previous step.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement notification driver in Neutron server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add unit and functional tests for L3 agent extension framework.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add unit and functional tests for notification driver in Neutron server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement proper devstack configuration to enable testing of extensions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement whatever gate changes are required to adopt the new extension
mechanisms.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement an extension that uses this extension management capability
(FWaaS).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change the QoS agent extension in the L2 agent (ML2/OVS and ML2/LB) to also
use the common extension management code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API-tests&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional tests would need to verify that the L3AgentExtensionManager is
loading the L3AgentExtension, as well as testing the communications of the
notification driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="fullstack-tests"&gt;
&lt;h3&gt;Fullstack Tests&lt;/h3&gt;
&lt;p&gt;Fullstack tests would need to exist to enable loading of a dummy extension and
then ensuring that the dummy extension receives RPC calls properly when issued
by Neutron server.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Existing user documentation describing services that make use of the L3 agent
facility, for example the &lt;cite&gt;_Admin Guide’s “Introduction to Networking” section
&amp;lt;http://docs.openstack.org/admin-guide/networking_introduction.html&amp;gt;_&lt;/cite&gt; would
need to be updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;New developer documentation describing the L3 agent extension mechanism would
need to be created.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-documentation"&gt;
&lt;h3&gt;API Documentation&lt;/h3&gt;
&lt;p&gt;Documentation of the method to discover what extensions are active would need
to be created.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Prior art: &lt;a class="reference external" href="https://review.openstack.org/#/c/91532/11/specs/juno/l3-agent-consolidation.rst"&gt;https://review.openstack.org/#/c/91532/11/specs/juno/l3-agent-consolidation.rst&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 12 May 2016 00:00:00 </pubDate></item><item><title>Flavors for L3 Service Plugin</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/newton/multi-l3-backends.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/multi-l3-backends"&gt;https://blueprints.launchpad.net/neutron/+spec/multi-l3-backends&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint covers the introduction of the flavor framework into
the in-tree L3 service plugin. By adding support for flavors, operators
will be able to run multiple L3 drivers in the same deployment.&lt;/p&gt;
&lt;p&gt;RFE: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1461133"&gt;https://bugs.launchpad.net/neutron/+bug/1461133&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The in-tree L3 service plugin only has support for the Neutron software
routers (legacy/ha/dvr/ha+dvr). If an operator wants to use another
type of router, the service plugin must be changed which will preclude
the use of the reference plugin routers. This current model fails to
address any use cases where a specific routing backend should be used
for only a subset of all of the logical routers in a Neutron deployment.&lt;/p&gt;
&lt;p&gt;More use cases can be found in the following etherpad:
&lt;a class="reference external" href="https://etherpad.openstack.org/p/neutron-modular-l3-router-plugin-use-cases"&gt;https://etherpad.openstack.org/p/neutron-modular-l3-router-plugin-use-cases&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Add flavor support to the in-tree L3 service plugin so requests can be
dispatched to different drivers depending on the flavor associated with
a given router. This will have no impact on other existing L3 service
plugins that exist outside of Neutron.&lt;/p&gt;
&lt;p&gt;block diagram:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+---------------------------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;Neutron&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt;                                              &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                                               &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+----------------------------------------------------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;L3&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="n"&gt;plugin&lt;/span&gt;                                 &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;                                                          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+------------------------------------------------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;                             &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+------------------------------------------------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;                                                          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+-----------+&lt;/span&gt;  &lt;span class="o"&gt;+----+&lt;/span&gt;  &lt;span class="o"&gt;+---+&lt;/span&gt;  &lt;span class="o"&gt;+------+&lt;/span&gt;  &lt;span class="o"&gt;+----------+&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;single_node&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dvr&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ha&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ha&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;dvr&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;vendor&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+--+--------+&lt;/span&gt;  &lt;span class="o"&gt;++---+&lt;/span&gt;  &lt;span class="o"&gt;++--+&lt;/span&gt;  &lt;span class="o"&gt;++-----+&lt;/span&gt;  &lt;span class="o"&gt;+----------+&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--+----|------------|-------|------|---------|---------------+-+&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;RPC&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;vendor&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;specific&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;communication&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="n"&gt;V&lt;/span&gt;
        &lt;span class="n"&gt;V&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;+------------------+&lt;/span&gt;
    &lt;span class="o"&gt;+---------+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Proprietron&lt;/span&gt; &lt;span class="mi"&gt;9000&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;l3&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;|&amp;lt;-----+-------+------+&lt;/span&gt;      &lt;span class="o"&gt;+------------------+&lt;/span&gt;
    &lt;span class="o"&gt;+---------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Within the flavor framework there are flavors and service providers. Flavors
are user-facing via the flavors API and they allow users to choose the type
of router they would like (e.g. ‘slow and cheap’). Each flavor is associated
to one or more service profiles. These service profiles define a driver and
some metadata to pass to that driver when it is used.&lt;/p&gt;
&lt;p&gt;When a user creates a router with a specific flavor the flavor framework will
look up the service profiles for that flavor and create the router using one
of the associated drivers. Once a driver is selected for a router, the
router/driver association is stored in the DB so any future operations on the
router can lookup the driver without going through the flavor framework.&lt;/p&gt;
&lt;p&gt;If a user does not choose a flavor, their router will have a NULL flavor. The
chosen driver will then depend on the operator configured service providers, or
in the backward compat case, it will be determined based on the HA and distributed
configuration flags.&lt;/p&gt;
&lt;p&gt;Currently, the flavor framework only supports one service profile
per flavor because it lacks the logic to schedule between profiles [1]
So initially we will only support one service profile per flavor but this
will not prevent future support for scheduling among multiple providers.&lt;/p&gt;
&lt;p&gt;The scheduling among multiple providers is not be confused with router
scheduling: the one referenced in the flavors framework is actually used
to determine which service provider to use for a given flavor if it has
multiple service profiles associated with it. Router scheduling is used
in agent-based implementations of L3 where multiple nodes can host the
routing function and thus the server needs to determine which one to
choose based on a specified policy (e.g. random vs load-based policy).&lt;/p&gt;
&lt;p&gt;For the sake of this effort, routing scheduling is to be considered
implementation specific and left to the driver. In other words, the
L3 plugin should be made unaware of routing scheduling issues as a
driver may or may not need to schedule the routing function to a node
depending on how the L3 function is actually implemented.&lt;/p&gt;
&lt;p&gt;This means that it is within the scope of this blueprint to move the
scheduling implementation details within the default drivers and leave
other drivers in charge of scheduling if they need it.&lt;/p&gt;
&lt;section id="responsibility-of-db-operations"&gt;
&lt;h3&gt;Responsibility of DB operations&lt;/h3&gt;
&lt;p&gt;The L3 service plugin will remain responsible for the CRUD operations on
the router DB objects. This will ensure consistency across common fields
between different flavors/drivers. If a driver needs to perform validation
on input before the record is created in the DB, it can subscribe a
validation callback to the PRECOMMIT events for the router.
Additionally, it is the responsibility of the driver to adjust its own records
based on the PRECOMMIT events if the driver requires storing extra information
about the router.&lt;/p&gt;
&lt;p&gt;Each driver may potentially require distributed coordination in order to
dispatch and implement router operations, and as such transactionality of
these operations is left as a driver specific issue. This aspect may be
revised in the future according to findings/experiments developed in the
context of [3]&lt;/p&gt;
&lt;/section&gt;
&lt;section id="comparison-to-ml2"&gt;
&lt;h3&gt;Comparison to ML2&lt;/h3&gt;
&lt;p&gt;This differs from ML2 in an important aspect. All L3 drivers will not
be called for each operation. Only a single driver will be responsible
for all operations regarding a given router. The driver that is called
is determined by the driver associated to the router when it is created.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="associating-a-router-to-a-driver"&gt;
&lt;h3&gt;Associating a Router to a Driver&lt;/h3&gt;
&lt;p&gt;This association is performed one of two ways: either via an explicit
flavor request from the user, or via the distributed/ha attributes and
distributed/ha configuration.&lt;/p&gt;
&lt;p&gt;The driver manager will load up four default drivers to represent the
single node, ha, distributed, and HA+distributed router types. The driver
manager will then select the appropriate one in the absense of a flavor
request from the user. In other words, the manager chooses a driver at
creation time based on the user selected flavor, or it will fall back
on HA/DVR attributes, if presented. If everything is ommitted, the
API behavior will remain unchanged and the centralized software router
is created. In other words if a custom driver is loaded up next to the
default providers, a user must specify the flavor in order to select
the requested behavior.&lt;/p&gt;
&lt;p&gt;In the event a user requests flags incompatible with the flavor
(e.g. neutron router-create –flavor-id=&amp;lt;ha-id&amp;gt; –distributed=True),
an error will be returned (e.g. invalid input). This can be potentially
solved either client side or server side; however the server side is
to be preferred as it makes the behavior consistent for API users too.&lt;/p&gt;
&lt;p&gt;Operators will be able to override the default drivers by explicitly
defining other service_providers in their configuration.&lt;/p&gt;
&lt;p&gt;It is up to the operator if he/she wants to actually expose any of the
drivers as flavors to the end user to pick from. The flavor_id associated
with a router is nullable, so an operator can maintain backwards compatiblilty
with the current model by not defining any flavors
(a.k.a ‘a tasteless deployment’).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;A flavor_id will be added to the Router table with a foreign key constraint to
the flavors table.[2] It will be nullable to preserve compatibility with the
current behavior.&lt;/p&gt;
&lt;p&gt;No other modifications to the existing tables are required since the service
type framework already exists and allows a driver to be associated with
a resource_id.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;All router objects will now have a nullable ‘flavor_id’ attribute
that indicates the router’s flavor. This attribute can also be used
in create/update calls to request a specific flavor. From an API
extension standpoint, the proposed framework will not include any
capability to allow drivers to bring their own extensions to
the L3 models, not now and not in the future. In other words, there
will not be a supported programmatic API for extension pluggability.
Having said that, the existing mechanisms to plug into the Neutron
frameworks can still be exploited as they are available at the
time of the driver development.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rpc-api-impact"&gt;
&lt;h3&gt;RPC API Impact&lt;/h3&gt;
&lt;p&gt;The L3 agent based solutions rely on a crucial RPC that allows agents
to sync their state with the Server. This API (sync_state) is heavily
specialized across the hierarchy l3-&amp;gt;dvr-&amp;gt;ha-&amp;gt;ha+dvr. Resolving the
mess is a long term objective of this effort, however, for now the
default software drivers will share this RPC detail and therefore will
continue to rely on the existing behavior of the sync_state operation.&lt;/p&gt;
&lt;p&gt;As soon as the first iteration of the framework is complete, strategies
to address this aspect will be explored, so that each driver that needs
to share this RPC call can do so by means of composition rather than
inheritance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="backward-compatibility"&gt;
&lt;h3&gt;Backward compatibility&lt;/h3&gt;
&lt;p&gt;Flavors and service providers are defined by operators. However, we want
the L3 reference plugin to continue to work without action by the operator
when they upgrade. To that effect, the current L3 plugin driver will
automatically register the single_node, ha, dvr, and dvr+ha drivers as
service providers so the driver manager can work the same as the current
system.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;add flavor framework support into the existing L3 plugin&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create separate drivers for single_node, HA, DVR, and HA+DVR routers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;decompose the giant mixin containing logic for all types in the main plugin
and move type-specific logic into each driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;add API tests to exercise flavors&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/33eec87d7822c0915bd45f2c9d2de0b6dc455771/neutron/db/flavors_db.py#L263-L273"&gt;https://github.com/openstack/neutron/blob/33eec87d7822c0915bd45f2c9d2de0b6dc455771/neutron/db/flavors_db.py#L263-L273&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/neutron-specs/specs/liberty/neutron-flavor-framework.html"&gt;https://specs.openstack.org/openstack/neutron-specs/specs/liberty/neutron-flavor-framework.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1552680"&gt;https://bugs.launchpad.net/neutron/+bug/1552680&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description><pubDate>Sat, 30 Apr 2016 00:00:00 </pubDate></item><item><title>Kill neutron-LBaaS, aka LBaaS project spinout</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/newton/kill-neutron-lbaas.html</link><description>

&lt;p&gt;The Octavia project has, as part of creating the new LBaaS reference
implementation, also implemented the LBaaS API as a standard pecan/wsgi
openstack endpoint.&lt;/p&gt;
&lt;p&gt;The Octavia LBaaS API would be identical and compatible with the Neutron
LBaaS v2 API, excepting the /lbaas root url token being missing.&lt;/p&gt;
&lt;p&gt;End users of the existing neutron API endpoint will see no differences
for two cycles, which means potential removal in P or Q, depending on when
this work lands. Note that if the shim is low-maintenance enough, it may
live for even longer; that will be at the discretion of the neutron PTL
and core team.&lt;/p&gt;
&lt;p&gt;This spec describes the process for removing LBaaS as a neutron extension,
and making it a standalone project of its own.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Octavia provides a virtually identical API and plugin mechanism that
neutron-lbaas provides without the tight coupling, which calls into question
why we are maintaining both, now that lbaasv1 is past deprecation.
The main goals of this spinout will be simplifying the administration
and implementation of both, while providing as seamless an experience
as possible to operators and end users.&lt;/p&gt;
&lt;p&gt;There are several reasons for spinning out the LBaaS project:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Having your service stuffed into the guts of a neutron-server, while
your code is in a separate repo, has been a fairly brittle proposition.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Refactors to core neutron have a chance of breaking LBaaS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Co-gate adds to instability of gate for both projects, and can be removed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron extensions get in the way of microversioning, and making
that migration a mess.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We would no longer be double-testing nearly the same functionality,
and consuming more infra and testing resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The active teams for LBaaS and neutron have virtually no overlap,
so the added overhead of administering both is providing no benefit
to neutron, and slowing down LBaaS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Octavia has its own REST API, so why maintain two, if we can make them
compatible?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The reasons against:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;There is a certain amount of busywork required to finish getting ready
to be a completely separate project, listed in proposed changes below,
but the payoff in two simpler projects would seem worth it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is some value in having all the “networking” APIs under one umbrella,
though there is precedent for higher-level services being outside (DNSaaS).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This list of changes will be split into “phase one” and “phase two”. Phase
one is the minimum list of changes necessary for a governance change and
to stop maintaining neutron-lbaas as it is today, and phase two are logical
next steps needed for any standalone openstack project.&lt;/p&gt;
&lt;p&gt;Octavia is an API server, a service VM framework for LBaaS, and the
reference implementation for LBaaS. Currently only service VM centric
drivers are supported&lt;/p&gt;
&lt;p&gt;Phase one:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In Octavia, an interface needs to be added so that non-service VM
drivers can be used behind the API server (e.g. hardware appliances or
existing lbaas drivers.) This driver
interface should accept current neutron LBaaS v2 drivers directly,
provided that those drivers limit themselves to passed in objects and
public lbaas plugin interfaces. The current neutron lbaasv2 drivers
will be moved into the octavia repo, though any driver reaching into
neutron’s guts is likely to break. So, don’t reach into guts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify the neutron-LBaaS API extension to be a direct proxy
pass-through to the octavia api controller.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Notify vendors to verify their drivers work with the Octavia API
controller, and to move their third-party CIs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Notify other projects using LBaaS, notably Heat.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove neutron-LBaaS/neutron co-gate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify minimum docs coverage from a user and API standpoint.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apply for governance change from neutron stadium to the big tent.
This includes moving neutron-lbaas into octavia, unless the neutron
/lbaas proxy is a pecan route in neutron proper, and then neutron-lbaas
can simply be removed/sent to the attic.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Phase two:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create client library, and/or direct support in openstackclient/sdk.
What happens to the existing ‘openstack loadbalancer’? Is it just a neutron
proxy for a few releases? Long-term, it will be an OSC plugin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create/verify/move API/install guide/user docs that are already written
for neutron-lbaas.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;During this transition, and for sometime after, the neutron /lbaas proxy
will make this transparent to users.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Spec that outlines specific changes needed in Octavia for this to happen:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/310667/"&gt;https://review.openstack.org/#/c/310667/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Proposed neutron-lbaas proxy shim layer:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/328053/"&gt;https://review.openstack.org/#/c/328053/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Brandon’s work on making an lbaasv2 driver layer directly in Octavia:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/311586/"&gt;https://review.openstack.org/#/c/311586/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;WIP governance patch, which will remain WIP until phase one is nearing
completion:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/313056/"&gt;https://review.openstack.org/#/c/313056/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Octavia’s ‘api_handler’ interface, which is similar to the current lbaasv2
driver interface (see 311586 for work to make this seamless with current
drivers):&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/octavia/blob/master/octavia/api/v1/handlers/abstract_handler.py"&gt;https://github.com/openstack/octavia/blob/master/octavia/api/v1/handlers/abstract_handler.py&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 28 Apr 2016 00:00:00 </pubDate></item><item><title>VLAN aware VMs</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/newton/vlan-aware-vms.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/vlan-aware-vms"&gt;https://blueprints.launchpad.net/neutron/+spec/vlan-aware-vms&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;This blueprint proposes how to incorporate VLAN aware VMs into
OpenStack. In this document a VLAN aware VM is a VM that sends and receives
VLAN tagged frames over its vNIC. The main point of that is to overcome the
limitations of the current one vNIC per network model. A VLAN (or other
encapsulation) aware VM can differentiate between traffic of many networks by
different encapsulation types and IDs, instead of using many vNICs. This
approach scales to higher number of networks and enables dynamic handling of
network attachments (without hotplugging vNICs).&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently VLANs in VMs are not integrated with Neutron.  There are various use
cases where it would be useful to allow a VM to be attached to multiple Neutron
networks using VLANs as a local encapsulation to differentiate the traffic for
each network as it goes in/out of a single VIF.&lt;/p&gt;
&lt;p&gt;Use cases:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Some applications have requirements to connect to many (say, hundreds) of
Neutron networks.  It is more practical to use a single or other small number
of VIFs and VLANs to differentiate traffic for each network than to have
hundreds of VIFs per VM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cloud workloads are often very dynamic.  It may be more efficient and/or less
complex to add/remove VLANs than to hotplug interfaces in a VM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A VM could be moved from one network to another without detaching the VIF
from the VM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A VM may be running many containers. Each container may have requirements to
be connected to different Neutron networks. Assigning a VLAN (or other
encapsulation) id for each container is more efficient and scalable than
requiring a vNIC per container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are legacy applications that expect to use VLANs as a way to connect to
multiple networks.  Neutron should provide a way to expose that model to the
VM decoupled from how the network is actually implemented.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The proposal may look related in some sense to the VLAN-transparent
approach (bp/nfv-vlan-trunks), but differs in that it doesn’t provide a
way to send opaque data through the links, but instead be aware of the
encapsulating, provided by the VM (or an appliance inside a VM).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposal keeps the port resource unchanged.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ neutron port-create NETWORK
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The new API extension looks like this:&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;One new trunk resource with member_actions for subport operations:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;One trunk resource&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subports encoded in an attribute of the trunk, added and removed by
member_actions&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The proposal is to add an API extension to turn already existing ports
into trunk and subports.  The best way to think about this is that
Neutron needs a method to describe a logical topology such that you have a
regular VIF port (the parent) and that a parent may also have child ports.
These child ports are used to connect the VIF port to further networks.
Both the parent and child ports have all of the attributes that a port
has today (however some subport attributes must behave differently,
eg. binding:host_id) and can be created on any Neutron network.
All needed information beyond legacy port attributes is contained in
newly introduced resource(s) referring legacy ports.&lt;/p&gt;
&lt;p&gt;The first part of the API extension is the logical topology portion.
First, we include a method to indicate that a port may have child
ports.  This isn’t strictly necessary, but is included for convenience.
It allows Neutron to go ahead and reject the port creation if subports
aren’t supported by the backend.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;# trunk-create may refer to 0, 1 or more subport(s).
$ neutron trunk-create --port-id PORT \
                      [--subport PORT[,SEGMENTATION-TYPE,SEGMENTATION-ID]] \
                      [--subport ...]
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;All ports referred must exist.&lt;/p&gt;
&lt;p&gt;Note that if a given plugin does not implement support for
bp/vlan-aware-vms, this request will be rejected.&lt;/p&gt;
&lt;p&gt;If the backend does not implement the extension any trunk operation will fail
(with 404). If a plugin does implement the extension, trunk operations may
return a conflict error if the port status is not compatible with the request.&lt;/p&gt;
&lt;p&gt;In addition to the logical topology piece, we need to define the type
of encapsulation (segmentation) used between the hypervisor and VM for
targeting packets to a logical subport, as well as for determining the
source logical port for a packet arriving from the VM. The encapsulation
here is local, used between the VM and hypervisor only.  It has nothing
to do with how the Neutron network the port is attached to is implemented.
SEGMENTATION-TYPE is an enum of strings, currently having one valid value
‘vlan’. SEGMENTATION-ID is an unsigned integer.  SEGMENTATION-TYPE and
SEGMENTATION-ID are optional in both trunk-create and trunk-subport-add
in the generic case, allowing neutron server to choose the type and id
if needed. On the other hand backends are allowed to reject requests
with unspecified segmentation details and make the user supply them.
Further segmentation types may be introduced by later specs.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;# trunk-add-subport adds 1 or more subport(s)
$ neutron trunk-subport-add TRUNK \
                            PORT[,SEGMENTATION-TYPE,SEGMENTATION-ID] \
                           [PORT,...]
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;All ports referred must exist.&lt;/p&gt;
&lt;p&gt;The CLI has the following new commands:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;trunk-create&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;trunk-delete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;trunk-list&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;trunk-show [should not print subports]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;trunk-subport-add&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;trunk-subport-delete&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;trunk-subport-list&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Importantly, after creating trunks and maybe subports, VMs are still booted
with a reference to plain old ports:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ nova boot --nic port-id=...
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Nova need not know about trunks and subports.&lt;/p&gt;
&lt;p&gt;Example logical model:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;           &lt;span class="o"&gt;+-----------+&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+-------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+------+&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;port1&lt;/span&gt; &lt;span class="o"&gt;+-----+&lt;/span&gt; &lt;span class="n"&gt;net1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+-------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+------+&lt;/span&gt;
&lt;span class="o"&gt;+-----+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+-------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;vm0&lt;/span&gt; &lt;span class="o"&gt;+------+&lt;/span&gt; &lt;span class="n"&gt;port0&lt;/span&gt; &lt;span class="o"&gt;+-----+&lt;/span&gt; &lt;span class="n"&gt;net0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+-------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+------+&lt;/span&gt;
&lt;span class="o"&gt;+-----+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+-------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+------+&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;port2&lt;/span&gt; &lt;span class="o"&gt;+-----+&lt;/span&gt; &lt;span class="n"&gt;net2&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+-------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+------+&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
           &lt;span class="o"&gt;+-----+-----+&lt;/span&gt;
                 &lt;span class="o"&gt;^&lt;/span&gt;
                 &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;+----------------+--------------+&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;                               &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Ports&lt;/span&gt; &lt;span class="n"&gt;combined&lt;/span&gt; &lt;span class="n"&gt;into&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="n"&gt;VIF&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="n"&gt;turning&lt;/span&gt; &lt;span class="n"&gt;port0&lt;/span&gt; &lt;span class="n"&gt;into&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;trunk&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="n"&gt;ports&lt;/span&gt; &lt;span class="n"&gt;into&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;subports&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;trunk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;                               &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;+-------------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The traffic of port0 is untagged in vm0.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The traffic of port1 is encapsulated, for example as vlan id 100.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The traffic of port2 is encapsulated, for example as vlan id 200.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the above example, a VM connects to 3 Neutron networks.  port0 is
a regular port that handles untagged traffic.  port0 has two subports,
each using VLAN encapsulation with a different VLAN ID.  Packets targeted
at a subport will be tagged with the appropriate VLAN ID before being
sent to the VIF.  Packets received on the VIF tagged with a VLAN ID
associated with a subport will be treated as if the logical source was
that subport and the packet will be sent to the Neutron network that
subport is attached to.&lt;/p&gt;
&lt;p&gt;Subports have independent, arbitrary MAC addresses just like any other Neutron
port.  If the application requires having subports use the same MAC address as
their parent, the port create API supports specifying the MAC address, so it
can be specified to match the parent’s MAC address.  A parent and a subport
having the same MAC address are not allowed to be on the same net.&lt;/p&gt;
&lt;p&gt;Nested subports are not supported.&lt;/p&gt;
&lt;section id="constraints"&gt;
&lt;h3&gt;Constraints&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A top level port that may have child ports added must be marked by creating
a trunk referring to the port in its &lt;cite&gt;port_id&lt;/cite&gt; attribute.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Every subport of a given parent should have unique (segmentation_type,
segmentation_id) among its siblings.  Otherwise, it would not be possible
to properly differentiate the source and destination logical port.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The parent port handles “untagged” traffic.  The parent will receive
all the packets that do not match a subport, which is no
different than how a regular port already behaves today.  This also
means that every VM has a port for untagged traffic.  It doesn’t
necessarily have to be used though and could be attached to a dummy
Neutron network if desired.  You could also have a security group
set on the parent port to drop all incoming and outgoing traffic.
A future enhancement could include the ability to create a Neutron
port not yet attached to a network, though it’s unclear how valuable
that actually is.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A port with a parent logically inherits its binding:host_id from its parent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An attempt to update binding:host_id of a subport (by booting a Nova VM with
a subport UUID, for example) must result in an error.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A normal user can only connect subports to its own parent ports. Admin
can connect subports to parent ports of different owners.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Until OVS supports QinQ, an OVS based Neutron backend cannot support having a
subport attached to a “vlan_transparent” network.  That would require the
abilty to transport VLAN tagged traffic over the VLAN tagged subport interface
(nested VLANs), which is not yet possible.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following deletion constraints exist:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Deletion of a trunk automatically deletes all of its subports.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deletion of a (child) port referred by a subport is forbidden. The subport
must be deleted first.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deletion of a (parent) port referred by a trunk is forbidden. The trunk
must be deleted first.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="nova-changes"&gt;
&lt;h3&gt;Nova changes&lt;/h3&gt;
&lt;p&gt;The Neutron OVS agent uses OVS in such a way that it will likely need
to create a new OVS bridge per top level parent port.  That requires
an enhancement to the existing OVS and vhost-user VIF types in Nova to
allow Neutron to tell Nova the name of the bridge to use for the port.
Currently, Nova only supports a single bridge name provided by the Nova
configuration file.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;For alternatives please see the history of the spec, including:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;v1: &lt;a class="reference external" href="https://review.openstack.org/#q,I015762abe197b91916374143410b1f182908909e,n,z"&gt;https://review.openstack.org/#q,I015762abe197b91916374143410b1f182908909e,n,z&lt;/a&gt;
patch sets 1 through 10&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;v2: &lt;a class="reference external" href="https://review.openstack.org/#q,I015762abe197b91916374143410b1f182908909e,n,z"&gt;https://review.openstack.org/#q,I015762abe197b91916374143410b1f182908909e,n,z&lt;/a&gt;
patch sets 11 through 21&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;v3: &lt;a class="reference external" href="https://review.openstack.org/#q,I8563e54cc984b60f2be2eb7cc2e3c6fc60e6de20,n,z"&gt;https://review.openstack.org/#q,I8563e54cc984b60f2be2eb7cc2e3c6fc60e6de20,n,z&lt;/a&gt;
patch sets 1 through 5&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;v4: &lt;a class="reference external" href="https://review.openstack.org/#q,I8563e54cc984b60f2be2eb7cc2e3c6fc60e6de20,n,z"&gt;https://review.openstack.org/#q,I8563e54cc984b60f2be2eb7cc2e3c6fc60e6de20,n,z&lt;/a&gt;
patch sets 6 and later (the current)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;Neutron port: no changes.&lt;/p&gt;
&lt;p&gt;Neutron DB table: trunks&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;id: integer primary key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tenant_id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;port_id: foreign key to ports.id&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Neutron DB table: subports&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;port_id: foreign key to ports.id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;trunk_id: foreign key to trunks.id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;segmentation_type&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;segmentation_id&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Neutron DB constraints:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;(segmentation_type, segmentation_id, trunk_id) must be unique in the
subports table&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ports referred by trunks.port_id must not be referred by subports.port_id
and vice versa.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;trunk resource:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tenant_id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;port_id&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;trunks&lt;/span&gt;
     &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;trunks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;TRUNK&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;add_subports&lt;/span&gt;
&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;trunks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;TRUNK&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;delete_subports&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'subports'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
         &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s1"&gt;'port_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PORT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s1"&gt;'segmentation_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SEGMENTATION_TYPE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s1"&gt;'segmentation_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SEGMENTATION_ID&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="o"&gt;...&lt;/span&gt;
         &lt;span class="p"&gt;]}}&lt;/span&gt;
&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;trunks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;TRUNK&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;subports&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;Only admin can create and attach subports for different tenants.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;Tenants should be aware that OpenStack does nothing to enable VMs
to handle the tagged traffic, but just provides tagged packets. It
is totally up to the user to set VMs up properly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The performance of existing functionality should be unaffected.  The data path
for normal ports is unchanged.&lt;/p&gt;
&lt;p&gt;In some cases, this change may improve performance.  Without this change,
connecting a VM to many Neutron networks required a VIF per network.  With this
change, you could connect to 1000 Neutron networks with very little overhead vs.
having to attach 1000 virtual interfaces to your VM before.  The tradeoff is
that some additional burden is shifted into the VM to deal with that
segmentation on a single interface.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.  Both parent ports and subports have all of the same attributes as Neutron
ports do today, including IPv6 addresses if desired.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New neutron resources are to be used&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Requires modifications to Neutron plugins to support this model&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Requires development of new tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Kevin Benton&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Peter V. Saveliev&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Russell Bryant&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bence Romsics&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;API extension and DB schema updates&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests for API+DB changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests for creating port topology&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest scenario test(s) for doing functional validation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron Plugin support.
* networking-ovn (OVN supports this model already)
* ml2+ovs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expose subport information in nova metadata service (likely will require a new
spec)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;The change needed for the existing OVS VIF type has &lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/neutron-ovs-bridge-name"&gt;its own blueprint&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Tempest and functional tests will be created.&lt;/p&gt;
&lt;section id="full-stack-and-in-tree-api-tests"&gt;
&lt;h3&gt;Full-stack and in-tree API tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create parent ports&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create subports&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bind parent ports&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete subports&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete parent ports&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Tests to be implemented:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Boot VM with one parent port and no children.
Verify connectivity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Boot VM with one parent port and multiple subports.
Verify connectivity to each logical port.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Boot VM with multiple parent ports and subports and verify connectivity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add subport to running VM with a parent port.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove subport from running VM with parent port.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete VM with parent port including subports.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Tests to be implemented:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Check that subport only can be connected to a parent port.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check that an invalid segmentation_type is rejected&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check that an invalid segmentation_id is rejected&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The use of parent ports and subports should be documented as a way to create a
logical multi-port topology using a single VIF on a VM.&lt;/p&gt;
&lt;p&gt;Possible scenarios for use cases should be provided with
CLI examples.&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Update networking API reference.
Update admin guide.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;The parent port resource description, subports behaviour, API reference.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/neutron-ovs-bridge-name"&gt;OVS VIF type: pass bridge name from neutron to nova&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subport details may be exposed to VMs via the Nova metadata service in a
later spec like this: &lt;a class="reference external" href="https://review.openstack.org/#q,I16845bd36878bbd9d7a877dc556b2650bc6f0fad,n,z"&gt;Virtual guest device role tagging&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/nfv-vlan-trunks"&gt;nfv-vlan-trunks&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 20 Apr 2016 00:00:00 </pubDate></item><item><title>Firewall as a Service API 2.0</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/newton/fwaas-api-2.0.html</link><description>

&lt;p&gt;&lt;strong&gt;Launchpad blueprint:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/fwaas-api-2.0"&gt;https://blueprints.launchpad.net/neutron/+spec/fwaas-api-2.0&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This spec introduces a few enhancements to Firewall as a Service (FWaaS)
API including making it more granular by giving the users the ability to
apply the firewall rules at the port level rather than at the router
level. Support is extended to various types of Neutron ports, including
VM ports and SFC ports as well as router ports. It also aims to provide
better grouping mechanisms (firewall groups, address groups and service
groups) and discuss the use of a common classifier in achieving it. While
this spec is proposing the API, the implementation will be carried out in
phases subject to availability of people to do the work. And at the end of
Mitaka - we will have a working reference implementation but, that may
not embody all the enhancements in this spec. The implementation phases
will be tracked by an appropriate RFE referencing this as the parent spec.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The Security Group API extension is a well known API for handling network
traffic. For basic traffic filtering, the Security Group API is well
understood by users, but as cloud infrastructure gains wider acceptance
into the enterprise, the security group API, which was built for public
cloud infrastructure becomes insufficient for the security and network
environments inside the enterprise.&lt;/p&gt;
&lt;p&gt;As such, one-off changes to the Security Group API end up occurring in
each deployment of OpenStack. One solution is to allow deployers of
OpenStack to “extend” an API extension to make it fit in their security
and network environment. Ideally, the Firewall as a Service API is the
API where usecases more advanced than the basic “let any traffic from X
IP into Y port into my group of VMs” should be supported.&lt;/p&gt;
&lt;p&gt;But the existing Firewall as a Service API has been deprecated in Liberty
because it was fairly limited, requiring substantial enhancements to make
it cover all the use cases raised by the community. There are also some
overlapping functionalities between FWaaS API and the SG API which need
to be rationalized.&lt;/p&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;Use Cases:&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a class="reference external" href="https://trello.com/b/TIWf4dBJ/fwaas-usecase-categorization"&gt;https://trello.com/b/TIWf4dBJ/fwaas-usecase-categorization&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;It is proposed to harmonize the FWaaS and Security Group models by
converging the implementation of FWaaS and Security Groups but keeping
a separate API for each of them while relying on a common backend. This
spec proposes an enhanced FWaaS API that incorporates Security Groups
functionality such that the FWaaS API becomes a superset of what is
exposed by the Security Group API.&lt;/p&gt;
&lt;p&gt;Relative to the FWaaS 1.0 API, the FWaaS 2.0 API provides the following
enhancements:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Applies at the granularity of Neutron ports rather than tenant
wide or a set of routers in a tenant.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Applies to various types of Neutron ports, including VM ports and
SFC ports as well as router ports. By applying FWaaS at VM ports,
it will be possible to filter east/west intra-subnet traffic as
well as east/west inter-subnet traffic and north/south traffic.
This will also allow FWaaS to filter east/west traffic when DVR is
used, as opposed to FWaaS 1.0 that only filters north/south
traffic in case of DVR [4], [5].&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allows for different firewall policies with different firewall
rules to be applied to different directions (ingress vs egress).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Introduces the Firewall Group construct for Neutron ports. This
becomes the association point for binding firewall policies and
Neutron ports, as well as a way to specify allowed sources and
destinations in firewall rules. This reduces or eliminates the
need to specify IP addresses for east/west traffic flows in
firewall rules. For example, when Firewall Group A is used as the
source firewall group id in a rule within an ingress policy in
Firewall Group B, we care only about the ports associated with
Firewall Group A. When a packet arrives, it is matched if its
source ip address matches an IP address of one the ports in
Firewall Group A.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adds indirections through address group and service group that
allow groups of addresses and groups of L4 ports to be specified
once and reused in multiple rules and multiple firewall policies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allows multiple firewall group associations for the same Neutron
port. For example, one firewall group applied to a tenant’s web
servers may specify a firewall policy that restricts traffic to
HTTP only (intended for north/south traffic), while another
firewall group applied to all the tenant’s instances may specify a
firewall policy that allows all traffic types between sources and
destinations in that firewall group (east/west traffic).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Relative to the Security Groups API [7], the FWaaS 2.0 API provides the
following enhancements:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Adds an explicit action attribute to rules so that “deny” and
“reject” actions can be specified in addition to the existing
“allow” action. This is particularly important for tenant or
service provider network admins that specify firewall policies
meant to apply to all of a tenant’s or service provider’s
instances, regardless of application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allows filtering based on both source and destination address
prefixes, rather than just the remote (source for ingress traffic,
destination for egress traffic) address prefixes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allows filtering based on both source and destination L4 port
ranges, rather than just destination L4 port range.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By adding indirections through firewall group, address group and
service group, allows for operational separation of responsibilities
between users and experts such as network admins. Experts can define
groups of IP address prefixes in address groups, and define service
groups using protocol and source/destination ports. Users can then
easily define firewall rules that refer to firewall group and
service group, without having to know about IP addresses and L4
ports. For example, a service group named &lt;em&gt;All Web Server Ports&lt;/em&gt;
could be defined with protocol TCP and destination L4 ports 80,
8080, and 443.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adds a “description” attribute to firewall rules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adds an “admin status” attribute to firewall rules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adds a “public” attribute allowing sharing of firewall rules
between different projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Firewall groups reference firewall rules through a firewall
policy. In particular, this allows reuse of sharable firewall
policies that are referenced by multiple firewall groups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the future, it is expected that service groups will support
deep packet inspection, so that traffic can be matched based on an
application ID and L7 fields such as URL strings, instead of or in
addition to L4 port ranges.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;section id="relationship-between-fwaas-and-security-groups"&gt;
&lt;h3&gt;Relationship Between FWaaS and Security Groups&lt;/h3&gt;
&lt;p&gt;FWaaS and Security Groups remain as separate features. The Security Group
API will be retained in addition to the FWaaS 2.0 API for two reasons.&lt;/p&gt;
&lt;p&gt;The first reason to retain the existing Security Group API is for those
users who want to leverage existing functionality in a way that aligns
as closely as possible with non-OpenStack security group definitions.&lt;/p&gt;
&lt;p&gt;The second reason has to do with “defense in depth”, where multiple
layers of data plane access control are defined and applied. With
existing FWaaS 1.0 and Security Groups, the perimeter firewall
functionality is defined in FWaaS and enforced at OpenStack routers,
while application firewall functionality is defined through Security
Groups and enforced at VM ports. Both north/south and inter-subnet
traffic must be allowed by both FWaaS and Security Groups in order to
pass end-to-end from the source to the destination.&lt;/p&gt;
&lt;p&gt;With FWaaS 2.0, it is important to retain “defense in depth” even when
FWaaS is enforced at VM ports. When both FWaaS and Security Groups are
associated with the same Neutron port, a packet must be allowed by both
features, i.e. “deny” wins between FWaaS and Security Groups. This
behavior is adopted to address typical use cases where a tenant network
admin uses FWaaS to specify tenant wide rules that are to be applied
regardless of the application, while an application deployer uses
Security Groups to narrow down allowed traffic to only what is needed
for a specific application.&lt;/p&gt;
&lt;p&gt;For example, a network admin creates a firewall rule that denies port
25 traffic. Even if the application deployer creates a security group
rule that allows port 25 traffic, the port 25 traffic will be denied.&lt;/p&gt;
&lt;p&gt;Note that as with the existing FWaaS 1.0 API and Security Groups, by
default OpenStack policy does not distinguish between different roles
within a project. Default OpenStack policy will not prevent different
users from the same project (e.g. application deployers vs tenant
network admins) from accessing the FWaaS API. This may be investigated
in future phases.&lt;/p&gt;
&lt;p&gt;In future phases, the FWaaS 2.0 API will be enhanced so that multiple
layers of “defense in depth” can be defined using only the FWaaS 2.0
API. This will allow application deployers to take advantage of the
enhancements of FWaaS 2.0 relative to Security Groups, while retaining
“defense in depth”. This will also allow for more than 2 layers of
“defense in depth”, for example tenant application deployers, tenant
network admins, and service provider network admins.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;section id="firewall-address-groups"&gt;
&lt;h4&gt;Firewall Address Groups&lt;/h4&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the
address_group object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable name for the address
group (255 characters limit). Does not
have to be unique.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable description for the
address group (255 characters limit).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of the address group. Only
admin users can specify a project
identifier other than their own.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;cidrs&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;List&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Array of key-value pairs of cidr and
ip version.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="firewall-rules"&gt;
&lt;h4&gt;Firewall Rules&lt;/h4&gt;
&lt;p&gt;Note that as with FWaaS 1.0, in FWaaS 2.0 firewall rules always use stateful connection
tracking.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the firewall
rule object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of the firewall rule. Only
admin users can specify a project
identifier other than their own.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable name for the firewall
rule (255 characters limit). Does
not have to be unique.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable description for the
firewall Rule (255 characters limit).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;public&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When set to True makes this firewall
rule visible to projects other than
its owner, and can be used in
firewall policies not owned by its
project.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;protocol&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;IP Protocol.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;source_port&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;port-range&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Source port number or a range (an
int in [1, 65535] or range in a:b).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;destination_port&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;port-range&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Destination port number or a range (
an int in [1, 65535] or range in a:b).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;service_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID of the service group [6].&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;ip_version&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;IP Protocol Version.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;source_ip_address&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Source IP address or CIDR.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;destination_ip_address&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Destination IP address or CIDR.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;source_address
_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When a source_address_group is
specified, it is matched when the
source IP address in the packet
matches one of the IP addresses in
the address group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;destination_address
_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When a destination_address_group is
specified, it is matched when the
destination IP address in the packet
matches one of the IP addresses in the
address group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;source_firewall_group
_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When a source_firewall_group is
specified, it is matched when the
source IP address in the packet
matches an IP address of one of the
ports in the firewall group.
Note:  This holds true when firewall
group contains a list of vm ports.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;destination_firewall
_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When a destination_firewall_group is
specified, it is matched when the
destination IP address in the packet
matches an IP address of one of the
ports in the firewall group.
Note:  This holds true when firewall
group contains a list of vm ports.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;action&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Action to be performed on the
traffic matching the rule (ALLOW,
DENY, REJECT). Default: DENY.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;enabled&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When set to False will disable this
rule in the firewall policy.
Facilitates selectively turning off
rules without having to disassociate
the rule from the firewall policy.
Default: True.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note: At most one of source_ip_address, source_address_group_id and
source_firewall_group_id can be specified.  The rule is matched when the
source IP address in the packet matches any one of: source_ip_address,
one of the IP addresses in the address group, or an IP address of one
of the ports in the firewall group. If you want it to match any packet,
set the source or destination to 0.0.0.0/0 or ::/0. The same applies to
destination_ip_address, destination_address_group_id, and destination
_firewall_group_id, with respect to the destination IP address in the
packet.&lt;/p&gt;
&lt;p&gt;Note: A rule may specify non-null values for either service_group_id,
or any combination of protocol, source_port, and destination_port.
|&lt;/p&gt;
&lt;/section&gt;
&lt;section id="firewall-policies"&gt;
&lt;h4&gt;Firewall policies&lt;/h4&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the firewall
policy object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of the firewall policy. Only
admin users can specify a project
identifier other than their own.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable name for the firewall
policy (255 characters limit). Does
not have to be unique.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable description for the
firewall Policy (255 characters limit).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;firewall_rules&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;List&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;This is an ordered list of firewall
rule uuids. The firewall applies the
rules in the order in which they appear.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;audited&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When set to True by the policy owner
indicates that the firewall policy has
been audited. Each time the firewall
policy or the associated firewall
rules are changed, this attribute will
be set to False and will have to be
explicitly set to True through an
update operation.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;public&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When set to True makes this firewall
policy visible to projects other than
its owner.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="firewall-groups"&gt;
&lt;h4&gt;Firewall groups&lt;/h4&gt;
&lt;p&gt;Firewall Groups (similar to Security Groups) are the central construct
of the FWaaS 2.0 API. They serve two purposes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Through firewall group / port associations, they specify the
the Neutron ports that are the points of enforcement of firewall
policies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Through the source_firewall_group_id and destination_firewall
_group_id in firewall rules, they allow for filtering based on
source and destination identities, while minimizing the need to
specify long lists of IP addresses.&lt;/p&gt;
&lt;p&gt;For each source_firewall_group and destination_firewall_group,
the OpenStack controller will tell OpenStack FWaaS agents the set
of IP addresses for all VM ports associated with firewall group.
The list of router ports associated with the firewall group will
be passed as is.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Similar to Security Groups, for each project, one Firewall Group named
“default” will be created automatically. This default Firewall Group
will be associate with all new VM ports within that project, unless it is
explicitly disassociated from the new VM port. This provides a way for a
tenant network admin to define a tenant wide firewall policy that
applies to all VM ports, except when explicitly provisioned otherwise.
The default firewall rules for the default Firewall Group are allow all,
i.e. the tenant network admin will have to explicitly define firewall
policies and rules in order for the default Firewall Group to take
effect. For example, the tenant network admin may want to deny
connectivity to certain IP addresses known to be harmful, or deny use of
particular L4 ports. This behavior is chosen assuming that typical
deployments will use “defense in depth”, with application deployers
specifying default Security Groups, while tenant network admins specify
default Firewall Groups.&lt;/p&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the firewall
group object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable name for the firewall
group (255 characters limit). Does
not have to be unique.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable description for the
firewall group (255 characters limit).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of the firewall group. Only
admin users can specify a project
identifier other than their own.
Default: derived from authentication
token.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;ingress_firewall
_policy_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘null’ if not associated with any
firewall policy.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;egress_firewall
_policy_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘null’ if not associated with any
firewall policy.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;ports&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;List&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;List of port_ids that will be
associated to this firewall_group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;section id="list-address-groups"&gt;
&lt;h5&gt;List address groups&lt;/h5&gt;
&lt;p&gt;Lists address groups.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/address_groups&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example List address groups: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;address_groups&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example List address groups: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"address_groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ADDR_GP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"cidrs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="show-address-group-details"&gt;
&lt;h5&gt;Show address group details&lt;/h5&gt;
&lt;p&gt;Shows address group details.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/address_groups/&amp;lt;address_group_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Forbidden(403), Not Found (404)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Show address group: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;address_groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;faaf49f&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dd89&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4e39&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a8c6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;101839&lt;/span&gt;&lt;span class="n"&gt;aa49bc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Show address group: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"address_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ADDR_GP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"cidrs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="create-address-group"&gt;
&lt;h5&gt;Create address group&lt;/h5&gt;
&lt;p&gt;Creates an address group.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/address_groups/&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;201&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Bad Request(400)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Create address group: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;address_groups&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"address_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ADDR_GP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"cidrs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Create address group: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"address_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ADDR_GP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"cidrs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="update-address-group"&gt;
&lt;h5&gt;Update address group&lt;/h5&gt;
&lt;p&gt;Updates an address group.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/address_groups/&amp;lt;address_group_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Bad Request(400) Not Found(404)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Update address group: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;address_groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="n"&gt;bfef97&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;af4e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f6b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a5d3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4678859&lt;/span&gt;&lt;span class="n"&gt;d2485&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"address_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"cidrs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Update address group: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"address_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ADDR_GP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"cidrs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"132.168.4.12/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"cidr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2001::db8::f00/64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="delete-address-group"&gt;
&lt;h5&gt;Delete address group&lt;/h5&gt;
&lt;p&gt;Deletes an address group.&lt;/p&gt;
&lt;p&gt;This operation does not return a response body.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DELETE&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/address_groups/&amp;lt;address_group_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;204&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Not Found(404)
Conflict(409) The Conflict error
response is returned when an
operation is performed while
address group is in use.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Delete address group: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;address_groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;be5e5f7&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c45e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="n"&gt;ba&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;85&lt;/span&gt;&lt;span class="n"&gt;da&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;156575&lt;/span&gt;&lt;span class="n"&gt;b60d50&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Delete address group: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="list-firewall-rules"&gt;
&lt;h5&gt;List firewall rules&lt;/h5&gt;
&lt;p&gt;Lists firewall rules.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/firewall_rules&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example List firewall rules: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_rules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example List firewall rules: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"service_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"fe99d33c1-b472-44f9-8226-30dc4ffd45332"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"asd435dg3-b472-44f9-8226-30dc4ffd45332"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW_HTTP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"source_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"destination_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"source_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"destination_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;
            &lt;span class="s2"&gt;"source_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"destination_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"source_firewall_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ds876h5t1-b472-44f9-8226-3087j9u953gh2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"destination_firewall_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"f98o6h5t1-b472-44f9-8226-3087j9u953gh2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="show-firewall-rule-details"&gt;
&lt;h5&gt;Show firewall rule details&lt;/h5&gt;
&lt;p&gt;Shows firewall rule details.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/firewall_rules/&amp;lt;firewall_rule_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Forbidden(403), Not Found (404)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Show firewall rule: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_rules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;faaf49f&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dd89&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4e39&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a8c6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;101839&lt;/span&gt;&lt;span class="n"&gt;aa49bc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Show firewall rule: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"service_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"fe99d33c1-b472-44f9-8226-30dc4ffd45332"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"asd435dg3-b472-44f9-8226-30dc4ffd45332"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"9faaf49f-dd89-4e39-a8c6-101839aa49bc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW_HTTP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"f9876h5t1-b472-44f9-8226-3087j9u953gh2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_firewall_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ds876h5t1-b472-44f9-8226-3087j9u953gh2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_firewall_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="create-firewall-rule"&gt;
&lt;h5&gt;Create firewall rule&lt;/h5&gt;
&lt;p&gt;Creates a firewall rule.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/firewall_rules/&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;201&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Bad Request(400)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Create firewall rule: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_rules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"f9876h5t1-b472-44f9-8226-3087j9u953gh2"&lt;/span&gt;
        &lt;span class="s2"&gt;"service_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"d2876h5t1-b472-44f9-8245-308dr4u953gh2"&lt;/span&gt;
        &lt;span class="s2"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW_HTTP"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Create firewall rule: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"service_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"d2876h5t1-b472-44f9-8245-308dr4u953gh2"&lt;/span&gt;
        &lt;span class="s2"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW_HTTP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"f9876h5t1-b472-44f9-8226-3087j9u953gh2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_firewall_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ds876h5t1-b472-44f9-8226-3087j9u953gh2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_firewall_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="update-firewall-rule"&gt;
&lt;h5&gt;Update firewall rule&lt;/h5&gt;
&lt;p&gt;Updates a firewall rule.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/firewall_rules/&amp;lt;firewall_rule_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Bad Request(400) Not Found(404)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Update firewall rule: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_rules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="n"&gt;bfef97&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;af4e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f6b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a5d3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4678859&lt;/span&gt;&lt;span class="n"&gt;d2485&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"true"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Update firewall rule: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"service_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"d2876h5t1-b472-44f9-8245-308dr4u953gh2"&lt;/span&gt;
        &lt;span class="s2"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"41bfef97-af4e-4f6b-a5d3-4678859d2485"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ALLOW_HTTP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ip_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_address_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"f9876h5t1-b472-44f9-8226-3087j9u953gh2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"source_firewall_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ds876h5t1-b472-44f9-8226-3087j9u953gh2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"destination_firewall_group_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="delete-firewall-rule"&gt;
&lt;h5&gt;Delete firewall rule&lt;/h5&gt;
&lt;p&gt;Deletes a firewall rule.&lt;/p&gt;
&lt;p&gt;This operation does not return a response body.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DELETE&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/firewall_rules/&amp;lt;firewall_rule_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;204&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Not Found(404)
Conflict(409) The Conflict error
response is returned when an
operation is performed while
firewall rule is in use.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Delete firewall rule: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_rules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;be5e5f7&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c45e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="n"&gt;ba&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;85&lt;/span&gt;&lt;span class="n"&gt;da&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;156575&lt;/span&gt;&lt;span class="n"&gt;b60d50&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Delete firewall rule: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="list-firewall-policies"&gt;
&lt;h5&gt;List firewall policies&lt;/h5&gt;
&lt;p&gt;Lists firewall policies.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/firewall_policies&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Forbidden(403)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example List firewall policies: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_policies&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example List firewall policies: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_policies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"audited"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"firewall_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"c69933c1-b472-44f9-8226-30dc4ffd454c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"test-policy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="show-firewall-policy-details"&gt;
&lt;h5&gt;Show firewall policy details&lt;/h5&gt;
&lt;p&gt;Shows firewall policy details.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/firewall_policies/&amp;lt;firewall_policy_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Not Found(404)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Show firewall policy: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_policies&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;faaf49f&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dd89&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4e39&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a8c6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;101839&lt;/span&gt;&lt;span class="n"&gt;aa49bc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Show firewall policy: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"audited"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"firewall_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"c69933c1-b472-44f9-8226-30dc4ffd454c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"test-policy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="create-firewall-policy"&gt;
&lt;h5&gt;Create firewall policy&lt;/h5&gt;
&lt;p&gt;Creates a firewall policy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/firewall_policies&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;201&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Create firewall policy: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_policies&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"firewall_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"test-policy"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Create firewall policy: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"audited"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"firewall_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"c69933c1-b472-44f9-8226-30dc4ffd454c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"test-policy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="update-firewall-policy"&gt;
&lt;h5&gt;Update firewall policy&lt;/h5&gt;
&lt;p&gt;Updates a firewall policy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/firewall_policies/&amp;lt;firewall_policy_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Not Found (404)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Update firewall policy: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_policies&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="n"&gt;bfef97&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;af4e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f6b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a5d3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4678859&lt;/span&gt;&lt;span class="n"&gt;d2485&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"firewall_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"a08ef905-0ff6-4784-8374-175fffe7dade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Update firewall policy: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"audited"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"firewall_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"a08ef905-0ff6-4784-8374-175fffe7dade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"c69933c1-b472-44f9-8226-30dc4ffd454c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"test-policy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="delete-firewall-policy"&gt;
&lt;h5&gt;Delete firewall policy&lt;/h5&gt;
&lt;p&gt;Deletes a firewall policy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DELETE&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/firewall_policies/&amp;lt;firewall_policy_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;204&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Not Found(404)
Conflict(409) The Conflict error
response is returned when an
operation is performed while the
firewall policy is in use.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Delete firewall policy: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_policies&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;be5e5f7&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c45e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="n"&gt;ba&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;85&lt;/span&gt;&lt;span class="n"&gt;da&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;156575&lt;/span&gt;&lt;span class="n"&gt;b60d50&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Delete firewall policy: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="insert-firewall-rule-in-firewall-policy"&gt;
&lt;h5&gt;Insert firewall rule in firewall policy&lt;/h5&gt;
&lt;p&gt;Inserts a firewall rule in a firewall policy relative to the position of
other rules.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/firewall_policies/&amp;lt;firewall_policy_id&amp;gt;\&lt;/span&gt;
&lt;span class="pre"&gt;/insert_rule&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Not Found(404)
Bad Request(400) Bad Request error
response is returned when the rule
information is missing, Conflict(409)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Insert firewall rule in firewall policy: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_policies&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="n"&gt;bfef97&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;af4e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f6b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a5d3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4678859&lt;/span&gt;&lt;span class="n"&gt;d2485&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;insert_rule&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rule_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"7bc34b8c-8d3b-4ada-a9c8-1f4c11c65692"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"insert_after"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"a08ef905-0ff6-4784-8374-175fffe7dade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"insert_before"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Insert firewall rule in firewall policy: Response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"audited"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"a08ef905-0ff6-4784-8374-175fffe7dade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"7bc34b8c-8d3b-4ada-a9c8-1f4c11c65692"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"c69933c1-b472-44f9-8226-30dc4ffd454c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"test-policy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note:&lt;/p&gt;
&lt;p&gt;insert_before and insert_after parameters refer to firewall rule uuids
already associated with the firewall policy. firewall_rule_id refers
to uuid of the rule being inserted.  When using “insert_after”, if
there are any rules after the specified rule, they get shifted down by
one to later position. When using “insert_before”, all rules from the
specified rule on get shifted down by one to a later position. Only
one of insert_after or insert_before can be non-null and if neither is
specified, firewall_rule_is inserted at the first position.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="remove-firewall-rule-from-firewall-policy"&gt;
&lt;h5&gt;Remove firewall rule from firewall policy&lt;/h5&gt;
&lt;p&gt;Removes a firewall rule from a firewall policy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/firewall_policies/&amp;lt;firewall_policy_id&amp;gt;\&lt;/span&gt;
&lt;span class="pre"&gt;/remove_rule&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Not Found(404)
Bad Request(400) Bad Request error
response is returned when the rule
information is missing or when a
firewall rule is tried to be
removed from a firewall policy to
which it is not associated.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Remove firewall rule from firewall policy: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_policies&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="n"&gt;bfef97&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;af4e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f6b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a5d3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4678859&lt;/span&gt;&lt;span class="n"&gt;d2485&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;remove_rule&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rule_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"7bc34b8c-8d3b-4ada-a9c8-1f4c11c65692"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Remove firewall rule from firewall policy: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"audited"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"a08ef905-0ff6-4784-8374-175fffe7dade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"c69933c1-b472-44f9-8226-30dc4ffd454c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"test-policy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="list-firewall-groups"&gt;
&lt;h5&gt;List firewall groups&lt;/h5&gt;
&lt;p&gt;Lists firewall groups.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/firewall_groups&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example List firewall groups: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_groups&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example List firewall groups: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"ingress_firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"egress_firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"FW_GROUP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"ports"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
                 &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;
             &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="show-firewall-group-details"&gt;
&lt;h5&gt;Show firewall group details&lt;/h5&gt;
&lt;p&gt;Shows firewall group details.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;GET&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/firewall_groups/&amp;lt;firewall_group_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Forbidden(403), Not Found (404)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Show firewall group: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;faaf49f&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dd89&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4e39&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a8c6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;101839&lt;/span&gt;&lt;span class="n"&gt;aa49bc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Show firewall group: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ingress_firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"egress_firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"FW_GROUP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ports"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
             &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;
         &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="create-firewall-group"&gt;
&lt;h5&gt;Create firewall group&lt;/h5&gt;
&lt;p&gt;Creates a firewall group.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;POST&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/firewall_groups/&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;201&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Bad Request(400)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Create firewall group: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_groups&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"ports"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
             &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;
         &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"FW_GROUP_1"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Create firewall group: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ingress_firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"egress_firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"FW_GROUP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ports"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
             &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;
         &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="update-firewall-group"&gt;
&lt;h5&gt;Update firewall group&lt;/h5&gt;
&lt;p&gt;Updates a firewall group.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PUT&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/firewall_groups/&amp;lt;firewall_group_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Bad Request(400) Not Found(404)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Update firewall group: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="n"&gt;bfef97&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;af4e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f6b&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a5d3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4678859&lt;/span&gt;&lt;span class="n"&gt;d2485&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"ingress_firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"f5876h5t1-b472-44f9-8245-308dr4u953gh2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"egress_firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"dg476h5t1-b472-44f9-8245-308dr4u953gh2"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Update firewall group: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"firewall_group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ingress_firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"f5876h5t1-b472-44f9-8245-308dr4u953gh2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"egress_firewall_policy_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"dg476h5t1-b472-44f9-8245-308dr4u953gh2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"FW_GROUP_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"45977fa2dbd7482098dd68d0d8970117"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ports"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
             &lt;span class="s2"&gt;"8722e0e0-9cc9-4490-9660-8c9a5732fbb0"&lt;/span&gt;
         &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="delete-firewall-group"&gt;
&lt;h5&gt;Delete firewall group&lt;/h5&gt;
&lt;p&gt;Deletes a firewall group.&lt;/p&gt;
&lt;p&gt;This operation does not return a response body.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Request Type&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DELETE&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Endpoint&lt;/p&gt;&lt;/td&gt;
&lt;td colspan="2"&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/fw/firewall_groups/&amp;lt;firewall_group_id&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td rowspan="2"&gt;&lt;p&gt;Response Codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Success&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;204&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Error&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized(401), Not Found(404)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Delete firewall group: JSON request&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;firewall_groups&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;be5e5f7&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c45e&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="n"&gt;ba&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;85&lt;/span&gt;&lt;span class="n"&gt;da&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;156575&lt;/span&gt;&lt;span class="n"&gt;b60d50&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;neutronclient&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Example Delete firewall group: JSON response&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;The following are the backend database tables for the REST API proposed above.&lt;/p&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;strong&gt;Firewall Address Groups&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the
address_group object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable name for the address
group (255 characters limit). Does not
have to be unique.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable description for the
address group (255 characters limit).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of the address group. Only
admin users can specify a project
identifier other than their own.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;strong&gt;Firewall Address Group CIDR associations&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the
address_group object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;firewall_address
_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID of firewall address group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;cidr&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CIDR that has to be associated to the
firewall address group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;ip_version&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;IP Protocol Version of the cidr.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;strong&gt;Firewall Rules&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the firewall
rule object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of the firewall rule. Only
admin users can specify a project
identifier other than their own.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable name for the firewall
rule (255 characters limit). Does
not have to be unique.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable description for the
firewall Rule (255 characters limit).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;public&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When set to True makes this firewall
rule visible to projects other than
its owner, and can be used in
firewall policies not owned by its
project.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;protocol&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;IP Protocol.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;source_port&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;port-range&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Source port number or a range (an
int in [1, 65535] or range in a:b).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;destination_port&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;port-range&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Destination port number or a range (
an int in [1, 65535] or range in a:b).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;service_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID of the service group [6].&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;ip_version&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;IP Protocol Version.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;source_ip_address&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Source IP address or CIDR.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;destination_ip_address&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Destination IP address or CIDR.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;source_address
_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When a source_address_group is
specified, it is matched when the
source IP address in the packet
matches one of the IP addresses in
the address group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;destination_address
_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When a destination_address_group is
specified, it is matched when the
destination IP address in the packet
matches one of the IP addresses in the
address group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;source_firewall_group
_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When a source_firewall_group is
specified, it is matched when the
source IP address in the packet
matches an IP address of one of the
ports in the firewall group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;destination_firewall
_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When a destination_firewall_group is
specified, it is matched when the
destination IP address in the packet
matches an IP address of one of the
ports in the firewall group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;action&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Action to be performed on the
traffic matching the rule (ALLOW,
DENY, REJECT). Default: DENY.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;enabled&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When set to False will disable this
rule in the firewall policy.
Facilitates selectively turning off
rules without having to disassociate
the rule from the firewall policy.
Default: True.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;strong&gt;Firewall Policies&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the firewall
policy object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of the firewall policy. Only
admin users can specify a project
identifier other than their own.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable name for the firewall
policy (255 characters limit). Does
not have to be unique.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable description for the
firewall Policy (255 characters limit).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;audited&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When set to True by the policy owner
indicates that the firewall policy has
been audited. Each time the firewall
policy or the associated firewall
rules are changed, this attribute will
be set to False and will have to be
explicitly set to True through an
update operation.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;public&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;When set to True makes this firewall
policy visible to projects other than
its owner.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;strong&gt;Firewall Policy Rule associations&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the
firewall_policy_rules object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;firewall_policy_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID of the firewall policy.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;firewall_rule_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID of the firewall rule.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;position&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;This is an attribute that
gets assigned to this rule when the
rule is associated with a firewall
policy. It indicates the position of
this rule in that firewall policy.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;strong&gt;Firewall Groups&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the firewall
group object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable name for the firewall
group (255 characters limit). Does
not have to be unique.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human readable description for the
firewall group (255 characters limit).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Yes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Owner of the firewall group. Only
admin users can specify a project
identifier other than their own.
Default: derived from authentication
token.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;ingress_firewall
_policy_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘null’ if not associated with any
firewall policy.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;egress_firewall
_policy_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid-str&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘null’ if not associated with any
firewall policy.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;strong&gt;Firewall Group Port associations&lt;/strong&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Req&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the
firewall_group_port object.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;firewall_group_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID of the firewall group.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;port_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;No&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID of the port that will be
associated to this firewall_group.
It can be any Neutron port (VM ports,
router ports, SFC ports).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;div class="line"&gt;&lt;br/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="multiple-firewall-policies"&gt;
&lt;h3&gt;Multiple Firewall Policies&lt;/h3&gt;
&lt;p&gt;When only one firewall group is associated with a specific Neutron port,
the firewall rules are evaluated in order according to their position.
Both “allow” and “deny” rules can be interspersed in any order, with the
first match determining the action to be taken.&lt;/p&gt;
&lt;p&gt;The FWaaS 2.0 API allows for multiple firewall group associations for
the same Neutron port. For example, one firewall group applied to a
tenant’s web servers may specify a firewall policy that restricts
traffic to HTTP only (intended for north/south traffic), while another
firewall group applied to all the tenant’s instances may specify a
firewall policy that allows all traffic types between sources and
destinations in that firewall group (east/west traffic).&lt;/p&gt;
&lt;p&gt;When there are multiple firewall groups associated with a specific
Neutron port, there is no position or priority between the different
firewall groups. Some deterministic behavior must be defined in order to
resolve the action to be taken when some firewall groups determine an
“allow” action while other firewall groups determine a “deny” action.&lt;/p&gt;
&lt;p&gt;This spec defines that packets will be allowed if any one of the
firewall groups associated with that Neutron port allows the packet.
This behavior is similar to the case of multiple Security Groups
associated with the same VM port.&lt;/p&gt;
&lt;p&gt;In future phases, new constructs will be proposed that will allow for
for a “deny” action determined by one firewall group to override an
“allow” action determined by a different firewall group in some cases,
depending on how the firewall groups are associated with the Neutron
port. Refer “Stratum” section in [3] for further details.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;TBD.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;In case of DVR, router ports other than north-facing router ports will
not be supported. The asymmetric design of the DVR data plane for
east/west traffic prevents the use of connection tracking, which is
essential for proper FWaaS operation. The workaround in order to apply
FWaaS to east/west traffic is to enforce FWaaS at VM ports rather than
router ports. Enforcement of FWaaS at VM ports seems to be better
aligned with the distributed architecture of DVR, regardless of this
restriction.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;TBD.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;We will need new Heat models.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Aishwarya Thangappa&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Chandan Dutta Chowdhury&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;German Eichberger&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;James Ardent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mickey Spiegel&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nate Johnston&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sarath Chandra Mekala&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shweta Padubidri&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sridhar Kandaswamy&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;REST API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB Schema&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI update&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Depends on the Service Groups [6]&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DB mixin and schema tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FWaaS Plugin with mocked driver end-to-end tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New tests need to be written&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;REST API and attributes validation tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron CLI and FWaaS API documentation have to be modified.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;neutron-fwaas repo will have a devref and documentation will be written.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://www.openstack.org/summit/tokyo-2015/videos/presentation/openstack-neutron-fwaas-roadmap"&gt;https://www.openstack.org/summit/tokyo-2015/videos/presentation/openstack-neutron-fwaas-roadmap&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[2] &lt;a class="reference external" href="https://etherpad.openstack.org/p/mitaka-neutron-next-adv-services"&gt;https://etherpad.openstack.org/p/mitaka-neutron-next-adv-services&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[3] &lt;a class="reference external" href="https://etherpad.openstack.org/p/fwaas-api-evolution-spec"&gt;https://etherpad.openstack.org/p/fwaas-api-evolution-spec&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[4] &lt;a class="reference external" href="https://etherpad.openstack.org/p/FWaaS_with_DVR"&gt;https://etherpad.openstack.org/p/FWaaS_with_DVR&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[5] &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1513574"&gt;https://bugs.launchpad.net/neutron/+bug/1513574&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[6] &lt;a class="reference external" href="http://specs.openstack.org/openstack/neutron-specs/specs/kilo/service-group.html"&gt;http://specs.openstack.org/openstack/neutron-specs/specs/kilo/service-group.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[7] &lt;a class="reference external" href="http://developer.openstack.org/api-ref-networking-v2-ext.html#security_groups"&gt;http://developer.openstack.org/api-ref-networking-v2-ext.html#security_groups&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Sun, 10 Apr 2016 00:00:00 </pubDate></item><item><title>Subnet Service Types</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/newton/subnet-service-types.html</link><description>

&lt;p&gt;RFE:
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1544768"&gt;https://bugs.launchpad.net/neutron/+bug/1544768&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Launchpad blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/service-subnets"&gt;https://blueprints.launchpad.net/neutron/+spec/service-subnets&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The current IP allocation method for ports on the external network
utilizes the same strategy done for internal networks - choose
an IP from the subnet(s) associated with the network.  In this
scenario, all subnets are created equal, and there is no way
to give precedence to one over the other.&lt;/p&gt;
&lt;p&gt;Since these IP addresses are typically Internet-routable, or at
least routable within the datacenter they are used in, they
should be considered scarce, and be assigned sparingly.&lt;/p&gt;
&lt;p&gt;This blueprint aims to change the allocation strategy to better
utilize this scarce resource, and only use it for ports that
must have Internet-routable IP addresses, using secondary subnets
for IP allocations for other ports.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;In Neutron, each router with an interface on the external network consumes
one (or more) IP addresses from the subnet configured on it.  For example,
on the Network Node, an IP address is assigned to a project’s (aka tenant’s)
router in order to allow instances to access the external network
using this single SNAT IP address.&lt;/p&gt;
&lt;p&gt;In the case of a router on a distributed (compute) node, which is also
connected to the external network, a single Floating IP (FIP) namespace
is created in order for each instance with a floating IP address to be
able to directly reach the external network.  The floating IP namespace
also consumes an IP address from the external subnet to use for all tenant
routers residing on this node, even though it is never used for north-south
routing of traffic - it is mainly used for reachability testing (aka - can
I reach that distributed router).&lt;/p&gt;
&lt;p&gt;In this second case, there is no reason an IP address from a different,
secondary subnet, could not be used for the primary IP address inside
the FIP namespace, such that reachability can still be confirmed, but
public IP consumption is not impacted.&lt;/p&gt;
&lt;p&gt;Also, when a router is just forwarding packets onto a transit
network for further processing by another device, like a carrier-grade
NAT, no NAT needs to be performed in the router, the packet just
follows the standard forwarding data path.  So using a subnet that
exists only within the datacenter is possible.&lt;/p&gt;
&lt;p&gt;Being able to choose the subnet used for IP allocation in all these
cases is highly-desired by operators.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This spec proposes adding a new logical item, called ‘service_type’, to
the Subnet class object in Neutron, a list attribute that can specify
the usage type for the subnet.  A type must be one of the currently
valid values for the ‘device_owner’ field in the Port model
(port[‘device_owner’]), for example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;‘network:floatingip_agent_gateway’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘network:router_gateway’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;…&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Since it is a list, it can contain more than one value in order to
specify IP addresses for multiple device_owner types that should be
allocated from the same subnet.&lt;/p&gt;
&lt;p&gt;This list will be instantiated as a new table containing rows of
(subnet_id, service_type) values, such that a join from Subnets.id
can be made to determine the service_types associated with the
subnet.&lt;/p&gt;
&lt;p&gt;When an IP allocation is performed, for example, when an external gateway
is added, and the plugin supports the ‘service-type’ extension, the IPAM
driver will return an address from the Subnet that has a ‘service-type’
matching the port’s device_owner field.&lt;/p&gt;
&lt;p&gt;In the case where no Subnets with the given ‘service-type’ exist for
the port’s device_owner, or the IP address pool of all matching subnets
is exhausted, the fallback is to use a Subnet without any type for IP
allocation.  This preserves backwards-compatibility with existing
deployments.&lt;/p&gt;
&lt;p&gt;When all Subnets are created with a ‘service-type’, there is no
fallback strategy since a Subnet without a type does not exist.
This can be used to enforce strict IP allocation from only Subnets
where the device_owner matches.&lt;/p&gt;
&lt;p&gt;When multiple Subnets exist with the given ‘service-type’, or there are
both a matching and one without a type, then they will be tried in
order, with the matching ‘service-type’ Subnet(s) being tried first.
For example, with a Floating IP agent gateway port, the precedence
order would be [‘network:floatingip_agent_gateway’, None].&lt;/p&gt;
&lt;p&gt;If a Subnet is specified explicitly in the port create or update request, the
logic to select candidate Subnets described above will be skipped.  The
specified Subnet will be the only candidate regardless of its ‘service-type’.&lt;/p&gt;
&lt;p&gt;With the data model proposed, all of this can be accomplished by simply
ordering all the matching subnets correctly, putting ‘service-type’
subnets first, followed by non-‘service-type’ subnets, in a single query.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Service-type subnet extension is added&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New table is created linking Subnet IDs with Service Types.  It will
have the columns (subnet_id, service_type), where the subnet_id has
a foreign key constraint on Subnets.id.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The primary key will be (subnet_id, service_type) to provide an index
and uniqueness.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;‘service_type’ will be exposed to users via the extension API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Ability to create or update subnets with a service-type will be&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;limited to the admin user, since it will only be affecting IP
allocation on external networks.  Validation will be done to
restrict the values to a known set of values supported by the
extension.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List Subnets of a given service-type.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sample REST calls:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;POST /v2.0/subnets
{
      'subnet': {
          'network_id': '&amp;lt;NETWORK-ID&amp;gt;',
          'ip_version': 4,
          'cidr': '10.0.3.0/24',
          'allocation_pools': [{'start': '10.0.3.20', 'end': '10.0.3.150'}],
          'service_type': ['network:floatingip_agent_gateway']
      }
}

PUT /v2.0/subnets/SUBNET-ID/service_types/
{
    'service_type': ['network:floatingip_agent_gateway']
}

GET /v2.0/subnets?service_type='network:floatingip_agent_gateway'
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="command-line-client-impact"&gt;
&lt;h3&gt;Command Line Client Impact&lt;/h3&gt;
&lt;p&gt;A new option will be added to the openstackclient, for example:&lt;/p&gt;
&lt;p&gt;$ openstack subnet create {ARGS} –service-type SERVICE-TYPE SUBNET-NAME&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;Horizon will need to at least expose the service_type attribute on the
subnet.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There should be almost no performance impact as this should just be
an additional table join in the IPAM code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;This change will consider IPv4 and IPv6 equally.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Deployers will not be required to do anything when upgrading code until
they want to make use of the new features provided by this spec.&lt;/p&gt;
&lt;p&gt;New or existing deployments can make use of this new feature after
upgrading their code by adding a new Neutron subnet to the existing
external network, or change the ‘service-type’ of an existing subnet on
that network if required.&lt;/p&gt;
&lt;p&gt;They might need to change configuration in their top-of-rack switches,
or whatever else needs to be done to have a secondary subnet on their
existing physical network.  That work is outside the scope of this spec.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;This change will have an effect on developers.  This blueprint contains API
and model changes that plugin providers will need to look at implementing.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;Yes.  This change has been discussed on the ML, in Neutron meetings
(especially L3), at mid-cycles, and at the design summit.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative is to not use Public IP addresses as Floating IP addresses,
but instead use IP addresses that are routable within the datacenter
infrastructure.  Access to the public Internet is then accomplished via
a carrier-grade NAT device that sits between the two networks.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~brian-haley"&gt;Brian Haley&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~carl-baldwin"&gt;Carl Baldwin&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please add your name here and attend the &lt;a class="reference external" href="https://wiki.openstack.org/wiki/Meetings/Neutron-L3-Subteam"&gt;L3 Subteam Meeting&lt;/a&gt; if you’d
like to contribute.  If your name is here and you don’t have any time to
contribute, let me know.  This section is really just my sticky note of
contributors who can play a role in this effort.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Subnet extension&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;For ML2, use the multi-provider extension data model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new ‘Subnet_service_types’ table&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add logical service_type value to Subnet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IPAM support&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;When choosing an IP address to allocate to a port, IPAM needs
to take into account the device_owner when selecting the subnet.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Unknown&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Unknown&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Subnet service-type resource (CRUD)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Document the usage of the value in the Subnet&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Thu, 31 Mar 2016 00:00:00 </pubDate></item><item><title>MTU selection and advertisement</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/mtu-selection-and-advertisement.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/mtu-selection-and-advertisement"&gt;https://blueprints.launchpad.net/neutron/+spec/mtu-selection-and-advertisement&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This proposes a list of fixes to the MTU problems of Openstack to
ensure that VMs run with the correct MTU on both virtual and physical
Openstack networks.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;tl;dr: Your Neutron network’s MTU for any L3 encap is probably not
1500 bytes.  This causes a multitude of creeping horrors, listed in
excruciating detail here, and while there are existing workarounds
they don’t work in a variety of deployment types, probably including
the one you’re running right now.  If you are willing to accept this
as a given, skip to the next section.&lt;/p&gt;
&lt;p&gt;Neutron networks have unpredictable MTUs, which causes a long list of
corner case behaviour.&lt;/p&gt;
&lt;p&gt;The MTU of a tenant network running on machines that themselves have
MTUs of 1500 bytes on all their interfaces (the typical default value)
may be, among other values:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;1500 bytes, where the encap mechanism used is VLANs, or the network
is a flat network.  Note that, independent of your preferred encap
type, one of these two applies to all your externally connected
network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;1492 bytes, where the encap mechanism used is GRE tunnels.  Note
that this implies that your tenant network on one side of the router
doesn’t have the same MTU as the external network on the other side&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;smaller, if the encap is something else L3 like VXLAN&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;larger, if the cloud has been deployed on an infrastructure using
jumbo frames&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the maximum transfer unit size is exceeded, packets are dropped,
either on the network (if the network cannot pass traffic as big as
the sender expects to send) or at the desination (if the desination’s
configured MTU is smaller than that of the sender or the network).  In
practice, this means that both the sender and receiver - be they VMs,
services or routers - &lt;em&gt;must&lt;/em&gt; agree on MTU size, and the network
segment &lt;em&gt;must&lt;/em&gt; pass packets of the agreed size.&lt;/p&gt;
&lt;p&gt;Also, note that L3 mechanisms for path MTU discovery &lt;em&gt;only&lt;/em&gt; take place
for packets passing through a L3 element such as a router.  They do
&lt;em&gt;not&lt;/em&gt; take place for traffic transiting an L2 segment, which means
that large packets are dropped without the sender finding out.  This
leads to inconsistent behaviour with different transfer types:
typically, bulk transfers of data do not work but some connections
such as small HTTP requests do.&lt;/p&gt;
&lt;p&gt;Aside from the size of the absolute maximum transfer unit that the
segment will pass, there is also typically a preferred transfer unit
size to use.  Some tunnelling protocols allow fragmentation of packets
after encapsulation, which means that if a certain transfer unit size
is exceeded the encapsulated packet undergoes fragmentation and, while
the packet arrives, the network performance drops off dramatically.&lt;/p&gt;
&lt;p&gt;Finally, MTU is frequently inconsistent between different endpoints in
a segment.  Between two VMs on the same host, it is quite common to be
able to communicate with transfer units that are bigger than between
two VMs on different hosts.  The MTU for the segment should be the
minimum that works between any pair of hosts, but this is not always
true.&lt;/p&gt;
&lt;p&gt;A recommended and widely deployed workaround is to advertise a
functional sub-1500 MTU to all VMs over DHCP, which works providing:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DHCP MTU advertisements are respected&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;there are no provider networks in operation (as their MTU size is
typically 1500 and may be completely different, and in either case
VMs will not communicate with external systems)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the external network is configured for small MTUs at the nexthop&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;any service MTUs are also appropriately configured.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This also does not function for IPv6-only VMs - they respond to an RA
attribute, not DHCPv4, and the RA attribute will generally only work
to &lt;em&gt;reduce&lt;/em&gt; network MTU - or for the occasional VMs that do not speak
IP at all.&lt;/p&gt;
&lt;p&gt;Occasionally, tenants also have opinions about the MTU they desire -
either that it is larger than the default 1500, or, for deployments
that have been deployed in a way that makes large MTU sizes
functional, that they nevertheless wish to have a 1500 MTU.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This blueprint proposes bringing consistency to MTU operations, such
that (in order of desirability):&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;the best MTU to use is automatically determined&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the plugin can ensure that advertisement mechanisms (e.g. DHCP, RA,
config drive) can access the correct MTU for the network, and are
used to propagate it to guests when this functionality is enabled&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the plugin can ensure that network services attached to a network
operate with the correct MTU (e.g. router ports have an appropriate
interface MTU configured) so that, even in the case of differing MTU
sizes on different networks, normal L3 behaviour will accommodate
the variance without breaking tenant communications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the tenant can discover the MTU on the network, so that - in the
case that the tenant has to write configuration files on a config
drive to instruct the VM to configure MTU - it can tell which MTU
value to use.  Note that some VMs will not request DHCPv4 MTU, a
strict reading of the RFC prohibits VMs from accepting a large MTU
over IPv6 RA, and there is no config drive mechanism at present for
avertising an MTU, so this possibility must be accounted for&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the tenant can request a specific MTU on a network - this is so
that, in the case that the tenant has VMs with preconfigured MTUs
(for instance, ones that do not respect any of the available forms
of MTU advertisement, they can ask for a specifc - typically 1500 -
MTU for networks that have these VMs on)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the plugin can confirm that it can deliver a certain MTU on the
network, if a request has been made explictly&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For any given network, Neutron will internally calculate two values.
These are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;the maximum MTU that will work.  This may be indeterminate (for
instance, if the encap fragments).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the optimum MTU to use.  This may be the maximum MTU, or it may be
smaller.  Packets greater than this optimum MTU may see degraded
throughput, though if they are smaller than the maximum MTU they
will be passed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The tenant may, optionally (and in Phase III; see below), propose an
MTU for the network by setting the ‘mtu’ flag on a net-create.  The
plugin in use has two options:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;It can create the network, setting the MTU of that network to the
size given (meaning that the L2 segment will pass packets of at
least that size; services started on that network will have the
same MTU as the network; and the MTU advertised, if advertisement
is turned on, is the MTU selected).  The ‘mtu’ attribute of the
network, stored in the DB and returned on the network object, will
contain the MTU requested.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It can decline to create the network, because it cannot satisfy the
MTU request, if the MTU is greater than the maximum MTU.
Alternatively, Neutron will decline the request if the plugin does
not support MTU control.  This allows us to make the ‘mtu’
interface core while supporting plugins that do not recognise it.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When the MTU is &lt;em&gt;not&lt;/em&gt; provided, supporting plugins will use the
preferred value.  Non-supporting plugins will leave it indeterminate.&lt;/p&gt;
&lt;p&gt;If the network is also flagged as VLAN transparent (per the VLAN
transparency spec, not implemented yet, at [1]), the network must pass
a VLAN tagged packet with content of the MTU size or less (meaning the
content of the packet before VLAN tagging must be 8 bytes smaller than
the MTU on the Neutron network).  This distinction matters in
tunnelling protocols such as GRE - traditionally, VLAN tags are not
counted against MTU, but the additional header fields count against
GRE tunnel payload, so additional space needs to be left if the tagged
packet might pass through a tunnel.&lt;/p&gt;
&lt;p&gt;A configuration item for Neutron, ‘advertise_mtu’, defaulting to false
if absent (for backward compatibility), enables MTU advertisement.  If
set to true, various MTU advertisement mechanisms will be enabled and
configured with the MTU.  The list of advertisements include:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DHCPv4 will advertise the MTU when requested by the guest with an
‘MTU’ option&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IPv6 RAs, where sent by Neutron, will contain the MTU (though,
typically, guests will only respect MTU sizes less than 1500 unless
specially configured)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following advertisement method will be added when 3rd party
support is available:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;cloud-init files will include the interface MTU for each interface.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If advertisement is turned off, it is the responsibility of the
Openstack application to ensure that its VMs have appropriate MTUs
configured.&lt;/p&gt;
&lt;p&gt;Regardless of the advertisement setting, Neutron network appliances
such as routers, and advanced service appliances, will have their
interfaces configured to the selected MTU if the MTU is known.  This
implies that the plugging mechanism for the service understands and
correctly implements MTU setting.&lt;/p&gt;
&lt;p&gt;For any given MTU that is advertised to the network, the plugin must
be certain that, even in the event of a change of underlying network
topology (e.g. failover to a backup path, or using a different encap
type, or switching from a single-host to multi-host setup when a new
instance is attached to the network), packets of the specified size
transmitted from &lt;em&gt;any&lt;/em&gt; endpoint will &lt;em&gt;always&lt;/em&gt; be guaranteed to reach
all desinations.  It is its task to ensure that the MTU is small
enough to work on the selected infrastructure, both inter-host and
intra-host.&lt;/p&gt;
&lt;p&gt;An Openstack network typically has physical networks for (a) external
connectivity and (b) provider network use.  These networks may or may
not have the same MTU size as each other and are quite likely to have
an MTU size different from that of the virtual tenant networks.  Link
MTU for physical networks is specified by configuration and will be
used as the maximum and preferred MTU sizes for provider and external
networks on those segments.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Common workarounds for this problem are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;using config, adding a DHCP option to propagate a ‘safe’ MTU to all
VMs, and setting the MTU in various (somewhat driver-specific)
config parameters to ensure that L2 and L3 network elements work.
This tends to work for v4 and not v6, as the equivalent option is
not generally set; it’s not fully functional, as routers are unaware
that their MTU is incorrect; and it’s only available to VMs that
actually support DHCP.  It also does not work if tenant and provider
networks have different MTUs, or internal networks and the external
network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;instructing users, in documentation, to set a ‘safe’ MTU in all VMs
(plus the same config option tweaks).  This has the same caveats as
above, in that the VMs may agree with each other but do not agree
with routers and this can result in unexpected behaviour.  It does
not work with provider networks or other configurations where
different Neutron networks have different MTUs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;it is possible to use large MTU interfaces and configure the MTU on
network components such as in-kernel switches and bridges, but again
routers are not always correctly configured and provider network MTUs
are commonly wrong.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are some MTU-related configuration variables, but they serve as
a workaround to MTU issues that arise with software networking
constructs.  If the MTU of the network were known explicitly there
would be no need for this configuration, as the relevant components
could have their MTU explcitly configured to be that of the virtual
network.&lt;/p&gt;
&lt;p&gt;When the driver sets the MTU on the network or the tenant provides it,
the values for network_device_mtu and veth_mtu are derived dynamically
for that network and any configuration values are ignored.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;‘mtu’ (positive integer) attribute added to the data model for
networks.  This stored the determined preferred value for ‘mtu’,
unless overridden by the user.  It may be indeterminate, in which case
it is stored as NULL.  When NULL, advertisement mechanisms will not
send MTU.&lt;/p&gt;
&lt;p&gt;In Phase I, mtu is stored in the database but not exposed over the
API.  It is set at net-create to the preferred MTU provided by the
plugin (if any), and read to provide advertisement via DHCP and RA.&lt;/p&gt;
&lt;p&gt;In Phase II, the item becomes visible over the API to all users as a
readonly attribute.  NULL is treated as unset.&lt;/p&gt;
&lt;p&gt;In Phase III, the item is writeable over the API, providing the
administrator has explicitly enabled it in policy.json.  It can only
be set in a net-create call and it is passed to the plugin; ML2 will
validate it aginst the plugin-provided max-MTU value and reject any
value that is too high.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Phase II only:&lt;/p&gt;
&lt;p&gt;The ‘mtu’ attribute can be read by any user from the network object.
The value is constant over the lifetime of the network.&lt;/p&gt;
&lt;p&gt;Phase III only:&lt;/p&gt;
&lt;p&gt;For net-create, the ‘mtu’ attribute may be provided.  It will be
validated against the max calculated MTU within the plugin and may be
rejected as too large.  Its value is immutable after net-create, so
net-update must not accept it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;There may be some visibility into cloud implementation now that the
user can detect maximum and preferred MTU values, but this is not a
security risk in and of itself.  Consideration should be given to
whether this weakens any other security assumptions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;RAs will carry MTU when advertisement is enabled.  An MTU greater
than 1500 will not be accepted by RFC-conforming IPv6 stacks in VMs.
Linux VMs will generally take it if their MTU is larger than 1500 when
the RA is received.  This information should be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;VMs may now receive MTU advertisements in DHCPv4 and IPv6 RA.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The current issues with MTU occasionally lead to very low network
performance when large tenant packets are passed over tunnels where
the tunnel packet size exceeds the PMTU of the tunnel.  Correct MTU
behaviour should rectify this, particularly if network plugins prefer
to create networks with MTUs that do not cause packet fragmentation.&lt;/p&gt;
&lt;p&gt;Nothing should make performance worse.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;The deployer may provide three new configuration variables:&lt;/p&gt;
&lt;p&gt;advertise_mtu - default false, and when false, backward compatible; no
effort is made to advertise MTU to VMs via network methods.  When
true, VMs will receive DHCP and RA MTU options when the network’s
preferred MTU is known.&lt;/p&gt;
&lt;p&gt;path_mtu - for L3 mechanism drivers, determines the maximum
permissible size of an unfragmented packet travelling from and to
addresses where encapsulated Neutron traffic is sent.  Drivers should
calculate maximum viable MTU for validating tenant requests based on
this value (typically path_mtu - max encap header size).  If not
supplied, the path MTU is indeterminate and no calculations will take
place (i.e. MTU requests will be declined for all drivers requiring
it).  (Note that the path MTU is specified and not probed, as it is
impossible to programmatically determine the smallest MTU on the
&lt;em&gt;worst&lt;/em&gt; possible path between two endpoints, only the path MTU
currently in use.)&lt;/p&gt;
&lt;p&gt;segment_mtu - for L2 mechanism drivers (i.e. VLAN), determines the
segment MTU.  If not supplied, the segment MTU is indeterminate and no
calculations will take place (i.e. MTU requests will be declined for
all drivers requiring it).  (Note that the segment MTU is determined
from config and &lt;em&gt;not&lt;/em&gt; by probing interfaces, as multiple interfaces
can be involved in a network segment.)&lt;/p&gt;
&lt;p&gt;Additionally, a new attribute, physnet_mtus, will be added to the
ML2 configuration to accommodate an optional per-physical network
MTU setting.  Any physical networks without a corresponding
physnet_mtus setting will cause the use of the global segment_mtu
value in MTU calculations for that physical network (if the
segment_mtu is unset then no calculation takes place).&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Example:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;physnet_mtus = physnet1:1550, physnet2:1500&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Or, to set MTU for physnet2 and leave physnet1 as default:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;physnet_mtus = physnet2:1550&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;This can be used to declare the MTU of physical networks, including
the external network and those used for provider networks.&lt;/p&gt;
&lt;p&gt;The values listed above mean that it is possible to calculate the
maximum MTU that a specific network can transit based on the driver or
drivers used to construct it.&lt;/p&gt;
&lt;p&gt;The veth_mtu property was previously used to configure the MTU of a
veth interface used in constructing OVS-driver network elements.  This
is no longer required when the network MTU is set.  It will be ignored
in those circumstances, but will be applied if the network mtu cannot
be calculated (e.g. if the path or segment MTUs are required and not set).&lt;/p&gt;
&lt;p&gt;The network_device_mtu was previously used to configure the MTU of
interfaces in namespaces that attach to Neutron networks.
After this change, if the driver (or the tenant) has set the MTU of
the network, this will now be used directly.  If indeterminate,
network_device_mtu will still be used.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Plugins should add support for the proposed MTU interface.  This blueprint
does not mandate the timetable but offers the facility for them to do so.
We will change at least the ML2 plugin as a sample to allow for testing but
do not guarantee to add support to all plugins.&lt;/p&gt;
&lt;p&gt;Drivers should add support for the proposed MTU interface.  We will
change the OVS, LB, VLAN, VXLAN and GRE drivers to add support.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;ijw-ubuntu&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;This work will be conducted in three distinct phases.&lt;/p&gt;
&lt;p&gt;Phase I will involve creating mechanisms to allow calculation of
suitable MTUs within the ML2 plugin and the OVS, Linuxbridge, VLAN,
GRE and VXLAN drivers; the advertisement of those MTUs to VMs; and the
use of those MTUs by the namespace implementations of services
(Neutron routers, DHCP, Metadata).  Note that, per the problem
statement, this &lt;em&gt;does&lt;/em&gt; require per-network MTU values.  At this point,
backward compatibility mechanisms will be put in place so that drivers
that do &lt;em&gt;not&lt;/em&gt; support MTU calculation fall back to their current
behaviour.&lt;/p&gt;
&lt;p&gt;Phase II will involve enabling the read-only ‘mtu’ flag on the network
object, so that VMs with issues understanding advertisement mechanisms
can be configured out-of-band to the correct MTU.&lt;/p&gt;
&lt;p&gt;Phase III will involve allowing the user to specify their own
selection of MTU, the validation of that MTU against the driver’s
permitted values, and the appropriate advertisement of the MTU.  This
will be done initially as experimental code, where the ‘mtu’
advertisement will take a value on net-create commands but the actual
writing of the value is disabled in the default policy.json.  This
permits interested parties to use the functionality without enabling
it for the majority of users.&lt;/p&gt;
&lt;p&gt;For Kilo, Phase I must be completed, and Phase II is highly desirable.
Phase III has a lower priority.&lt;/p&gt;
&lt;p&gt;The tasks for phase I are as follows:&lt;/p&gt;
&lt;p&gt;Change the data model in the database to have an ‘mtu’ flag on
networks, adding upgrade and downgrade scripts&lt;/p&gt;
&lt;p&gt;Change the config file reader so that the new format of the
bridge-mappings item is understandable.&lt;/p&gt;
&lt;p&gt;Add the path_mtu, segment_mtu and advertise_mtu properties to the
configuration file reader&lt;/p&gt;
&lt;p&gt;Change the OVS, LB, VLAN, GRE and VXLAN drivers to correctly calculate
their maximum and preferred MTU values, using bridge-mappings,
path_mtu and segment_mtu as required.&lt;/p&gt;
&lt;p&gt;Change the ML2 plugin to correctly determine the maximum and preferred
MTU values for a network based on the capabilities of the drivers in
use for the network, and store that value on the network object in the
database.&lt;/p&gt;
&lt;p&gt;Correct the network control and plugging code to correctly set the MTU
on all software network elements that respect it&lt;/p&gt;
&lt;p&gt;Add code to the neutron namespaces to correctly set the MTU&lt;/p&gt;
&lt;p&gt;Add automatic advertisement, if the MTU is set on a network, from DHCP,
when DHCP is enabled.&lt;/p&gt;
&lt;p&gt;Add automatic advertisement, if the MTU is set on a network, from RA,
when RA is enabled.&lt;/p&gt;
&lt;p&gt;The tasks for phase II are as follows:&lt;/p&gt;
&lt;p&gt;Expose the ‘mtu’ flag for read on networks&lt;/p&gt;
&lt;p&gt;The tasks for phase III are as follows:&lt;/p&gt;
&lt;p&gt;Expose the ‘mtu’ flag for write on net-create&lt;/p&gt;
&lt;p&gt;Validate the value passed against the maximum MTU the driver is
capable of&lt;/p&gt;
&lt;p&gt;Change the core Neutron code to refuse to create a network when an
‘mtu’ is provided and a plugin does not know its maximum MTU.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Phase I:&lt;/p&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;p&gt;Phase II:&lt;/p&gt;
&lt;p&gt;Test presence and value of new ‘mtu’ attribute; confirm read-only;
confirm expected value&lt;/p&gt;
&lt;p&gt;Phase III:&lt;/p&gt;
&lt;p&gt;Test writing to ‘mtu’ attribute; test it is respected; test it is
correctly validated against maximum and preferred MTU&lt;/p&gt;
&lt;p&gt;Validate that max MTU is correctly calculated for VLAN based on
segment mtu for tenant networks and the physical network MTU for
provider networks&lt;/p&gt;
&lt;p&gt;Validate that max MTU is correctly calculated and used for the
external network based on the external bridge physical MTU.&lt;/p&gt;
&lt;p&gt;Verify physical MTUs default to 1500.&lt;/p&gt;
&lt;p&gt;Verify network elements are correctly configured based on the new
config parameters and the old config parameters no longer affect
behaviour.&lt;/p&gt;
&lt;p&gt;Verify that a driver and plugin decline a network create with an
untransmissibly large MTU&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Phase I:&lt;/p&gt;
&lt;p&gt;Confirm that VLAN, VXLAN, GRE, OVS and Linuxbridge drivers are
correctly calculating their MTU from the inputs - the configuration
parameters path_mtu, segment_mtu and physnet_mtus&lt;/p&gt;
&lt;p&gt;Confirm that, using the above drivers, ML2 correcly calculates the MTU
to use for a variety of network types, including virtual, provider and
external networks&lt;/p&gt;
&lt;p&gt;Confirm that the MTU is being correctly advertised by checking the
dnsmasq and RADVD config in use on networks when advertise_mtu is set;
confirm that it is &lt;em&gt;not&lt;/em&gt; advertised when advertise_mtu is not set&lt;/p&gt;
&lt;p&gt;Phase II:&lt;/p&gt;
&lt;p&gt;Confirm that the ‘mtu’ value exposed on a network is correct per
selected network configuration, for a variety of configurations&lt;/p&gt;
&lt;p&gt;Phase III:&lt;/p&gt;
&lt;p&gt;Ensure appropriate application of MTU to all elemtns when
MTU-specified and a non-specified networks are used.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Tempest scenario tests to ensure:&lt;/p&gt;
&lt;p&gt;Phase I:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;When advertisement is on, a packet of that size can be transmitted
and received across a network between VMs that recognise the
advertisement type&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Phase II:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;When VMs are manually configured on startup with the ‘mtu’ value
seen on the network, with ‘advertise_mtu’ disabled, a packet of
that size can be transmitted and received across a network between
VMs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Phase III:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;an accepted MTU is transmissible&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;The new ‘mtu’ attribute should be documented.
The changed behaviour of DHCP and RA should be documented.&lt;/p&gt;
&lt;p&gt;The new ‘path_mtu’, ‘segment_mtu’ and ‘advertise-mtu’ options should
be documented.  The options they replace should be deprecated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Plugin and driver design documents should note the new functionality
to manage MTU.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/nfv-vlan-trunks"&gt;https://blueprints.launchpad.net/neutron/+spec/nfv-vlan-trunks&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 01 Feb 2016 00:00:00 </pubDate></item><item><title>Allow Open vSwitch agent extensions to own their flows</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/l2-agent-extensions-agent-api.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1517903"&gt;https://bugs.launchpad.net/neutron/+bug/1517903&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In Liberty, &lt;a class="reference internal" href="#l2-agent-extensions"&gt;L2 agent extensions&lt;/a&gt; and &lt;a class="reference internal" href="#l2-agent-extension-manager"&gt;L2 agent extension manager&lt;/a&gt; were
introduced. Those extensions are triggered on specific events (particularly, on
port updates and deletes), but they have no way of interacting with the agent’s
underlying resources, e.g. bridges, flows, etc. Some features currently in
development (SFC, QoS DSCP, others) require some level of coordination between
an extension and the agent running it.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;One major use case where extensions need to coordinate with the agent that is
running them arises from the Open vSwitch agent graceful restart feature added
in Liberty cycle. For this feature, a per-session agent id is used to
distinguish flows that belong to the current agent session from those that
belong to the previous one. The problem starts when an extension wants to
inject its own flows into the switch. Since those extensions don’t have a way
to determine what the current agent id is, they cannot mark their new flows
with it, which results in the agent dropping all their flows on restart under
the assumption that they are stale in the sense of “belonging” to the previous
agent session.&lt;/p&gt;
&lt;p&gt;Allowing each extension to reserve a unique cookie value known to the agent,
and to use that value for its own flows, will be the first reference
implementation agent-specific API that will be exposed through the new proposed
mechanism. This will be achieved by exposing integration and tunnel bridges
thru a light weight wrapper around Open vSwitch bridges that allocates and
manages cookie values for extensions and hardens them from breaking flows that
belong to other extensions.&lt;/p&gt;
&lt;p&gt;Later, the agent-specific API will be extended once the extensions needs are
better understood. One of the features planned for the future is a higher level
flow management API that would abstract out the processing pipeline, allowing
multiple flow-aware extensions to be managed in a more controlled manner
(enforcing processing ordering, better safe guarding other features from
accidental breakages by misbehaving extensions, etc.) Once that higher level
API is implemented, we may consider deprecating the API proposed by this spec.&lt;/p&gt;
&lt;p&gt;Note that additional APIs are out of scope for the proposal.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposed change will expand the extensions manager and the L2 agent
extensions APIs with an optional agent-specific API object. The extension
manager will in turn propagate the new API object to each of the extensions.
An extension that needs to interact with the agent running it will be able to
determine the agent type (e.g., Open vSwitch, Linuxbridge, SR-IOV, etc.) that
is running it by inspecting the driver_type argument that is already passed
into its initialize() method.&lt;/p&gt;
&lt;p&gt;Since extensions can be maintained outside the Neutron tree, we should consider
not breaking them with later agent API changes. Hence the agent API will be
considered part of public Neutron API and will evolve with due attention to
backwards compatibility concerns.&lt;/p&gt;
&lt;p&gt;Since out-of-tree agents could already rely on extensions mechanism, the new
API object argument will be optional in the extensions manager and in
extensions themselves.&lt;/p&gt;
&lt;p&gt;Only Open vSwitch will be updated to  pass the agent API object of
corresponding type into L2 agent extensions. Other agents will be extended with
the mechanism as needs arise.&lt;/p&gt;
&lt;p&gt;As part of the proposal, the Open vSwitch agent API object will include two new
methods that will return wrapped and hardened bridge objects with cookie values
allocated for calling extensions. Extensions will be able to use those wrapped
bridge objects to set their own flows, while the agent will rely on the
collection of those allocated values when cleaning up stale flows from the
previous agent session:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+-----------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt; &lt;span class="n"&gt;API&lt;/span&gt; &lt;span class="o"&gt;+--------------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;+-----+-----+&lt;/span&gt;                                                  &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                   &lt;span class="o"&gt;+-----------+&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;                               &lt;span class="o"&gt;+--+&lt;/span&gt; &lt;span class="n"&gt;Extension&lt;/span&gt; &lt;span class="o"&gt;+--+&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+-----------+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+---+-+-+---+&lt;/span&gt;  &lt;span class="mi"&gt;2&lt;/span&gt;  &lt;span class="o"&gt;+--------------+&lt;/span&gt;  &lt;span class="mi"&gt;3&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;4&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;Agent&lt;/span&gt;   &lt;span class="o"&gt;+-----+&lt;/span&gt; &lt;span class="n"&gt;Ext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;manager&lt;/span&gt; &lt;span class="o"&gt;+-----+--+&lt;/span&gt;   &lt;span class="o"&gt;....&lt;/span&gt;    &lt;span class="o"&gt;+--+-----+&lt;/span&gt;
&lt;span class="o"&gt;+-----------+&lt;/span&gt;     &lt;span class="o"&gt;+--------------+&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
                                       &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+-----------+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
                                       &lt;span class="o"&gt;+--+&lt;/span&gt; &lt;span class="n"&gt;Extension&lt;/span&gt; &lt;span class="o"&gt;+--+&lt;/span&gt;
                                          &lt;span class="o"&gt;+-----------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Interactions with the agent API object are in the following order:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;#1 the agent initializes the agent API object (bridges, other internal state)&lt;/span&gt;
&lt;span class="c1"&gt;#2 the agent passes the agent API object into the extension manager&lt;/span&gt;
&lt;span class="c1"&gt;#3 the manager passes the agent API object into each extension&lt;/span&gt;
&lt;span class="c1"&gt;#4 an extension calls the new agent API object method to receive bridge wrappers with cookies allocated.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Call #4 also registers allocated cookies with the agent bridge objects.&lt;/p&gt;
&lt;p&gt;Note: the proposal does not cover major flow table rework suggested in the
corresponding &lt;a class="reference internal" href="#openstack-dev-mailing-thread"&gt;openstack-dev@ mailing thread&lt;/a&gt;. Instead, a simpler approach is
chosen for Mitaka, so that we unblock features interested in setting custom
flows, and work on table management part of the mailing list proposal on our
pace.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Ihar Hrachyshka (ihrachys)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;David Shaughnessy (davidsha)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;span class="target" id="l2-agent-extensions"&gt;L2 agent extensions&lt;/span&gt;: &lt;a class="reference external" href="https://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/agent_extension.py?id=b01e3084d135492850384f7732763ad40a1bbc0b"&gt;https://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/agent_extension.py?id=b01e3084d135492850384f7732763ad40a1bbc0b&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span class="target" id="l2-agent-extension-manager"&gt;L2 agent extension manager&lt;/span&gt;: &lt;a class="reference external" href="https://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/manager.py?id=b01e3084d135492850384f7732763ad40a1bbc0b"&gt;https://git.openstack.org/cgit/openstack/neutron/tree/neutron/agent/l2/extensions/manager.py?id=b01e3084d135492850384f7732763ad40a1bbc0b&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;span class="target" id="openstack-dev-mailing-thread"&gt;openstack-dev@ mailing thread&lt;/span&gt; on agent-specific API for L2 agent extensions: &lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2015-December/081264.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2015-December/081264.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 05 Jan 2016 00:00:00 </pubDate></item><item><title>Moving to Keystone v3</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/newton/moving-to-keystone-v3.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/keystone-v3"&gt;https://blueprints.launchpad.net/neutron/+spec/keystone-v3&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint is meant to capture the changes to the Neutron repos (neutron,
neutron-lib and python-neutronclient) needed to fully integrate Neutron with
the Keystone v3 API.&lt;/p&gt;
&lt;p&gt;All the steps described in this document are applicable also to repos
neutron-fwaas, neutron-lbaas, neutron-vpnaas and neutron-dynamic-routing.
However, only the changes in neutron, neutron-lib and python-neutronclient
are required to consider this blueprint completed.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The &lt;a class="reference external" href="http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3.html#what-s-new-in-version-3-0"&gt;Keystone v3 API&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id1" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; was released on February 20, 2013. In the Icehouse
release the &lt;a class="reference external" href="https://blueprints.launchpad.net/keystone/+spec/deprecate-v2-api"&gt;Keystone v2 API was deprecated&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id3" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. The deprecation had to be
&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2014-March/031016.html"&gt;reverted&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id5" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; because many OpenStack projects did not support the v3 API yet.&lt;/p&gt;
&lt;p&gt;In the Mitaka release Keystone is again &lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2015-November/080816.html"&gt;deprecating the v2 API&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id7" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. Projects will
be able to use the v2 API for the next four releases, but after that it will not
be supported. To be consistent with other OpenStack projects and to be able to
continue using the Identity Service, we must update Neutron to exclusively use
Keystone v3 when v2 is no longer supported.&lt;/p&gt;
&lt;p&gt;With the Keystone v3 API, the concept of “tenant” is deprecated in favor of
“project”. In particular, the attribute &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt; is replaced with
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt;. Neutron must initially support &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; as an alias for
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt; before finally replacing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt; altogether. Deprecation
will be kept as long as Neutron CLI will be supported.&lt;/p&gt;
&lt;p&gt;In requests &lt;strong&gt;to&lt;/strong&gt; Neutron, the neutron server already treats &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; as
an alias for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt;. Internally, Neutron should eventually replace
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt; with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; in attributes and database fields.&lt;/p&gt;
&lt;p&gt;In requests &lt;strong&gt;from&lt;/strong&gt; Neutron to other OpenStack services, the neutron components
should use keystoneauth, which abstracts the v2/v3 differences.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Change all existing uses in Neutron code from Keystone v2 to Keystone v3.
Initially both versions of API will be supported. Migration will be handled in
several steps.&lt;/p&gt;
&lt;ol class="arabic simple" start="0"&gt;
&lt;li&gt;&lt;p&gt;Update Neutron server to accept Keystone v3 contexts in requests. [DONE]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the API bindings in python-neutronclient to properly handle both
project_id and tenant_id.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update Neutron server to use only keystoneauth for requests to other
OpenStack services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update documentation about deprecation of tenant_id attribute:&lt;/p&gt;
&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;&lt;p&gt;OpenStack Networking API reference,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron and neutronclient developer references.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; alias for all &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt; columns in DB.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update codebase, changing all occurences of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant&lt;/span&gt;&lt;/code&gt; with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project&lt;/span&gt;&lt;/code&gt;,
where appropriate. Special care needs to be taken for:&lt;/p&gt;
&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;&lt;p&gt;When renaming arguments for callables, some callers may pass them using
kwargs notation (tenant_id=…) instead of positional.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When changing code that is used by external projects, the change must not
break the external project. Deprecation warnings should be set up.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="neutron-api"&gt;
&lt;h3&gt;Neutron API&lt;/h3&gt;
&lt;p&gt;The Neutron API accepts the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; attribute and treats it as an alias
for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt; attribute. This is &lt;a class="reference external" href="https://review.openstack.org/253782"&gt;already implemented&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id9" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Also, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt; is used as a filter parameter in Neutron API. It is a
requirement that this use-case will continue to work.&lt;/p&gt;
&lt;p&gt;Neutron API responses will be expanded to contain both &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt;. For now we are unable to phase out &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt; since that
would require an API version change. When &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/consolidate-extensions"&gt;microversioning&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id13" id="id14" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; is adopted for the
Neutron API the task of removing deprecated attributes can be commenced.
Meanwhile we will expose &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; through yet another API extension,
enabled by default.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="neutron-client"&gt;
&lt;h3&gt;Neutron client&lt;/h3&gt;
&lt;p&gt;For CLI commands, the Neutron client is being deprecated in favor of &lt;a class="reference external" href="http://docs.openstack.org/developer/python-neutronclient/devref/transition_to_osc.html"&gt;OpenStack
Client&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id15" id="id16" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.  Therefore the CLI portion of python-neutronclient will not be
updated.  In the OpenStack Client the CLI commands have already adopted the
policy of using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_&lt;/span&gt;&lt;/code&gt; and do not support &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The only part of python-neutronclient which will be modified is the Python API
bindings.  All the places where the bindings accept &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_name&lt;/span&gt;&lt;/code&gt; need to be expanded to also accept &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_name&lt;/span&gt;&lt;/code&gt;.  The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_&lt;/span&gt;&lt;/code&gt; parameters will be marked as deprecated and
to be removed in the future.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="openstack-documentation"&gt;
&lt;h3&gt;OpenStack documentation&lt;/h3&gt;
&lt;p&gt;Neutron client CLI is being deprecated in favor of &lt;a class="reference external" href="http://docs.openstack.org/developer/python-neutronclient/devref/transition_to_osc.html"&gt;OpenStack Client&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id15" id="id17" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, thus
the only document update regarding its behavior will contain information about
deprecation.&lt;/p&gt;
&lt;p&gt;The neutronclient Python API documentation will be updated to show
corresponding changes about bindings.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="neutron-developer-reference"&gt;
&lt;h3&gt;Neutron developer reference&lt;/h3&gt;
&lt;p&gt;The term &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant&lt;/span&gt;&lt;/code&gt; is used all across the documentation. All the places need to
be updated, with extra information about &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt; deprecation in favor of
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Additional guidelines will be provided for all subprojects/affiliated projects,
about modifications required to be consistent with Neutron API changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="database"&gt;
&lt;h3&gt;Database&lt;/h3&gt;
&lt;p&gt;Renaming columns from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt; to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; and from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_name&lt;/span&gt;&lt;/code&gt;
to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; will require downtime and will be done in a contract
migration.&lt;/p&gt;
&lt;p&gt;To allow changes in smaller chunks, and for backward compatibility, we will
temporarily use the &lt;a class="reference external" href="http://docs.sqlalchemy.org/en/rel_1_0/orm/mapped_attributes.html?highlight=synonym#synonyms"&gt;SQLAlchemy synonym feature&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id11" id="id12" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; to make &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt; a
synonym for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; columns.&lt;/p&gt;
&lt;p&gt;For some time, database operations will see &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt;
attributes separately coming up in lists of properties and such, and care will
need to be taken in how they are filtered and passed around.&lt;/p&gt;
&lt;p&gt;Once all existing columns have been renamed to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt;, all new columns
added to any Neutron code shall use only &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt;.  A hacking rule will
be added to prevent the reintroduction of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt; in source code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="internal-changes"&gt;
&lt;h3&gt;Internal changes&lt;/h3&gt;
&lt;p&gt;Server code changes will be submitted in reviewable chunks, without interruption
to the external API or external project dependencies. Client code changes are
additive until the deprecated keywords are removed.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Write tests to check responses for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project&lt;/span&gt;&lt;/code&gt; parameters, to be
sure that introduced changes are consistent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Test if &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; returns the same response as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test if &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tenant_id&lt;/span&gt;&lt;/code&gt; is updated when &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;project_id&lt;/span&gt;&lt;/code&gt; is updated.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id1" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3.html#what-s-new-in-version-3-0"&gt;http://specs.openstack.org/openstack/keystone-specs/api/v3/identity-api-v3.html#what-s-new-in-version-3-0&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/keystone/+spec/deprecate-v2-api"&gt;https://blueprints.launchpad.net/keystone/+spec/deprecate-v2-api&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2014-March/031016.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2014-March/031016.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2015-November/080816.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2015-November/080816.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id9" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id10"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/253782"&gt;https://review.openstack.org/253782&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id11" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id12"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://docs.sqlalchemy.org/en/rel_1_0/orm/mapped_attributes.html?highlight=synonym#synonyms"&gt;http://docs.sqlalchemy.org/en/rel_1_0/orm/mapped_attributes.html?highlight=synonym#synonyms&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id13" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id14"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/consolidate-extensions"&gt;https://blueprints.launchpad.net/neutron/+spec/consolidate-extensions&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id15" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id16"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id17"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/python-neutronclient/devref/transition_to_osc.html"&gt;http://docs.openstack.org/developer/python-neutronclient/devref/transition_to_osc.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Mon, 14 Dec 2015 00:00:00 </pubDate></item><item><title>Adopt Oslo Guru reports</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/adopt-oslo-guru-reports.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/guru-meditation-report"&gt;https://blueprints.launchpad.net/neutron/+spec/guru-meditation-report&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes adoption for Oslo Guru reports in Neutron. The new feature
will enhance debugging capabilities of all official Neutron services, by
providing an easy way to gather runtime data about current threads and
configuration, among other things, to developers, operators, and tech support.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently Neutron does not have a way to gather runtime data from active
service processes. The only information that is available to deployers,
developers, and tech support to analyze is what was actually logged by the
service in question. Additional data could be usefully used to debug and solve
problems that occur during Neutron operation. Among other things, we could be
interested in stack traces of all (both green and real) threads, pid/ppid info,
package version, configuration as seen by the service, etc.&lt;/p&gt;
&lt;p&gt;Oslo Guru reports provide an easy way to add support for gathering this kind of
information to any service. Report generation is triggered by sending a special
(USR1) signal to a service. Reports are generated on stderr, that can be piped
into system log, if needed.&lt;/p&gt;
&lt;p&gt;Guru reports are extensible, meaning that we will be able to add more
information to those reports in case we see it needed. For example, we could
add a new report section for L2 Open vSwitch agent to dump flows and other
relevant networking data to the report. Note that this spec does not cover any
of possible extensions and just lays the foundation for them.&lt;/p&gt;
&lt;p&gt;Guru reports are supported by Nova.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;First, a new oslo-incubator module (reports.*) should be synchronized into
neutron tree. Then, each service entry point should be extended to register
reporting functionality before proceeding to its real main(). This may be
achieved through utilizing neutron/cmd/__init__.py or a similar way that would
automatically expose the functionality to all services.&lt;/p&gt;
&lt;p&gt;After neutron core repository adopts the feature, advanced services’
repositories will be similarly updated to utilize the module.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;In theory, the change could expose service internals to someone who is able to
send the needed signal to a service. That said, we can probably assume that the
user is already authorized to achieve a lot more than just having an access to
stack traces and configuration used. Also, if deployers are afraid of the
information leak for some reason, they could also make sure their stderr output
is channeled into safe place.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The feature does not require any additional resources until it’s triggered by
the user. Default report generation is not expected to take too long. Report
extensions will need to be assessed on case by case basis. In any case, reports
are not expected to be generated too often and are assumed to be debugging
capability, not something to trigger once per minute just in case.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Deployers may be interested in making sure those reports are collected
somewhere (e.g. stderr should be captured by syslog).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We could reimplement the wheel, but we hopefully won’t.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;ihrachyshka&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;sync reports.* module from oslo-incubator&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;adopt it in all neutron services using a wrapper located under
neutron/cmd/…&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note: the feature was once proposed for inclusion but was later abandoned:
&lt;a class="reference external" href="https://review.openstack.org/#/q/project:openstack/neutron+topic:bp/guru-meditation-report,n,z"&gt;https://review.openstack.org/#/q/project:openstack/neutron+topic:bp/guru-meditation-report,n,z&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;reports.* module is currently going thru graduation consideration. In case it’s
graduated into oslo.reports library before neutron switches to it, we won’t
actually need to sync any code from oslo-incubator but instead add a new
external oslo dependency. If Neutron switches to the module before graduation
is complete, then we’ll need to adopt oslo.reports later as part of usual oslo
liaison effort.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Ideally, the feature would be tested using full stack testing framework that
was expected to enter the tree in Kilo but was postponed to Liberty. Note that
the framework is not yet reproposed for Liberty.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Documentation should be extended to describe the new feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Developer documentation should be updated to include information on how to add
support for the reporting feature. Special attention should be made on those
who implement Neutron extensions out of tree.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;oslo-incubator module: &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/oslo-incubator/tree/openstack/common/report"&gt;http://git.openstack.org/cgit/openstack/oslo-incubator/tree/openstack/common/report&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;blog about nova guru reports: &lt;a class="reference external" href="https://www.berrange.com/posts/2015/02/19/nova-and-its-use-of-olso-incubator-guru-meditation-reports/"&gt;https://www.berrange.com/posts/2015/02/19/nova-and-its-use-of-olso-incubator-guru-meditation-reports/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;oslo.reports repo: &lt;a class="reference external" href="https://github.com/directxman12/oslo.reports"&gt;https://github.com/directxman12/oslo.reports&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;full stack testing: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/integration-tests"&gt;https://blueprints.launchpad.net/neutron/+spec/integration-tests&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 09 Dec 2015 00:00:00 </pubDate></item><item><title>Network IP Availability Extension</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/network-ip-availability-api.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1457986"&gt;https://bugs.launchpad.net/neutron/+bug/1457986&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Wouldn’t it be nice if we knew when a network or one of its subnets were
nearly exhausted of IPs?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The basic need: Determining how much of a network’s or subnet’s IPs are being
consumed with respect to the total number of IPs they support. Ideally
this information would provide the following for networks as well as subnets:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;used_ips (number allocated or reserved within that subnet or network)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;total_ips (maximum total number available as defined by the subnet)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This blueprint describes a simple Neutron API extension that adds the
ability for an administrator (or monitor) to call an API that returns a
breakdown of IP availability details for each network. A monitor could then
alert cloud operators when thresholds have been crossed so they know to add
more capacity. The goal of this blueprint is to provide a simple API extension
that will get this IP availability information.&lt;/p&gt;
&lt;p&gt;Use cases:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Admin or monitor invokes API extension to get detailed information about
network IP availability. From that data, admin or monitor can act on networks
that are nearly full.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide foundation API for a future nova scheduler to filter out or weigh
compute hosts based on a host’s backing network capacity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide counts for number of IPs used within a network or subnet.
Answers the question: When a network is down, how many IPs are being
affected (applies to IPv4 and IPv6)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;We propose adding a read-only (GET) API extension that retrieves IP
availability information from existing data structures currently in OpenStack.&lt;/p&gt;
&lt;p&gt;To create this API, we plan on creating a services extension that an admin
can configure and add to their deployment. This could also be implemented
(if community so desires) permanently into the API (non-extension).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GET /v2.0/network-ip-availability&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Support for filter query parameters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;network_id (network id as a uuid)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;network_name (name of network)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ip_version (IP version either 4 or 6)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tenant_id (owning tenant as uuid)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Access: admin (via json.policy)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Read-only: &lt;strong&gt;No&lt;/strong&gt; part of this API will change or modify data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Response Data:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Network IP availability: A network_ip_availability response that contains
a list of networks (see network information)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Network information: network id, network name, tenant id, list of subnet
sections (see subnet information), number of IPs used in network, maximum
number of IPs that network could support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subnet information: subnet id, subnet name, IP version, cidr,
number of IPs used in subnet, maximum number of IPs that subnet could
support.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="id1"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;View from orbit of how things will happen for new REST API:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;API Extension created for IP availability count information&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extension queries database to fetch Allocation, AllocationPool, Subnet,
number of IPs used, and total counts IPs within each subnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extension generates and returns a response with a list of networks as well
as a nested list of subnet information in each network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implementation code changes should be restricted to stay within the
extension itself and not touch other areas of Neutron.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Python client modified to support fetching this data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI modified to support this fetching this data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other modifications deemed necessary for complete end-to-end experience.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="scope-for-initial-release"&gt;
&lt;h3&gt;Scope for initial release&lt;/h3&gt;
&lt;p&gt;Items targeting Mitaka release (subject to review/comments/changes/help)&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;(m1) Create the above working REST endpoint.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(m1) Mature and flesh out unit/integration testing new extension API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(m1) Update Neutron client to support this new API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(m?) Design and create equivalent CLI command.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(m?) Add and/or modify page(s) in Horizon to display used and total counts.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="answers-to-questions-and-concerns"&gt;
&lt;h3&gt;Answers to questions and concerns&lt;/h3&gt;
&lt;p&gt;The following are answers to questions and concerns received in the past:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This extension will support IPv4 and IPv6 as well as the ability to filter
for each.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IPv6 total IP counts will be astronomical. This is known and is a key
reason we plan to support ip_version as a query parameter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As new read-only API extension, this should not affect any known drivers,
services, routing, DHCP, agents, scheduling, quota, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Serves up existing subnet and IP allocations information as it is in Neutron
today (no outside data/structure/code changes needed to support this).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IPAM concerns: IPAllocations and IPAllocationPools are maintained up to date
on neutron side regardless of IPAM driver. Therefore IPAM driver implementers
will be free of the need to implement an abstract function to support this.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Floating IPs: Because we are targeting IPAllocations and pools, this spec
will handle floating IP networks where floating IPs are reserved (created),
but not yet associated to a fixed IP. Port counts are not able to support
this.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;RFE Bug: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1457986"&gt;https://bugs.launchpad.net/neutron/+bug/1457986&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Proof of concept code: &lt;a class="reference external" href="https://review.openstack.org/#/c/212955"&gt;https://review.openstack.org/#/c/212955&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 30 Nov 2015 00:00:00 </pubDate></item><item><title>LBaaS Layer 7 rules</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/lbaas-l7-rules.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-l7-rules"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-l7-rules&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Layer 7 switching takes its name from the OSI model, indicating that the device
switches requests based on layer 7 (application) data. Layer 7 switching is
also known as “request switching”, “application switching”, and
“content based routing”.
A layer 7 switch presents to the outside world a “virtual server” that accepts
requests on behalf of a number of servers and distributes those requests based
on policies that use application data to determine which server should service
which request. This allows for the application infrastructure to be specifically
tuned/optimized to serve specific types of content. For example, one server can
be tuned to serve only images, another for execution of server-side scripting
languages like PHP and ASP, and another for static content such as HTML, CSS and
JavaScript.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Use Cases:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Redirect traffic to a Pool that supports static content (HTML, CSS)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Redirect traffic to a Pool that serves images (jpg, png, etc)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Extend the LBaaS API and support Layer 7 switching.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;L7 Entities:&lt;/dt&gt;&lt;dd&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;L7Rule - Set of attributes that defines which part of the request should
be matched and how it should be matched.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L7Policy - A collection of L7Rules. Holds the action that should
be performed when the rules are matched.(Redirect to Pool, Redirect to URL,
Reject). L7Policy holds a Listener id, so a Listner can evaluate a collection
of L7Policies. L7Policy will return ‘true’ when all of the L7Rules that
belong to this L7Policy are matched. L7Policies under a specific Listener
are ordered and the first l7Policy that returns a match will be executed.
When none of the policies match the request gets forwarded to
listener.default_pool_id&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;Model:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+--------------------+&lt;/span&gt;        &lt;span class="o"&gt;+--------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Listener&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;L7Policy&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------------+&lt;/span&gt;        &lt;span class="o"&gt;+--------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="nb"&gt;id&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="nb"&gt;id&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="o"&gt;+--------+&lt;/span&gt;   &lt;span class="n"&gt;action&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;redirect&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;listener&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+--------------------+&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;index&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
                              &lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;
                              &lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;
                              &lt;span class="o"&gt;+-----------------+--+&lt;/span&gt;
                                                &lt;span class="o"&gt;|&lt;/span&gt;
                                                &lt;span class="o"&gt;|&lt;/span&gt;
                             &lt;span class="o"&gt;+------------------+--+&lt;/span&gt;
                             &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;L7Rule&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;
                             &lt;span class="o"&gt;+---------------------+&lt;/span&gt;
                             &lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;
                             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="nb"&gt;id&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
                             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;l7&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
                             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="nb"&gt;type&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;
                             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;compare&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
                             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;key&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;
                             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;value&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;
                             &lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;
                             &lt;span class="o"&gt;+---------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Two new entities are introduced: L7Rule and L7Policy
The L7Policy is a container of L7Rules.
The L7Policy contains a reference to a Listener&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;L7Rule object Data Model.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Field&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Null&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Key&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string(36)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;NO&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;PRI&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;l7_policy_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string(36)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;NO&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;FK&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Enum (*)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;NO&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;compare_type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Enum (*)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;NO&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;key&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string(36)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;NO&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;value&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string(36)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;YES&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;type values&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Hostname&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Path&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;FileType: This is the file extension. Examples: txt, jpg, png, xls&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;A rule that is looking for text files will look like:
type = FileType, compare_type=EqualTo, value = txt&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Header&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Cookie: This is the value of a specific cookie&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;A rule that is looking for a cookie named ‘department’
with the value starting with ‘finance-’ will look like:
type = Cookie, compare_type=StartsWith, key = department
value = finance-&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;compare_type values&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Regexp&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;StartsWith&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;EndsWith&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Contains&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;EqualTo&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GreaterThan&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LessThan&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;L7Policy object Data Model.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Field&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Null&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Key&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string(36)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;NO&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;PRI&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;listener_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string(36)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;NO&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;FK&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;action&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Enum (*)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;NO&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;pool_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string(36)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;YES&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;redirect_url&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string(256)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;YES&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;index&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;int&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;NO&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;action: [Reject,RedirectToURL,RedirectToPool]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If action is RedirectToURL redirect_url can not be null&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If action is RedirectToPool pool_id can not be null&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Index&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If total policies for this listener is less than index, append to end of
list.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Index numbering starts with 0&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If policy with same index number exists, insert the new policy at that
index number and increment all policy indexes for this listener with an
equal or higher index value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Not specifying an index appends the policy to the list.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;l7rule-create    Create a L7Rule for a given tenant.&lt;/p&gt;
&lt;p&gt;Request&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;POST /v2.0/l7rules
Accept: application/json&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"l7rule"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;"l7_policy_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"6b96ff0cb17a4b859e1e575d221683c5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Header"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;"compare_type"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"StartsWith"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'department'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"HR"&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"l7rule"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"6b96ff0cb17a4b859e1e575d221683d7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"l7_policy_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"6b96ff0cb17a4b859e1e575d221683c5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Header"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"compare_type"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"StartsWith"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'department'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"HR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"6b96ff0cb17a4b859e1e575d2216845"&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;l7rule-show    Show information of a given L7Rule.&lt;/p&gt;
&lt;p&gt;Request&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;GET /v2.0/l7rules/6b96ff0cb17a4b859e1e575d221683d7
Accept: application/json&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Response&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"l7rule"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"6b96ff0cb17a4b859e1e575d221683d7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"l7_policy_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"6b96ff0cb17a4b859e1e575d221683c5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Header"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"compare_type"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"StartsWith"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'department'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"HR"&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"6b96ff0cb17a4b859e1e575d2216845"&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;l7rule-delete    Delete a given L7Rule.&lt;/p&gt;
&lt;p&gt;Request&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;DELETE /v2.0/l7rules/6b96ff0cb17a4b859e1e575d221683d7
Accept: application/json&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;l7policy-create    Create a L7Policy for a given tenant.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;POST /v2.0/l7policies
Accept: application/json&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"l7policy"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"listener_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"6b96ff0cb17a4b859e1e575d221683c5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"action"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"RedirectToPool"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"pool_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;6&lt;/span&gt;&lt;span class="nx"&gt;b96ff0cb17a4b859e1e575d22168399&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"index"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"l7policy"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"6b96ff0cb17a4b859e1e575d221683d7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"listener_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"6b96ff0cb17a4b859e1e575d221683c5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"action"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"RedirectToPool"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"pool_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;6&lt;/span&gt;&lt;span class="nx"&gt;b96ff0cb17a4b859e1e575d22168399&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"6b96ff0cb17a4b859e1e575d2216845"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"index"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;l7policy-show    Show information of a given L7Policy.&lt;/p&gt;
&lt;p&gt;Request&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;GET /v2.0/l7policies/6b96ff0cb17a4b859e1e575d221683d7
Accept: application/json&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Response&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"l7policy"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"6b96ff0cb17a4b859e1e575d221683d7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"listener_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"6b96ff0cb17a4b859e1e575d221683c5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"action"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"RedirectToPool"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"pool_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;6&lt;/span&gt;&lt;span class="nx"&gt;b96ff0cb17a4b859e1e575d22168399&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"6b96ff0cb17a4b859e1e575d2216845"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"index"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;l7policy-delete    Delete a given L7Policy.&lt;/p&gt;
&lt;p&gt;Request&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;DELETE /v2.0/l7policies/6b96ff0cb17a4b859e1e575d221683d7
Accept: application/json&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change has been in review since Juno.  Much discussion has taken place
over IRC and the mailing list.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~avishayb"&gt;https://launchpad.net/~avishayb&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;strong&gt;TBD&lt;/strong&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;REST API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB Schema&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LBaaS plugin and driver API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI update&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Depends on the new LBaaS model &lt;a class="reference external" href="https://review.openstack.org/#/c/89903/"&gt;https://review.openstack.org/#/c/89903/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DB mixin and schema tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LBaaS Plugin with mocked driver end-to-end tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Specific driver tests for each existing driver supporting L7 switching&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;REST API and attributes validation tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron CLI should be modified with L7Rule and L7Policy entities&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron API should be modified with L7Rule and L7Policy entities&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/LBaaS/l7"&gt;https://wiki.openstack.org/wiki/Neutron/LBaaS/l7&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 28 Oct 2015 00:00:00 </pubDate></item><item><title>Neutron-Lib Decomposition</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/neutron-lib.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-lib"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-lib&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This proposal is about stabilizing some of the common interfaces used
by Neutron’s child repos, both the advanced services and decomposed plugins.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Part of the goal of splitting functionality and vendor code out of neutron
was to increase focus on core neutron, getting it stable, and increasing the
velocity of making changes. Since the services repos and decomposed
plugins/drivers are both importing and using internal neutron interfaces,
unless we run existing tests against the universe of all of this code,
it becomes difficult to re-factor or make simple changes without breaking
these newly separated projects and plugins.&lt;/p&gt;
&lt;p&gt;In addition, there is a certain amount of magic involved in the implicit
dependency that neutron is installed, because of the openstack/requirements
rules regarding global dependencies, and neutron not being on that list.
We end up having to assume neutron is present and are unable to check that
the version present is compatible.&lt;/p&gt;
&lt;p&gt;The requirements driving this change are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A set of neutron methods which are considered “stable”, and which will
not be removed or have their method signatures changed without a long-term
deprecation plan.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This is not a mechanical split.  For each module, we must determine if the
current interface is what we want to support, or if it needs to change. And
for each module, it will likely need strict interface tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;At the end of the “split” process, there is no co-gate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A library in pypi.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Addition of this library to the global requirements list.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A versioned reference to the library in various projects requirements.txt.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This proposal is to split neutron into a neutron-lib of reusable library
code and neutron core (servers, agents, plugins, drivers.) Part of creating
neutron-lib would involve creating rigid interface tests for exposed
library methods.&lt;/p&gt;
&lt;p&gt;This library will live in the new repo neutron-lib, and will be published
to pypi.&lt;/p&gt;
&lt;p&gt;This would &lt;em&gt;not&lt;/em&gt; be a mechanical split, but rather each piece of code
moved into the library would need to satisfy several criteria:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Is this a reusable module that makes sense in a general library?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does it have interface tests, or do they need to be added?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Is the current interface good for a library, or does it need to be
re-factored?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some trivial items, like the exceptions module, can move over directly
as part of this blueprint, however even trivial code that is not shared by
anyone should not move.  Most modules with any complexity at all will
require separate blueprints and careful consideration.&lt;/p&gt;
&lt;p&gt;This blueprint can be considered complete when:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A neutron-lib repo with testing framework and Jenkins exists.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A stable version of neutron-lib has been released to pypi.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron, neutron-lbaas, neutron-fwaas, neutron-vpnaas depend on neutron-lib
via requirements.txt, and NONE OF THEM IMPORT EACH OTHER.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Api and functional tests are fully separate between the above four repos.
In other words, there is NO co-gate, and interface breakages are enforced
via tests in neutron-lib.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests will no longer share code between repos. Unit test base classes will
be repo specific, initially likely dup’ed, and diverge on their own.
Any root functionality that the base classes require from neutron will
be a candidate for inclusion in neutron-lib or re-factoring.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/neutron-lib-decomposition"&gt;https://etherpad.openstack.org/p/neutron-lib-decomposition&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron project repos
- &lt;a class="reference external" href="https://github.com/openstack/governance/blob/master/reference/projects.yaml#L81"&gt;https://github.com/openstack/governance/blob/master/reference/projects.yaml#L81&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest-lib:
- &lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/tempest-library"&gt;https://blueprints.launchpad.net/tempest/+spec/tempest-library&lt;/a&gt;
- &lt;a class="reference external" href="https://github.com/openstack/tempest-lib"&gt;https://github.com/openstack/tempest-lib&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cinder:
- &lt;a class="reference external" href="https://review.openstack.org/#/c/153673/"&gt;https://review.openstack.org/#/c/153673/&lt;/a&gt;
- &lt;a class="reference external" href="https://github.com/openstack/os-brick"&gt;https://github.com/openstack/os-brick&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ironic-lib:
- &lt;a class="reference external" href="https://review.openstack.org/#/c/157757/"&gt;https://review.openstack.org/#/c/157757/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Depends-On:
- &lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2015-February/056515.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2015-February/056515.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 28 Oct 2015 00:00:00 </pubDate></item><item><title>Example Spec - The title of your blueprint</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/reorganize-unit-test-tree.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/reorganize-unit-test-tree"&gt;https://blueprints.launchpad.net/neutron/+spec/reorganize-unit-test-tree&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Reorganize the structure of the unit test tree to be consistent with
the structure of the code tree.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;There is no consistent organization of unit test modules
(neutron/test/unit/*).  There is no easy way to find the unit tests
for a given module, making it challenging to determine whether code is
well-tested.  There are also no clear guideline as to where new tests
should go, ensuring that the problem continues.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The module structure of the neutron/tests/unit subtree should be
changed to mirror the structure of the code tree.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The path structure should be the same.  This implies that modules
under the path:&lt;/p&gt;
&lt;p&gt;neutron/[path]&lt;/p&gt;
&lt;p&gt;should have test modules in the following location&lt;/p&gt;
&lt;p&gt;neutron/tests/unit/[path]&lt;/p&gt;
&lt;p&gt;For example, test modules for ‘neutron/scheduler’ should have tests
at ‘neutron/tests/unit/scheduler’.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The name of the test modules should correspond to the name of the
module under test, prefixed with ‘test_’.  For example, the module
‘neutron/scheduler/dhcp_agent_scheduler.py’ implies the test module
‘neutron/tests/unit/scheduler/test_dhcp_agent_scheduler.py’.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;This requirement should be documented such that new changes follow
this scheme.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Patch authors and reviewers will need to ensure that new changes
maintain the consistent structuring of the unit test tree.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;marun&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Reorganize the test tree&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;The required structure of the unit test tree should be documented in the in-tree developer documentation.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://pytest.org/latest/goodpractises.html"&gt;https://pytest.org/latest/goodpractises.html&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Oct 2015 00:00:00 </pubDate></item><item><title>ARP spoofing filtering via ebtables</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/arp-spoof-filtering-ebtables.html</link><description>

&lt;p&gt;This issue allows ARP cache poisoning attacks to be started from a guest
VM to other VMs in the same network. This is a security issue, especially
on shared networks.&lt;/p&gt;
&lt;p&gt;This blueprint suggest that we utilize the ebtables tool to configure
Ethernet-frame-level filtering, which prevents these spoofing packets
to be sent by a VM.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;With an ARP cache poisoning attack a device in the local network can
impersonate someone else. Specifically, a device can claim ownership of an IP
address, which it does not actually have.&lt;/p&gt;
&lt;p&gt;The attacker sends out a gratuituous ARP response, in which their network
interface (identified by MAC address) claims to be configured with a certain
IP address. However, this might be someone else’s IP address. Other devices in
the network update their ARP cache with the spoofed entry and will put the
attacking device’s MAC address as the destination address of frames that are
to be sent to the attacked IP address.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;We propose to add an ‘ebtables manager’, which knows how to utilize the
ebtables utility. This utility can be used to create Ethernet frame level
filtering rules.&lt;/p&gt;
&lt;p&gt;Whenever a port for a VM is created or deleted, we use the ebtables manager to
update ebtables rules, which prevent the sending of spoofed ARP packets
through this port.&lt;/p&gt;
&lt;p&gt;Please note that the ebtables manager code is largely based on the work of
Édouard Thuleau, who had submitted a patch (see ‘references’ section below).&lt;/p&gt;
&lt;p&gt;This patch, however, did not make it into the release and was abandoned. We
are now resurrecting much of this patch.&lt;/p&gt;
&lt;p&gt;An updated version of this patch was submitted for Juno, but was rejected for
various reasons.&lt;/p&gt;
&lt;p&gt;The existing patch replaced some of the iptables-based filtering with new
ebtables filters. Therefore, it changed quite a bit of the existing code in
iptables_firewall.py. This was not appreciated, since this code was seen as
brittle and in need of a re-write.&lt;/p&gt;
&lt;p&gt;Therefore, we are now proposing that the changes to iptables code are kept to
a minimum. We merely need to add a few small hooks in the iptables code, so
that the ebtables manager code is invoked when a port is created or deleted.
The ARP spoofing related rules are the same as in the previous patch, however
none of the unrelated rules introduced by the previous patch are contained in
this patch.&lt;/p&gt;
&lt;p&gt;If at some later time the iptables code is going to be re-written, any hooks
to the ebtables code can easily be ported over.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;The ebtables manager code is run with the same privileges as the iptables code
(root-wrap).&lt;/p&gt;
&lt;p&gt;It improves security of VMs on shared networks.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The new code will be called whenever a VM port is created or deleted. The
impact of calling the ebtables code is similar to the impact of the iptables
code. It will be called in addition to the iptables code and does not replace
it. The ebtables code is only touched when a port is created or deleted, no
other time.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;Not applicable.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;The ‘ebtables’ utility needs to be installed. This is normally available in
various standard packages. On Debian, for example, it’s installed like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;# apt-get install ebtables&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;p&gt;In fact, the proposed patch is designed to have as little impact as possible.
The existing code isn’t changed and both the iptables and ebtables code can be
independently refactored without impacting each other.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;?&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;It seems that iptables isn’t capable of performing such filtering and
therefore can’t be used for this.&lt;/p&gt;
&lt;p&gt;Another alternative is to do nothing: This is only an issue on shared
networks. That’s a business decision, though, and it seems some people are
quite eager to have this patch.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Juergen Brendel (&lt;a class="reference external" href="mailto:jbrendel%40cisco.com"&gt;jbrendel&lt;span&gt;@&lt;/span&gt;cisco&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement the ebtables code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement the code that uses the ebtables manager to create the spoofing
related rules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integrate code with iptables: Add the small hooks into the iptables-firewall
code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All sorts of tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The ebtables utility needs to be installed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Not sure yet.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Funtional tests to show that the iptables and ebtables code work together
properly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The need for ebtables may be listed somewhere as a requirement.&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Original patch by Édouard Thuleau: &lt;a class="reference external" href="https://review.openstack.org/#/c/70067/"&gt;https://review.openstack.org/#/c/70067/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Launchpad blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/arp-spoof-patch-ebtables"&gt;https://blueprints.launchpad.net/neutron/+spec/arp-spoof-patch-ebtables&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Original bug report: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1274034"&gt;https://bugs.launchpad.net/neutron/+bug/1274034&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Oct 2015 00:00:00 </pubDate></item><item><title>Reliable quota enforcement</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/better-quotas.html</link><description>

&lt;p&gt;Launchpad: &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/better-quotas"&gt;https://blueprints.launchpad.net/neutron/+spec/better-quotas&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Enforce network resource quotas in a reliable and efficient way, without
changing the quota API interface.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Quotas enforcement is a relatively simple task. When a request for creating
one or more resources is received, the available resource quota is checked,
and if the request cannot be satisfied an error is returned to the user.
This works perfectly under the assumption that API requests are served
serially.&lt;/p&gt;
&lt;p&gt;Unfortunately, this assumption is not true when multiple REST API workers are
employed. The same applies also if there is a single API worker, but multiple
API servers are operating behind a load balancer.&lt;/p&gt;
&lt;p&gt;In these conditions, two or more concurrent requests can pass quota
enforcement even if there is not enough quota available to accept all of them.&lt;/p&gt;
&lt;p&gt;For instance, assume there are 2 REST API workers and the current quota usage
is Nmax - 1 where Nmax is the resource quota.
Two requests are then sent and dispatched to the workers.
Each worker enforces the quota before the other worker completes processing
the API request.
Both requests are accepted, leading to a overall resource usage of Nmax + 1&lt;/p&gt;
&lt;p&gt;Therefore, leveraging multiple workers and bulk creates, a tenant could in
theory create up to Nmax * Nworkers resources. While this is unlikely to
happen, there is still a good chance that tenants could manage to use more
resources then those they’ve been assigned by the cloud provider.
This situation is far from ideal both for the cloud provider and the user, as
the former might end up in a situation where data center resources are
oversubscribed, whereas the latter could be billed more than expected.&lt;/p&gt;
&lt;p&gt;For RPC API workers instead, quotas are not enforced at all.
This implies that quotas are not enforced for resources created via RPC,
usually “internal” ports. While not enforcing quotas for service ports such
as DHCP ports might be a desired thing, this is probably not the correct
behavior. Indeed these ports will still contribute to the overall usage upon
enforcement for REST API requests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Add a concept of ‘resource reservation’, which is already adopted in other
projects such as nova and cinder.
Whenever a quota enforcement check is successful, mark the requested amount of
resources as ‘reserved’ immediately.&lt;/p&gt;
&lt;p&gt;The reservation shall be removed as soon as the corresponding API operation is
completed, successfully or not. This will be ideally done upon return from the
plugin call. In case of server crashes, an expiration time should be provided
to ensure stale reservations do not prevent allocation of resources upon server
restarts.&lt;/p&gt;
&lt;p&gt;Multiple reservations can exist at anytime for the same tenant and the same
resource. The quota check should add all the existing reservations to the
current usage count.&lt;/p&gt;
&lt;p&gt;Even with reservations, there still is a race condition which can occur if a
worker performs the quota check before the others specify their reservations.
This can be forced using lock-free algorithms which retry an operation if there
are not the conditions to perform it.
DB integrity constraints can be used to this aim, without recurring to locking
queries or other distributed synchronization constructs.&lt;/p&gt;
&lt;p&gt;This can be achieved by introducing a table with the only purpose of keeping
track of reservations in progress.&lt;/p&gt;
&lt;p&gt;The resource reservation process will therefore look as it follows:&lt;/p&gt;
&lt;p&gt;1) ACQUIRE RESERVATION FACILITY
Write down in an appropriate DB table, say reservation_locks, that a given worker
is attempting to reserve a certain amount of a given resource for some tenant.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;—————————————&lt;/em&gt;————*
| RESOURCE_TYPE | TENANT_ID | LOCKED_BY | EXPIRATION |  PK: RESOURCE_TYPE,
&lt;em&gt;—————|———–|———–&lt;/em&gt;————*      TENANT_ID
| network       | xxx       | worker_0  | some time  |
&lt;em&gt;—————————————&lt;/em&gt;————*&lt;/p&gt;
&lt;p&gt;The selected primary key ensures that it won’t be possible for two distinct
workers to attempt to concurrently reserve the same resource. The expiration
time stamp ensures stale locks are ignored in case of server failures.&lt;/p&gt;
&lt;p&gt;2) COMMIT TRANSACTION.
This will trigger an integrity violation error if another worker attempts to
make another reservation for the same tenant and resource type.&lt;/p&gt;
&lt;p&gt;In this case, step 1 will be tried again for a few times. There will be an
exponential backoff time between attempts.&lt;/p&gt;
&lt;ol class="arabic simple" start="3"&gt;
&lt;li&gt;&lt;p&gt;DO RESERVATION&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Record the reservation in an appropriate table&lt;/p&gt;
&lt;p&gt;&lt;em&gt;——————————————–&lt;/em&gt;—————-*
| RESOURCE_TYPE | TENANT_ID | BOOKING_AMOUNT |   EXPIRATION   |
&lt;em&gt;—————|———–|—————-&lt;/em&gt;—————-*
| network       | xxx       | 2              | at some point  |
&lt;em&gt;——————————————–&lt;/em&gt;—————-*&lt;/p&gt;
&lt;ol class="arabic simple" start="4"&gt;
&lt;li&gt;&lt;p&gt;RELEASE RESERVATION FACILITY&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;COMMIT TRANSACTION&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;p&gt;worker 0                           worker 1
———-                         ———-
acquire_resv_facility              acquire_resv_facility
COMMIT - SUCCESS                   COMMIT - FAIL (INTEGRITY VIOLATION)
do_reservation                     RETRY
release_resv_facility              COMMIT - FAIL (INTEGRITY VIOLATION)
COMMIT - SUCCESS                   RETRY
-                                  do_reservation
-                                  COMMIT - SUCCESS
-                                  release_resv_facility
-                                  COMMIT - SUCCESS&lt;/p&gt;
&lt;p&gt;The table for acquiring the reservation facility acts as a centralized lock,
leveraging only primary keys, which are correctly enforced even in
active/active clusters such as MySql Galera.
The algorithm should however be regarded as non-blocking since workers will
always actively retry to perform the reservation; furthermore the backoff
mechanism should prevent starvation.&lt;/p&gt;
&lt;p&gt;It is also worth noting that the proposed expiration timestamps will prevent
stale records from preventing acquiring the reservation facility or create
‘ghost’ resource reservation. The expiration timeout might be configurable,
but a default of at least two minutes is advisable considering that the
current neutron implementation still suffers of DB deadlocks triggered by
eventlet, which with the default MySql setting block threads for about 50
seconds.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;This document proposes two new tables:&lt;/p&gt;
&lt;p&gt;Table name: bookings
Attributes:
resource_type  string
tenant_id      string
booking_amount integer
expiration     datetime&lt;/p&gt;
&lt;p&gt;Table name: booking_locks
resource_type string
tenant_id     string
locked_by     string
expiration    datetime&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;No impact on the API interface.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;The proposed change should not open any vulnerability which could lead to
DoS, leaking tenant information, or allowing attackers to plug into
other tenant’s networks.&lt;/p&gt;
&lt;p&gt;All the DB queries performed in the implementation of this specification
will be scoped by tenant, and built in a way to prevent SQL injection.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Some additional DB operations will be performed upon quota enforcement.&lt;/p&gt;
&lt;p&gt;This change might also serialize some operations which were previously
processed in parallel by distinct workers.&lt;/p&gt;
&lt;p&gt;While the overall performance impact is expected to be negligible, it will be
important to evaluate it upon code review.&lt;/p&gt;
&lt;p&gt;There is also an interesting question pertaining resource usage. It is
indeed worth exploring whether it is better to count it every time or updating
their usage counter whenever resources are created or deleted.
To this aim, the cost of SELECT queries vs the cost of adding db hooks on
resource create/delete and performing the corresponding UPDATE query should be
carefully compared.
The gain/loss in terms of performance depends on relative frequency of GET
operations vs POST/DELETE operations. Update is definitely more expensive,
but SELECT are way more frequent. However, it should be possible to implement
this specification leaving resource usage calculation unchanged, and then
perhaps come back to it in the future.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;As service ports are not anymore counted in resource usage, deployers might
expect in theory an increase in port usage. This increase should however be
contained if one considers ports are typically used with instances, and the
enforcement criteria for instances are not being altered by this specification.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;The implementation for this specification will come with adequate developer
documentation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None, I don’t think so… But one can never know.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;One alternative worth considering is to us a single table for managing
bookings.
While the tuple (resource_type, tenant_id, resource_amount) cannot be
reliably used as a primary key for serializing bookings among workers,
the “locked_by” attribute can be added to this table and the following
tuple can constitute the primary key:&lt;/p&gt;
&lt;p&gt;(resource_type, tenant_id, locked_by)&lt;/p&gt;
&lt;p&gt;When committing the booking the locked_by value would be erased and this
will allow other workers to make their booking.&lt;/p&gt;
&lt;p&gt;Nevertheless, this solution does not appear to bring benefits in terms
of performance and scalability, and also makes the code less readable.&lt;/p&gt;
&lt;p&gt;Even if it would be possible to use locking queries (e.g.: SELECT ..
FOR UPDATE) statements, this solution has already proved not ideal, and will
also miserably fail with some DB backends if active/active replication is
employed.&lt;/p&gt;
&lt;p&gt;Moreover, an alternative non-blocking algorithms could have been constructed
along the lines of the one proposed for Nova &lt;a class="footnote-reference brackets" href="#id4" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. That algorithm has the
advantage of performing on average 1 DB transaction instead of 2 for each
quota enforcement operation, so it is therefore more efficient.
On the other hand, the cost of a retry operation in case of conflict would
be slightly higher. While the latter details is not really important, this
alternative algorithm cannot be applied to Neutron as it does not have
resource usage counters; without them the implementation of this alternative
lock free algorithm would be rather difficult.&lt;/p&gt;
&lt;p&gt;Another alternative would consist in a separate quota granting authority.
This is a possibility, and that is what the ‘Blazar’ &lt;a class="footnote-reference brackets" href="#id5" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;  resource
reservation project advocates for, but might result in an overkill for many
OpenStack deployments. Moreover, while in theory it is possible to use
Blazar to this aim, the project has actually been conceived to book resources
which are meant to be time-shared across tenants.
On the other hand the ‘Boson’ &lt;a class="footnote-reference brackets" href="#id6" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; project might represent a more viable
alternative were quota management and enforcement are delegate to a 3rd
application. While this project is very interesting, its not yet in a
developments stage such that it can be considered for adoption by Neutron.&lt;/p&gt;
&lt;p&gt;Finally, this problem can also be solved by introducing a distributed lock
among API workers. memcached or zookeeper could be used with relative
ease to implement this sort of distributed coordination.
Nevertheless, there is probably no need to resort to distributed
coordination if a lock-free algorithm can be devised just leveraging DB
integrity.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;salv-orlando&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Preliminary yak shaving - refactor existing quota module&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add resource booking logic and use them in quota enforcement&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove service ports from quota enforcement&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;The big dependencies for this change could be the following:
1) removal of self-grown WSGI framework and subsequent switch to pecan
2) review of the plugin interface.&lt;/p&gt;
&lt;p&gt;While the above work items pretty define new hooks for performing quota
enforcement, they won’t change the logic of the quota enforcement module,
which can therefore be implemented orthogonally.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None. This specification does not change the API interface nor any change
which might have an impact on the integrated gate.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Appropriate functional tests will be added to validate correct quota
enforcement. As a proper verification will require triggering the race
condition, some sort of fault injection might be needed. The need and
feasibility of this will be evaluated separately.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;No further API test is needed.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Document that service ports won’t count anymore in the overall
resource usage.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;As there is currently no developer documentation for quotas, this is rather
easy: “do developer documentation for the quota enforcement module”&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Nova lock-free quotas: &lt;a class="reference external" href="https://review.openstack.org/#/c/135296"&gt;https://review.openstack.org/#/c/135296&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Blazar project: &lt;a class="reference external" href="https://wiki.openstack.org/wiki/Blazar"&gt;https://wiki.openstack.org/wiki/Blazar&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Boson project: &lt;a class="reference external" href="https://wiki.openstack.org/wiki/Boson"&gt;https://wiki.openstack.org/wiki/Boson&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Oct 2015 00:00:00 </pubDate></item><item><title>Neutron/Full-Stack White-Box Tests Framework</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/full-stack-white-box-tests.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/integration-tests"&gt;https://blueprints.launchpad.net/neutron/+spec/integration-tests&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;This blueprint specifies the framework needed to write new full-stack tests
targeting Neutron components (as opposed to tests which validate integration
among different OpenStack components). These tests are intended to be
white-box - they will validate Neutron’s functionality, mainly on the operating
system level.&lt;/p&gt;
&lt;p&gt;In other words, full-stack tests intend to test Neutron on its own, without
any other OpenStack components, and fall between functional and Tempest
tests.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently there are 3 main types of tests for Neutron:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests, which intend to check the code mostly at the function level
where each function is tested separately. For example: make sure that
function X returns value Y when the arguments are A, B and C.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functional tests, which target only single sub-components and intend to
validate interaction with external (system or host-local) resources
(mostly operating system interactions and outside packages like Open-vSwitch
and iproute2…) An example functional test could look like:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;test_router_lifecycle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""Create a router and check that the agent creates various resources.&lt;/span&gt;

&lt;span class="sd"&gt;    self.agent is an instance of type L3NATAgent (the main class in the L3&lt;/span&gt;
&lt;span class="sd"&gt;    Agent) and is created as part of the test. The assertions make sure that&lt;/span&gt;
&lt;span class="sd"&gt;    various OS resources (like interfaces, namespaces, processes) are created&lt;/span&gt;
&lt;span class="sd"&gt;    as part of the creation of a new router.&lt;/span&gt;
&lt;span class="sd"&gt;    """&lt;/span&gt;
    &lt;span class="n"&gt;router_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;generate_router_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;enable_ha&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;manage_router&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;router_info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_namespace_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_metadata_proxy_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_assert_internal_devices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_assert_external_device&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_assert_gateway&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_assert_floating_ips&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_assert_snat_chains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_assert_floating_ip_chains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_delete_router&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_assert_router_does_not_exist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ol class="arabic simple" start="3"&gt;
&lt;li&gt;&lt;p&gt;Tempest tests, which check that OpenStack as a whole and Neutron in
particular behave as intended. Tempest tests are split to 2 groups:&lt;/p&gt;
&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;&lt;p&gt;Scenario tests (start a new instance and make sure that the instance has
connectivity to the external network). These tests often intend to check
more than one component at a time (as opposed to full-stack tests
discussed here, which check only Neutron).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API tests (create a new router, make sure that the controller is aware of
it and delete it).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There is currently no way to check Neutron as a standalone project and the
interaction between the different Neutron components without other OpenStack
components such as Nova or Cinder.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The framework will be written in the Neutron tree, thus allowing for easier
writing of new tests (as opposed to out-of-tree Tempest tests), being aware of
Neutron resources used during tests (executing Neutron agents and cleaning up
used resources), and running specific Neutron tests intended to check the
interaction between the different Neutron components.&lt;/p&gt;
&lt;p&gt;The framework intends to achieve state isolation, achieved through reseting the
state of Neutron components and restarting Neutron agents when needed (Tempest
currently does this manually - routers created during tests needs to be
explicitly deleted afterwards).&lt;/p&gt;
&lt;p&gt;Currently the intention is to reset said state after each full-stack test, but
this can be easily changed (we might want to do so after each test suite
instead) once enough tests are added to the framework which will allow reliable
benchmarking.&lt;/p&gt;
&lt;p&gt;The framework will support:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Writing full-stack tests using the unittest module,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restarting all the Neutron processes which are needed (neutron-server,
L3 agent, etc…) using setUp and cleanUp when appropriate,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wiping the databases and cleaning up resources (specifically running
neutron-ovs-cleanup and neutron-netns-cleanup),&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using only python-neutronclient to communicate with Neutron.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;test_ha_router_startup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""Create an HA router for two agents and make sure they can communicate.&lt;/span&gt;

&lt;span class="sd"&gt;    While this full-stack test look similar to 'test_router_lifecycle', it&lt;/span&gt;
&lt;span class="sd"&gt;    relies on the Neutron API (python-neutronclient) to create a new router&lt;/span&gt;
&lt;span class="sd"&gt;    and actual processes (one neutron-server, 2 pairs of L3 and OVS agents),&lt;/span&gt;
&lt;span class="sd"&gt;    meaning that once a request is made, it goes through all relevant agents&lt;/span&gt;
&lt;span class="sd"&gt;    and components (instead of a single sub-component). OS resources are also&lt;/span&gt;
&lt;span class="sd"&gt;    checked in this test.&lt;/span&gt;
&lt;span class="sd"&gt;    """&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;test_ha_router_startup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
      &lt;span class="n"&gt;l3_agents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'neutron-l3-1-agent'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'neutron-l3-2-agent'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

      &lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_router&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'router'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'router-test'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;uuidutils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;generate_uuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                           &lt;span class="s1"&gt;'ha'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;}})&lt;/span&gt;
      &lt;span class="n"&gt;router_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'router'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

      &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_assert_namespaces_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;l3_agents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;slave&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_get_master_and_slave&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;l3_agents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="c1"&gt;# Only if the two agents can ping each other will the other router&lt;/span&gt;
      &lt;span class="c1"&gt;# change itself to be the backup router.&lt;/span&gt;
      &lt;span class="n"&gt;test_daemon&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wait_until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'backup'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_get_ha_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;router_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;slave&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Running full-stack tests will require one to setup devstack and stop all the
services (‘./stack.sh’, ‘./unstack.sh’), then using tox to run the tests.
Further steps might be needed down the line to setup databases and other
resources, but an attempt to minimize the steps required to run the tests will
be taken over time.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;Users will be able to manually execute full-stack tests using normal tools
(such as tox), though admins and cloud users don’t need to run these tests
after deployment.&lt;/p&gt;
&lt;p&gt;No changes to python-neutronclient are needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Writing new features might require writing full-stack tests for them, as well
as unit and function tests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;Running full-stack tests will be available to run, similarly to current unit
and functional tests, and will increase the level of credibility and
reliability of new and existing Neutron features (both upstream and
downstream).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Writing these kind of tests could be done in Tempest, however this approach was
not chosen for several reasons:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The direction of the QA effort in OpenStack precludes performing these kind
of tests in Tempest since it is refocusing on multi-service testing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Full-stack tests allow for greater flexibility when developers write new
Neutron code. Tempest policy dictates that only API tests are used with the
various components, thus disallowing checks which involve system interaction
and limiting tests of some of the features mentioned previously. Since the
tests will be placed in-tree, the policy regarding new tests will be easier
to determine.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;With this new type of testing we could test specific conditions (like
consistency and sustained connectivity across agent restarts), which is
impossible at this moment with Tempest.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;John Schwarz &amp;lt;&lt;a class="reference external" href="mailto:jschwarz%40redhat.com"&gt;jschwarz&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Assaf Muller &amp;lt;&lt;a class="reference external" href="mailto:amuller%40redhat.com"&gt;amuller&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maru Newby &amp;lt;&lt;a class="reference external" href="mailto:marun%40redhat.com"&gt;marun&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Add ability to manage daemonized Neutron processes,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement supporting full-stack white-box testing framework,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add an example of a full-stack test.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/124136/"&gt;https://review.openstack.org/#/c/124136/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/125109/"&gt;https://review.openstack.org/#/c/125109/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The ultimate goal is having these new kinds of full-stack tests be run as part
of the gate - coders will have to verify that their code passes specific
‘full-stack white-box tests’ gate job in order to get their patches merged.&lt;/p&gt;
&lt;p&gt;Furthermore, changes to the infra project will be required to add these kind of
tests to the gate (first as a non-voting and later as a voting gate job).&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;The following wiki page contains documentations and “best practices” regarding
in-tree tests and full-stack tests specifically. Before writing new
tests, a developer should read the following wiki page:
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/InTreeTests"&gt;https://wiki.openstack.org/wiki/Neutron/InTreeTests&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;TESTING.rst should be updated to reflect the new tests framework.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 22 Oct 2015 00:00:00 </pubDate></item><item><title>Address Scopes</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/address-scopes.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/address-scopes"&gt;https://blueprints.launchpad.net/neutron/+spec/address-scopes&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let’s make address scopes a first class thing in Neutron.  With all of the
overlapping and arbitrary use of the both IPv4 and IPv6 addresses it is
impossible for Neutron to know what can be routed where.  Address scopes will
be used by Neutron to address this problem.&lt;/p&gt;
&lt;p&gt;This proposal has no relation to RFC 4007 IPv6 address scopes &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://tools.ietf.org/html/rfc4007"&gt;https://tools.ietf.org/html/rfc4007&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Neutron allows tenants to bring their own addresses and allows overlapping IP
addresses on any networks.  Before subnet pools, a subnet could be created with
any cidr the user wanted to supply.  It didn’t matter if the address overlapped
with another subnet in the same project or another project.  Neutron provides
isolation at the L2 level to ensure this can work.&lt;/p&gt;
&lt;p&gt;Subnet Pools &lt;a class="footnote-reference brackets" href="#id4" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; added in Kilo are a step in the right direction.  They add
overlap protection and allow an admin to define a pool of addresses from which
subnets can be allocated by multiple projects.  Now we can coordinate
addresses.  This is good.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/subnet-allocation"&gt;https://blueprints.launchpad.net/neutron/+spec/subnet-allocation&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;p&gt;Neutron L3 provides a limited routing solution to isolate between projects.  As
long as routers only connect one project’s internal networks, floating ips will
work it out between projects.  This can only go so far.&lt;/p&gt;
&lt;p&gt;With IPv6, we want to forget floating IPs and route straight in to tenant
networks.  We can’t just turn on routing assuming that everything will just
work.  How can we tell the difference between a valid, unique, and routable
subnet and one that someone just made up while filling out the subnet create
details?  Even with IPv4, some clouds in small to medium size organizations may
want to just dispense with floating IPs and use some private addressing
directly.&lt;/p&gt;
&lt;p&gt;Also, a full integration of MPLS/BGP VPN in to Neutron can benefit from this
down the road.  An analog to address scopes in the L3 VPN world are route
distinguishers.  With the addition of address scopes, we can easily map to
route distinguishers.  How address scopes relate to route distinguishers and
the somewhat related route targets is out of scope for this blueprint.  Other
blueprints like this one &lt;a class="footnote-reference brackets" href="#id6" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; will address this more completely.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/prefix-clashing-issue-with-dynamic-routing-protocol"&gt;https://blueprints.launchpad.net/neutron/+spec/prefix-clashing-issue-with-dynamic-routing-protocol&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Add a new object called AddressScope.  An AddressScope can be associated with
multiple SubnetPool objects in a one-to-many relationship.  This will allow
delegating parts of an address scope to different tenants.  The SubnetPools
under an AddressScope must not overlap.  They must also be from the same
address family.  Only an admin can associate an AddressScope and SubnetPool
from different tenants.  Once a subnet pool has been associated, it can only be
updated by the address scope owner.  If this owner is not the subnet pool owner
then it must be an admin.&lt;/p&gt;
&lt;p&gt;A SubnetPool which is not associated with an AddressScope will be treated the
same as subnets which were not created from any pool from an address scope
point of view.  The reason for this is to preserve the behavior introduced in
Kilo where address scopes do not exist.&lt;/p&gt;
&lt;p&gt;In the reference implementation of the L3 plugin, Neutron routers will be aware
of address scopes.  It will use multiple routing tables and policy routing –
features found in Linux and managed by iproute2 – to implement connecting to
networks with different address scopes.  The incoming device (iif) will be
specified with each rule.&lt;/p&gt;
&lt;p&gt;Subnets on a network will be constrained to the same subnet pool &lt;a class="footnote-reference brackets" href="#id8" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.  Even if
there are multiple pools in a scope, a network will be constrained to only one
pool per address family.  This work has already been completed and backported
to Kilo.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1451559"&gt;https://bugs.launchpad.net/neutron/+bug/1451559&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;p&gt;NAT will be automatically included between an internal network and an
“external” network to which a router is connected as a gateway &lt;em&gt;unless&lt;/em&gt; the two
networks have subnets from subnet pools in the same address scope.  It will
provide 1-1 NAT for floating IPs and many-1 for default SNAT just like today.
This will support existing use cases.  We don’t intend to implement any more
NAT use cases than this at this time.  An addition (post-Liberty) may be a more
general ipv4 NAT functionality but we want to gauge the demand for that and
explore other options too, like providing something as part of LBaaS or
something like that.&lt;/p&gt;
&lt;img alt="../../_images/address-scopes.png" src="../../_images/address-scopes.png"/&gt;
&lt;p&gt;Routers will route between networks of the same scope without NAT.  For
example, if a tenant has a subnet pool and the admin includes that subnet pool
in the same address scope as the external network then that tenant’s subnets
will be routed directly to the external network.&lt;/p&gt;
&lt;p&gt;You might be wondering here if a tenant could add any addresses he desires to
the subnet pool after the admin linked it to a scope.  Once a subnet pool has
been associated with an address pool, only the owner of the address scope will
be able to update the pool.&lt;/p&gt;
&lt;p&gt;BGP dynamic routing will use the concept of address scopes.  It will attach
metadata in order to know how to advertise routes in the address scopes.  That
will be worked out as part of late work on the BGP spec &lt;a class="footnote-reference brackets" href="#id10" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/125401/"&gt;https://review.openstack.org/#/c/125401/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Adds a new table for address scopes.  It will have a name and an id.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adds a new field (default null) to the SubnetPool referencing a single
AddressScope.  This will be updatable.  On update, the subnet pool will be
checked for address uniqueness with other subnet pools under the scope.
Also, routers must be notified of the change in order to adjust routing.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Basically, we add CRUD semantics for the new address scope object.&lt;/p&gt;
&lt;p&gt;We need API to associate address scopes with subnet pools.  This will be done
using a list field on the address scope.  Note that the list will be updated
with overwrite semantics, not patch semantics.  If a subnet pool being added to
the address pool is associated with a different address scope, the operation
will fail.&lt;/p&gt;
&lt;p&gt;Only an admin can associate a subnet pool with a different owner than the
address scope.  Once a subnet pool has been associated, only the address scope
owner can update the addresses in the subnet pool.&lt;/p&gt;
&lt;p&gt;The subnet pool will be enhanced with a read-only attribute to return the ID of
the address scope to which it belongs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;See the performance impact.  A change in an address scope could have a big
impact on the control plane.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;Notifications to routers on…&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Create/Update/Delete of Address Scopes sends an update for routers connected
to affected subnets.  The scope of any subnet belonging to a subnet pool can
be changed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RPC data for a router sent to the L3 agent will be enhanced by adding the
address scope ID of each network a router connects to.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The python-neutron client will be enhanced to operate on address scopes&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The addition, deletion, or update or AddressScopes could result in a lot of L3
agent activity.  This is because any change in address pools can change the
scope of a subnet.  Any changes involving more than one project will be an
admin only operation which should limit the concern.  In any case, it shouldn’t
have any bigger impact than deploying a software upgrade which would restart L3
agents.&lt;/p&gt;
&lt;p&gt;When an L3 agent requests information about a router, the address scope of each
of the subnets to which the router is connected must be looked up.  This can be
done without adding any new queries.  Existing queries will need to join
the address scope table on the subnet pool id to retrieve the address scope id.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;This will work for IPv4 and IPv6 equally as well.  Some might think that we
don’t need this for IPv6 because everyone will have unique addresses.  But,
they’re missing the point because this isn’t just about solving the problem of
overlapping IPv4 addresses.  It also recognizes that we have tenants choosing
their own IPv6 addresses too.  They could overlap or not be routable for other
reasons.  We’re giving Neutron the ability to know how to handle them.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;The community will love it.  ;)&lt;/p&gt;
&lt;p&gt;Seriously though, this allows Neutron L3 to know where stuff can be routed.
This is important especially with IPv6 where we want to just route through to
project’s networks instead of using floating IPs to traverse the address scope
boundary.&lt;/p&gt;
&lt;p&gt;It is also an important piece to integrating MPLS/VPN which has been requested
countless times from the community.  This work will be integrated with the BGP
work after that work has matured a bit.  BGP and other dynamic routing
protocols will be address scope aware so that only addresses from the right
scope are advertised to a given peer or on a given network.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;There are alternatives to using multiple routing tables and policy routing.
For example, iptables rules could be attempted but may not be able to address
all cases, especially if addresses overlap.  Address scopes map very nicely on
to multiple routing tables and routing policy.&lt;/p&gt;
&lt;p&gt;There is also work to introduce VRF capability in to the Linux kernel directly
&lt;a class="footnote-reference brackets" href="#id12" id="id11" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.  This work could provide richer capability.  However, it is very new and
isn’t ready to be used for this purpose.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id11"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://lwn.net/Articles/632522/"&gt;https://lwn.net/Articles/632522/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~carl-baldwin"&gt;carl-baldwin&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~ryan-tidwell"&gt;ryan-tidwell&lt;/a&gt;
&lt;a class="reference external" href="https://launchpad.net/~vikschw"&gt;vikschw&lt;/a&gt;
&lt;a class="reference external" href="https://launchpad.net/~jbelamaric"&gt;jbelamaric&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Add address scope id to RPC response to L3 agent.  (Initially just the
subnet pool id)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enhance L3 agent to honor address scopes in routing tables and policy
routing.  Initially just subnet pool id.  It must be able to handle changing
scope ids for any given port.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add DB model for address scopes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add CRUD for AddressScope, including association with SubnetPool.  Update
the Neutron server to send the appropriate scope instead of the pool.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional testing of the L3 agent enhancements to the routing tables.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Full API test coverage of the new API.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;This feature deserves some new user documentation for how/why to use the new
API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;New API to be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/subnet-allocation"&gt;https://blueprints.launchpad.net/neutron/+spec/subnet-allocation&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 13 Oct 2015 00:00:00 </pubDate></item><item><title>Get Me A Network</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/get-me-a-network.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/get-me-a-network"&gt;https://blueprints.launchpad.net/neutron/+spec/get-me-a-network&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In some cloud deployments using Neutron, there is a need for each tenant
to configure resources, like a network, subnet and router, before they
are able to boot a VM. This can be a difficult proposition for those that
do not understanding networking, or do not want to understand it - they
just want a running VM. In this document we will describe ways for an
administrator to configure their cloud networking such that a tenant
does not have to do the heavy lifting typically required.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;How does a tenant boot a VM without creating a Neutron network themselves?&lt;/p&gt;
&lt;p&gt;There are a number of options.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The cloud administrator can create a shared private network&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A shared private network is a resource that all tenant’s can see
and use, for example, it will be in the output of ‘neutron net-list’.
If it is the only network visible to a tenant, then by default, a
‘nova boot’ will use it as the network for a VM.&lt;/p&gt;
&lt;p&gt;An administrator can create this network with just a few commands,
for example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ neutron net-create --shared private-shared-network
$ neutron subnet-create --name private-shared-subnet private-shared-network 10.0.0.0/24
$ neutron router-create private-shared-router
$ neutron router-interface-add private-shared-router private-shared-subnet
$ neutron router-gateway-set private-shared-router public-network
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Additionally an administrator could add an IPv6 subnet to the network
as well, giving all VMs IPv6 addresses automatically&lt;/p&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;p&gt;Easy to configure, with no tenant interaction.&lt;/p&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;p&gt;Since this network is shared by multiple tenants, they also share the
same broadcast domain, so it could be seen as less secure since inter-VM
communication is possible. For this reason it is recommended that
security groups are enabled by default.&lt;/p&gt;
&lt;p&gt;Another con is that this shared network could become ‘full’ if the
address range is too small, or the VM count becomes too large. A reasonable
large default subnet should be created for this reason.&lt;/p&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;The cloud administrator can create a provider network&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Similar to a shared private network, a provider network can be a shared
resource available to all tenants. The difference is that it does not
require a Neutron router, that function is provided by the infrastructure.&lt;/p&gt;
&lt;p&gt;An administrator can create this network with just a few commands,
for example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$ neutron net-create provider-shared-network --provider:network_type flat --provider:physical_network eth0
$ neutron subnet-create --name private-shared-subnet private-shared-network 10.0.0.0/24
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;p&gt;Easy to configure, with no tenant interaction.&lt;/p&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;p&gt;Similar to a shared private network.&lt;/p&gt;
&lt;ol class="arabic simple" start="3"&gt;
&lt;li&gt;&lt;p&gt;The cloud administrator can provision a Neutron network for each tenant&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As part of tenant creation, for example, after Keystone has been called
to create the tenant, an administrator could automatically configure
Neutron resources - network, subnet and router. This could be part of a
larger post-creation step specific to the deployment.&lt;/p&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;p&gt;Every tenant gets a private network for their VMs.&lt;/p&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;p&gt;Increased resource usage, since each tenant will have their own router
and DHCP server configured.&lt;/p&gt;
&lt;p&gt;NOTE: This method will not be implemented as part of this specification.&lt;/p&gt;
&lt;ol class="arabic simple" start="4"&gt;
&lt;li&gt;&lt;p&gt;Change Neutron to auto-allocate resources&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Neutron could be changed to automatically allocate a network, subnet
and router when Nova calls it when booting a VM. This code does not
exist today, but given this was the primary reason for this spec,
will be proposed as part of devref documentation when landing this
feature.&lt;/p&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;p&gt;Every tenant gets a private network for their VMs.&lt;/p&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;p&gt;More complicated. Still requires administrator to define default
values or resources to be used to allocate the network. Possible
race conditions if many simultaneous calls are made.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Document how a deployer can create a shared private network and connect
it to their physical network. Most of this is in the example above.
We will also document how a provider network can be created. This will
cover options 1 and 2 above.&lt;/p&gt;
&lt;p&gt;For option 4, detailed implementation will be done with devref
documentation in-tree as part of the change.&lt;/p&gt;
&lt;section id="future-work"&gt;
&lt;h3&gt;Future Work&lt;/h3&gt;
&lt;p&gt;A future enhancement could be to update the Neutron network model
with a new field to identify these “default” shared networks. This would
allow the Nova or Neutron code to filter them out if there is more than one
network, avoiding the dreaded:&lt;/p&gt;
&lt;p&gt;ERROR (BadRequest): Multiple possible networks found, use a Network ID to be
more specific. (HTTP 400) (Request-ID: req-b429d44c-d6e8-4e29-9425-928c2dc22411&lt;/p&gt;
&lt;p&gt;that can happen when more than one network is available at boot time.&lt;/p&gt;
&lt;p&gt;This could be implemented as a new flag, or as a new preference value
that could be used to filter networks by priority. This would have API and
CLI impact, and affect both the Nova and Neutron code. This work would
need to specified in another document.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="gerrit-topic"&gt;
&lt;h3&gt;Gerrit Topic&lt;/h3&gt;
&lt;p&gt;To enable reviewers to find offered patches implimenting the agreed upon
work the gerrit topic &lt;a class="reference external" href="https://review.openstack.org/#/q/topic:get-me-a-network+-status:abandoned,n,z"&gt;get-me-a-network&lt;/a&gt; will be used.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;There is a long history of trying to do orchestration-type magic inside
Neutron and the results have made it difficult for external orchestration
tools[1], added race conditions and caused disputed ownership of resources[2].
We want to avoid the same kinds of issues with this work. For this reason, we
need to be able to distinguish between instances that are in a VPC (i.e. have
advanced networking) and those that are not.  For example, AWS does this today.&lt;/p&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2014-April/032098.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2014-April/032098.html&lt;/a&gt;
[2] &lt;a class="reference external" href="https://bugs.launchpad.net/nova/+bug/1158684"&gt;https://bugs.launchpad.net/nova/+bug/1158684&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Etherpad from the Liberty summit:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/YVR-neutron-get-me-a-network"&gt;https://etherpad.openstack.org/p/YVR-neutron-get-me-a-network&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 13 Oct 2015 00:00:00 </pubDate></item><item><title>Flavor framework - Templates and meta-data</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/neutron-flavor-framework-templates.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-flavor-framework-templates"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-flavor-framework-templates&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Flavor Framework spec introduces a static framework for creating different
feature levels for a service.  This proposal adds the ability to have the
objects being created for the service, influence the flavor’s behavior.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The original flavor framework allows operators to create custom feature levels
for a given service.  But, some features require per-instance data to be
effectively deployed.&lt;/p&gt;
&lt;p&gt;An example would be a load balancer that offers page caching.  With flavors,
you can specify one flavor for no page caching, and another for page caching
everything.  But, full page caching often breaks legacy applications, and
certain URLs often need to be exempted, on a per load-balancer basis, such
as “do page caching, but not for /legacy/bank/thingie”.&lt;/p&gt;
&lt;p&gt;Another example would be an operator choosing to enable DDoS protection for a
certain level of load balancer, but security features like those often need
to have a per-instance whitelist for the end-admin to be able to quickly deal
with false positives.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This proposal suggests two changes to the existing flavor framework:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add a model/table for “flavor object meta-data”, which is meta-data that
is stored for any given flavor-enabled neutron object, back-referenced with
that objects’ UUID, and a mixin (/me hides) that adds a “flavor_meta” attribute
to said object.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the “metadata” field passed to drivers, support jinja templating syntax,
with macro substitution available for the neutron model attributes or the
above per-instance meta data.  Macro substitution will happen before the
resulting “metadata” is passed to the backend plugin/driver, so drivers
do not need to be aware of this templating.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is intended to be a temporary mechanism for operators to use to enable
certain features that are otherwise missing from openstack, without directly
modifying neutron.&lt;/p&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;p&gt;With the static flavor framework, you might have a flavor named “AwesomeSauce”,
which includes load balancing and DDoS protection, and the driver metadata might
look like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;vendor_z23_ddos_protection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and that is exactly what would be passed to the z23 lbaas driver.  With the
templating syntax, that example becomes:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;vendor_z23_ddos_protection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
  &lt;span class="n"&gt;z23_funky_whitelist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;whitelist&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With a corresponsing flavor_meta field on the LoadBalancer object being:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;whitelist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"1.2.3.4, 8.8.8.8"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and the resulting metadata passed to the driver would be:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;vendor_z23_ddos_protection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
  &lt;span class="n"&gt;z23_funky_whitelist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;'1.2.3.4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'8.8.8.8'&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;One new logical model will be added to the database.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;FlavorMeta&lt;/span&gt;
  &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt;
  &lt;span class="n"&gt;object_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt;
  &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;
  &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The ServiceProfile model will be modified to add an “allowed_meta_keys”
attribute, that when taken in conjunction with the template that can be
defined in the “metadata” attribute, defines the allowed additional of the
data that the end user can submit as flavor_meta data.&lt;/p&gt;
&lt;p&gt;The following existing models will be modified with a ‘meta’ method which
will lookup associated FlavorMeta data:&lt;/p&gt;
&lt;p&gt;LoadBalancer&lt;/p&gt;
&lt;p&gt;As more features are made flavor aware, their root models should add the meta
method (mixin?).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Supporting flavor-enabled models will add an attribute for flavor_meta.
Setting this attribute will create an associated FlavorMeta model.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;flavor_meta&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list
key/value&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;per-object
meta data&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Resource: /service_profile&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;allowed_meta_keys&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;keys for
flavor_meta&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;This is an additional hook for operators to enable. If present, users can
interact with the flavor_meta attribute via the API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Services/models that want to support flavors and this templating mechanism will
need to add the appropriate model entry and db migration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change allows operators greater flexibility in enabling advanced services
within the Neutron framework.&lt;/p&gt;
&lt;p&gt;Many of the features that can be enabled via this mechanism can and should be
added as features in their corresponding service projects. This proposal
specifies a mechanism for operators and vendors to enable features which,
for whatever reason, are not being addressed by the OpenStack dev community yet.
This could be because the feature is too niche to be broadly applicable,
the release timeline is too far in the future, or a good open-source
alternative simply does not exist yet.  This proposal adds a mechanism to
handle the interim, until the mainline feature is supported.&lt;/p&gt;
&lt;p&gt;Best practices:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If you need to migrate flavors, the prior decision is that if you have to
create a new service entity with a new flavor. They can not be modified
at this time. This applies to all flavors, not just this proposal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If an equivalent community feature exists, it is encouraged that operators
use that feature/give feedback/contribute. The recommended best practice
for drivers is for features exposed in the main-line to override features
exposed through flavor meta-data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It should be self-evident that enabling a feature offered by a single vendor
does two things for the Operator:  1. It allows the operator to utilize that
feature and expose it to their users. 2. If users use said feature, the
operator may find it more difficult to switch vendors if they choose to do
so at a later date. Furthermore, for features offered by multiple vendors,
care must be taken in abstracting those features, if the operator desires to
support multiple vendors.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The first alternative is to do nothing.  This results in what many vendors are
doing today, which is to brew up proprietary neutron solutions in order to
expose more advanced features.  This results in inconsistent solutions for
operators, more difficulty tracking trunk, and vendor lock-in.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another alternative is the same as this proposal minus the templating on the
flavor metadata.  Since the flavor metadata is tied to a particular driver,
and thus vendor specific, removing the templating would force vendors to expose
vendor specific goo to their end users.  In addition, since multiple service
profiles (drivers/vendors) can be used to implement a single flavor,
not having templating would mean that that multiple backend support would break
unless those backends supported the exact same back-end metadata, which
is unlikely and impractical.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, the most straightforward alternative is to implement each feature
natively into the services API.   In the aforementioned page caching example,
add page caching as a feature in the API, with a URL exception list, and
wait for all drivers to implement to that backend.  This adds maintenance
and development load to the entire community, and means that Neutron will have
a built-in lag for adding new features that appear in the marketplace.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~dougwig"&gt;https://launchpad.net/~dougwig&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add new data model and migration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add mixin for neutron models, with ‘meta’ method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add mixin to LoadBalancer, and its REST attributes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify flavors to apply jinja templating to service profile metadata attr.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Main flavors framework&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LBaaS v2&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Flavor tests need to be enhanced to include per-object meta-data and some basic
templated flavor metadata, and verify that substituted data is passed to
the backend.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Tests to verify the flavor_meta field in models, and that the jinja substitution
is happening properly in the flavors code before being passed to backends.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Modify flavor API tests to include flavor_meta field for objects.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;This change is invisible to end users.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Deployers will need documentation for the new API fields and the templating syntax.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Flavors framework - &lt;a class="reference external" href="https://review.openstack.org/#/c/102723"&gt;https://review.openstack.org/#/c/102723&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 13 Oct 2015 00:00:00 </pubDate></item><item><title>Add availability zones for agents</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/availability-zone.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/add-availability-zone"&gt;https://blueprints.launchpad.net/neutron/+spec/add-availability-zone&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Implement availability zones for the DHCP and L3 agents.  Just like
Nova and Cinder, this allows users to specify where the network
services run, giving better fault isolation.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Nova and Cinder have availability zones today.  Cloud administrators can assign
availability zones to physical nodes. Each of the nodes generally is equipped
different power sockets, network switches, cooling devices and others.  By
properly choosing from the provided availability zones, users can minimize
their chance of service failures.&lt;/p&gt;
&lt;p&gt;But, as Neutron doesn’t have availability zones, there’s no way to put network
services under distinct availability zones as a VM instance or a VM volume.
What happens with Neutron is completely by chance today. A user has risk of
higher probability of network failure because the user cannot allocate network
resources to availability zones for high availability.  Also, network traffic
can go through long paths between availability zones.  DVR and L3 HA can
mitigate these issues somewhat, but they don’t entirely solve the problem since
DVR still need central SNAT router, which need to be HA capable, and L3 HA
is not aware of underlying hardware configuration to be HA as a system
(i.e. not only assigning routers to “other node” but to the “appropriate node
(or group of nodes)”).&lt;/p&gt;
&lt;p&gt;Note: This spec focuses on high availability of network resources. This spec
does NOT address the scalability issue of process communications related to
cell discussion nor underlying network topology related to network segment
discussion.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This change introduces the concept of an “Availability Zone” into Neutron. In
particular, an availability zone is an optional attribute for Network and
Router resources.  These attributes in no way affect the behavior of Neutron in
terms of allowed logical network connectivity.  These attributes are simply
used as hints to the backend about the location of other resources (compute and
storage) that will be using these network resources.  The Neutron backend may
be able to use this to optimize its dynamic placement of resources to improve
performance and/or ensure resources are placed in the same defined failure
domain.&lt;/p&gt;
&lt;p&gt;Create a new extension called availability_zone.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The extension adds a new API that lists availability zones.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The rest of this information applies to the implementation of availability
zones for the built-in reference backend.&lt;/p&gt;
&lt;p&gt;The extension adds the availability_zone attribute to Agent DB models. It also
adds availability_zones and availability_zone_hints arrtibute for Network and
Router DB models.  The corresponding API resources will see the availability_zone
attribute, too.&lt;/p&gt;
&lt;p&gt;The new config options availability_zone and default_availability_zones are
added. Availability zone of each agent is set by the availability_zone config
parameter in each configuration file. If availability_zone parameter is not
given in agent config, the agent is assigned to the default availability zone
named “nova”. The name “nova” is referred to availability zone of Nova and
Cinder. When a user executes resource create API without availability zone
attribute, neutron set default_availability_zones value to the resource. The
default_availability_zones value can be blank. If that’s the case, the
scheduler selects any agent from any availability zone without any preference
of specific availability zone. This helps to avoid the unbalance of resource
assignment.&lt;/p&gt;
&lt;p&gt;API and config are arranged to the following.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Using config, deployer specifies which availability_zone an agent
belongs to, and they can also define default availability zones for
user resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using GET API of availability zone, users can get all the
availability zones which neutron manages. API of availability zone
is “GET” only.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using GET API of network resources, users can get which availability
zones their network resources is assigned.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using POST API of network resources, users can create a network resource with
availability zone hints as candidate for availability zone which the
resource belongs to.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This spec enables each resource to belong to multiple availability zones. A
user is able to specify the list of multiple AZs as a parameter when a resource
is created. The list of multiple AZs defines the candidates of availability
zone where the resource may be deployed. If the parameter at the creation is
not given and the default_availability_zones config is not specified, the
resource can be deployed at any availability zone. In other words, the list of
multiple AZs for a resource restricts the scope of the deployment. Therefore,
we can get redundancy by scheduling a network or a router to two agents in two
distinct availability zones. Scheduler is also improved so that routers and
networks are properly allocated with availability zone.&lt;/p&gt;
&lt;p&gt;Limitations: With the reference L3 implementation without HA, we apparently
cannot assign a router to multiple L3 agents and as a result we cannot achieve
pure high availability from availability zone. A user just has an expectation
of failure domain by setting availability zone to non-HA router. With L3-HA
enabled router in the reference L3 implementation, all L3 agents across
availability zones still need to have the connectivity to an external network
uniformly to achieve high availability deployment.&lt;/p&gt;
&lt;p&gt;Future work: It is definitely expected that all other services in neutron such
as lbaas, fwaas, vpnaas and so on are able to handle the availability zone as
its attributes. As these haven’t supported HA capability in the reference
implementation yet, I suggest to implement them separately in another spec by
step-by-step approach, hopefully almost concurrently with this spec.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;As noted above, the spec adds availability_zone attribute to DB. A migration
script will be provided.  When operators update config, neutron checks
different availability zone between resources and agents, then outputs some
logs.&lt;/p&gt;
&lt;p&gt;Attribute will be added:&lt;/p&gt;
&lt;p&gt;Availability_zone attribute to RouterExtraAttributes&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;availability_zone_hints&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;availability zone candidate for the router&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;availability_zones&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;availability zone for the router&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Availability_zone attribute to NETWORKS as extend&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;availability_zone_hints&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;availability zone candidate for the network&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;availability_zones&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;availability zone for the network&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Availability_zone attribute to Agent&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;availability_zone&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;String&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;availability zone for the agent&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;/agents&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;‘availability_zone’ key is added to ‘configurations’ attribute(dict). Note that
‘configurations’ attribute is read only.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;/networks and /routers&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following attribute is added.&lt;/p&gt;
&lt;table class="docutils align-default" id="id1"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;New attribute&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;availability_zone_hints&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list of string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW(POST only), all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[]&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list of string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list of human-readable name&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;availability_zones&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list of string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[]&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list of string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list of human-readable name&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;/availability_zones&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The extension introduces a new availability_zone API resource. Only GET is available.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;availability_zones&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list of dict&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;see example below&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;An example of a JSON response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"availability_zones"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"nova"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"state"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"available"&lt;/span&gt;
        &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;python-neutronclient and horizon will support new availability_zone value.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.  This proposal is protocol agnostic.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;To make use of this feature, deployers need to set availability_zone in the
each configuration file(e.g. l3_agent.ini and dhcp_agent.ini), specifying each
network node’s availability zone.&lt;/p&gt;
&lt;p&gt;The spec expects deployer to set an availability zone to an agent by config file
since availability zone is related to a place of power socket and fixed
equipment. However it doesn’t block new feature connected with availability zone
from providing API, which enables deployer to specify availability zone without
the config. It includes feature managing physical resources like
Host_aggregation, Cell and others.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="upgrade-impact"&gt;
&lt;h3&gt;Upgrade Impact&lt;/h3&gt;
&lt;p&gt;Agent side: Before the upgrade, all agents are considered to be in the default
availability zone named “nova.” Once an operator configures availability zone
config parameter ‘availability_zone‘ in its agent config file and the agent
is restarted, the agent belongs to the availability zone set in the config
file. If an operator sets “nova” to the parameter, it means same as the
default availability zone.&lt;/p&gt;
&lt;p&gt;Resource side: Before the upgrade, all resources are considered to be at any
availability zone.  Even though an operator changes the availability zone of
agents, it doesn’t break the matching to existing resources on the agent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Hirofumi Ichihara &amp;lt;ichihara-hirofumi&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Secondary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Iwamoto Toshihiro &amp;lt;iwamoto&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add availability_zone to the DB models&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make agents report their availability_zone settings&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the availability_zone extension&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(Validate REST API availability_zone parameters)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add AvailabilityZoneFilter based on existing neutron scheduler implementations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify the L3(non-DVR and dvr_snat router) and DHCP agent schedulers to be AZ aware&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify the L3(HA router) agent schedulers to be AZ aware&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add availability zone to python-neutronclient(Volunteers needed)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add availability zone to horizon(assignee: amotoki)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Add tests, which ensure resources are allocated for proper availability
zone. Two new tests will be added for the following resources:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Network availability zone&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Router availability zone&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Tests for the new attribute and the new API resource will be added.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;The new config options will be documented. Availability zone use cases and the
usage will be documented in the devref.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Nova availability zone&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cinder availability zone&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An implementation of this blueprint
&lt;a class="reference external" href="https://review.openstack.org/#/c/183369/"&gt;https://review.openstack.org/#/c/183369/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 29 Sep 2015 00:00:00 </pubDate></item><item><title>External DNS Resolution</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/external-dns-resolution.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/external-dns-resolution"&gt;https://blueprints.launchpad.net/neutron/+spec/external-dns-resolution&lt;/a&gt;&lt;/p&gt;
&lt;dl class="field-list simple"&gt;
&lt;dt class="field-odd"&gt;Author&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-odd"&gt;&lt;p&gt;Carl Baldwin &amp;lt;&lt;a class="reference external" href="mailto:carl.baldwin%40hp.com"&gt;carl&lt;span&gt;.&lt;/span&gt;baldwin&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class="field-even"&gt;Copyright&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-even"&gt;&lt;p&gt;2015 Hewlett-Packard Development Company, L.P.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;This blueprint builds from where the Internal DNS Resolution blueprint leaves
off &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.  That one reconciles the Nova VM name with the hostname assigned by
Neutron DHCP and with a DNS name that can be used to look up the host using
Neutron’s internal DNS.  The next step is to integrate DNSaaS so that instances
can be found using their instance names plus a DNS domain name from outside the
cloud.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/internal-dns-resolution"&gt;https://blueprints.launchpad.net/neutron/+spec/internal-dns-resolution&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;As instances come and go and floating IPs are associated and disassociated,
changes may be required in an external DNS service to reflect them.  Currently,
these changes need to be made independently.  This is often a manual process
which is prone to error.  It can be scripted using an API to the external DNS
service but that adds complication for API users and their scripts.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="overview"&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
&lt;p&gt;This change will link public IP addresses on Neutron external networks with an
external DNS service such as OpenStack Designate.  Tenants will expect that any
create, update, or delete of an IP address on a network will result in a
set of corresponding changes in DNS, covering both A/AAAA and PTR records.&lt;/p&gt;
&lt;p&gt;A very important question to consider at this point is whether the A/AAAA
record(s) pointed to by the DNS name are associated with an instance or
with the public IP itself.  This question will be discussed in detail in
the &lt;a class="reference internal" href="#data-model-impact"&gt;Data model impact&lt;/a&gt; section.&lt;/p&gt;
&lt;p&gt;The change will introduce an interface and a reference implementation of that
interface which will integrate with the OpenStack Designate service.  This
reference implementation will be as easy to configure and use as possible.&lt;/p&gt;
&lt;p&gt;This driver will be administratively configured with credentials for the
external service in a way similar to how Nova is configured to access the
Neutron service for port creation when an instance gets created.&lt;/p&gt;
&lt;section id="split-horizon-dns"&gt;
&lt;h4&gt;Split Horizon DNS&lt;/h4&gt;
&lt;p&gt;Consider an IPv4 situation where NAT is used and a DNS domain has been
associated with a network.  One might expect DNS to respond to queries on that
domain with the private IP address for VMs that happen to reside on the same
network.  Similarly, a reverse DNS request for the private IP address would
return the VMs DNS name.&lt;/p&gt;
&lt;p&gt;The advantage of split horizon DNS is that any machine can use the same names
for other machines regardless of whether the machine is on the same network or
a different network.&lt;/p&gt;
&lt;p&gt;This is the kind of thing that has been accomplished using BIND 9 dns server
views.  It is typical to disable recursive DNS on the external zone but not on
the internal zone.&lt;/p&gt;
&lt;p&gt;This blueprint will accomplish this by leveraging the existing dnsmasq
implementation for internal resolution and integrate with an external dns
service for the external part.&lt;/p&gt;
&lt;p&gt;Currently, the domain name is set by Neutron to openstacklocal.  To enable
split horizon DNS, dnsmasq for a network will be configured with the domain
name associated with that network instead of openstacklocal.  If no domain is
associated then it will default to openstacklocal.&lt;/p&gt;
&lt;p&gt;There are some limitations to split horizon DNS.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;If two networks are connected privately by a neutron router then split
horizon DNS will not work between them.  It will only work for names of
instances on the same network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It will probably not work for names that come from the the floating IP, as
explained in the &lt;a class="reference internal" href="#data-model-impact"&gt;Data model impact&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;+–––––––––––––+    +–––––––––––––+    +–––––––––––––+    +–––––––––––––+
| FloatingIP  |    | Port        |    | Network     |    | DNSDomain   |
+–––––––––––––+    +–––––––––––––+    +–––––––––––––+    +–––––––––––––+
| ...         |––&amp;gt; | ...         |––&amp;gt; |...          | --&amp;gt;|             |
|             |    |             |    |             |    |             |
| dns_domain  |    |             |    |             |    | dns_domain  |
| dns_name    |    | dns_name    |    |             |    |             |
+–––––––––––––+    +–––––––––––––+    +–––––––––––––+    +–––––––––––––+
     \                                                          |
      \                                                         V
       \                                           +––––––––––––––––––––––+
        \                                          | External DNS service |
         \                                         +––––––––––––––––––––––+
          +––––––––––––––––––––––––––––––––––––––&amp;gt; | dns_domain           |
                                                   | dns_name             |
                                                   | ...                  |
                                                   |                      |
                                                   +––––––––––––––––––––––+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The diagram above summarizes the changes that will be made to the data model
and how these changes will support the interactions with the external DNS
service. Such interactions are triggered when a public IP is created, updated
or deleted. Three cases will be supported:&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Floating IP with null dns_domain and dns_name:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;case&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DNS&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;linked&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;instances&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="n"&gt;More&lt;/span&gt; &lt;span class="n"&gt;precisely&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;they&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt;
&lt;span class="n"&gt;linked&lt;/span&gt; &lt;span class="n"&gt;through&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="n"&gt;attached&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="n"&gt;When&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;floating&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;
&lt;span class="n"&gt;association&lt;/span&gt; &lt;span class="n"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt; &lt;span class="n"&gt;used&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;DNS&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;come&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;the&lt;/span&gt;
&lt;span class="n"&gt;backing&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="s1"&gt;'s dns_name and the DNSDomain associated to the port'&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;dns_name&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="n"&gt;either&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;Nova&lt;/span&gt; &lt;span class="n"&gt;display&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;Neutron&lt;/span&gt;
&lt;span class="n"&gt;generated&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;consistent&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;blueprint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Floating IP with no null dns_domain and dns_name:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;case&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;dns_name&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;dns_domain&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;linked&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;floating&lt;/span&gt;
&lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;When&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;floating&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;association&lt;/span&gt; &lt;span class="n"&gt;changes&lt;/span&gt; &lt;span class="n"&gt;there&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="n"&gt;need&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;change&lt;/span&gt;
&lt;span class="n"&gt;anything&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;DNS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="n"&gt;relevance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;covers&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="n"&gt;case&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;floating&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;always&lt;/span&gt; &lt;span class="n"&gt;have&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;given&lt;/span&gt;
&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt; &lt;span class="n"&gt;regardless&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;which&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;associated&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;dns_name&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;dns_domain&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;overridden&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="n"&gt;floating&lt;/span&gt;
&lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="n"&gt;If&lt;/span&gt; &lt;span class="n"&gt;these&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;floating&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;then&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;DNS&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;comes&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;the&lt;/span&gt; &lt;span class="n"&gt;floating&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Port with no null dns_name on a public provider network with no null
dns_domain:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;case&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;making&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;ports&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt;
&lt;span class="n"&gt;accesible&lt;/span&gt; &lt;span class="n"&gt;outside&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;Openstack&lt;/span&gt; &lt;span class="n"&gt;cloud&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Once&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DNS&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;linked&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;
&lt;span class="n"&gt;instances&lt;/span&gt; &lt;span class="n"&gt;through&lt;/span&gt; &lt;span class="n"&gt;their&lt;/span&gt; &lt;span class="n"&gt;ports&lt;/span&gt; &lt;span class="n"&gt;attached&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;An&lt;/span&gt;
&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="s1"&gt;'s name and domain used for DNS will come from its backing port&lt;/span&gt;
&lt;span class="n"&gt;dns_name&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;DNSDomain&lt;/span&gt; &lt;span class="n"&gt;associated&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="s1"&gt;'s network.&lt;/span&gt;

&lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;dns_name&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="n"&gt;either&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;Nova&lt;/span&gt; &lt;span class="n"&gt;display&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;Neutron&lt;/span&gt;
&lt;span class="n"&gt;generated&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;consistent&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;blueprint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Multiple networks can be linked to the same DNS domain.  This raises
the potential concerns over duplicate names.  Duplicate entries for a single
DNS name are valid part of DNS, and are considered acceptable by this
blueprint.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Because how A and AAAA records map can depend on whether the
publishing DNS is running split view, it may make sense to publish the IP
under both names if they exist.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;For PTR records, what will be published is a pointer to the instance dns name
under the private IP address and a pointer to the floating ip dns name under
the floating IP address.&lt;/p&gt;
&lt;section id="dnsdomain"&gt;
&lt;h4&gt;DNSDomain&lt;/h4&gt;
&lt;p&gt;A DNSDomain object will be added to the data model, with a one to many
relationship with the network object. This will allow to associate several
networks with a DNS domain name. No relationship with a DNSDomain object means
that the network object is not associated with a DNS domain name. There is no
need to populate existing network objects on upgrade so the upgrade will not
require any special attention.&lt;/p&gt;
&lt;p&gt;The dns_domain in a DNSDomain object will be validated as a legal dns domain at
the API level.  The plugin will also validate the domain with the external
service to ensure that it exists and is accessible to the tenant.&lt;/p&gt;
&lt;p&gt;In some scenarios, a single DNS domain name may legally exist multiple times in
the external service.  A driver specific qualifier may be optionally appended
to the dns_domain name, and will be separated from the name by a single colon
(:) character.  For example, assuming the domain example.org exists in the
external service with a resource ID of 298c22d1-cebd-475b-b5c9-0f880ee2f23f,
the qualified domain name stored by DNSDomain could be
“example.org:298c22d1-cebd-475b-b5c9-0f880ee2f23f”. The use of a qualifier must
be optional, and only required where a project has visibility of more than one
DNS domain with the same name in the external service.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="floating-ip"&gt;
&lt;h4&gt;Floating IP&lt;/h4&gt;
&lt;p&gt;Two fields – dns_domain and dns_name – will be added to the floating ip
object.  The dns_domain field will be validated in the same way it is on the
&lt;a class="reference internal" href="#dnsdomain"&gt;DNSDomain&lt;/a&gt; object.  The dns_name field will be validated as a valid PQDN. See
the internal-dns-resolution blueprint for details.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;The API will be extended to support CRUD operations on the new object
DNSDomain. The create and update operations will enable users to associate dns
domains with a list of networks.&lt;/p&gt;
&lt;p&gt;The current API to manage floating ips will be extended to add optional
dns_domain and dns_name fields.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;The Neutron configuration files will contain driver specific configuration for
accessing the external service, this will include sensitive information such
as usernames/passwords, and will be similar in nature to how Nova is
configured with Neutron credentials for port creation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;This change will need a corresponding change to python-neutronclient to add
support for the API changes in &lt;a class="reference internal" href="#rest-api-impact"&gt;REST API impact&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;This change is something that has to be explicitly enabled by the deployer.  It
is optional, the defaults will work for existing or new deployments.&lt;/p&gt;
&lt;p&gt;The deployer will be responsible for configuring the driver to interact with
the external DNS service.  This will be an optional feature and will not
require any action on the part of the deployer until enabling the new feature
is desired.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;This functionality could be handled from Designate.  In general, this has the
disadvantage of excluding other DNS services.&lt;/p&gt;
&lt;p&gt;This could be accomplished by polling Neutron for changes to public IP
addresses.  Doing this would require tuning the polling interval so that it is
often enough that users will not complain about the time it takes for changes
to take effect but not so often that it becomes a burden on the performance of
the system.&lt;/p&gt;
&lt;p&gt;This could also be done by integrating Designate with Neutron RPC so that it
picks up on changes to public IP address.  This has a disadvantage that it ties
Designate to the implementation of Neutron.  It would be difficult for
designate to understand and account for the relationship between internal ports
and floating IP ports.  It would also be difficult to control the affinity of a
DNS name.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Extend database models.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add dns_name and dns_domain attributes to FloatingIP model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add DNSDomain object.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Database upgrade script.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend API and validators.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add dns_name and dns_domain to FloatingIP.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement CRUD operations for DNSDomain&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement interface between Neutron and external DNS service&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement driver for Designate.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/internal-dns-resolution"&gt;https://blueprints.launchpad.net/nova/+spec/internal-dns-resolution&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This change requires the use of the Designate API which is not currently used
by Neutron.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Designate has a full DevStack plugin, which can be used as part of integration
testing within the gate.  There is an open question around if this plugin needs
to be included within the devstack tree, or if it can be consumed reliably from
the Designate repo.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference internal" href="#rest-api-impact"&gt;REST api impact&lt;/a&gt; should be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://eavesdrop.openstack.org/irclogs/%23openstack-neutron/%23openstack-neutron.2014-02-21.log"&gt;Discussion on IRC that sparked this blueprint&lt;/a&gt; (2014-02-21T00:19:20)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Designate"&gt;Openstack Designate Project&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 23 Sep 2015 00:00:00 </pubDate></item><item><title>Restructure OVS L2 agent</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/restructure-l2-agent.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/restructure-l2-agent"&gt;https://blueprints.launchpad.net/neutron/+spec/restructure-l2-agent&lt;/a&gt;&lt;/p&gt;
&lt;dl class="field-list simple"&gt;
&lt;dt class="field-odd"&gt;Author&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-odd"&gt;&lt;p&gt;Rossella Sblendido &amp;lt;&lt;a class="reference external" href="mailto:rsblendido%40suse.com"&gt;rsblendido&lt;span&gt;@&lt;/span&gt;suse&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class="field-even"&gt;Author&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-even"&gt;&lt;p&gt;Marios Andreou &amp;lt;&lt;a class="reference external" href="mailto:marios%40redhat.com"&gt;marios&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;This blueprint focuses on paying down the technical debt for the OVS L2 agent,
as already discussed during the Kilo design summit &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; .
The goal of this work is to improve the code quality of the OVS l2 agent, in particular
with respect to scalability and performance. These improvements will be evaluated by
performing stress tests using Rally and comparing the results before and after
this change. Test coverage for the OVS L2 agent will also be improved as part of this
blueprint.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/kilo-neutron-agents-technical-debt"&gt;https://etherpad.openstack.org/p/kilo-neutron-agents-technical-debt&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The L2 agent presents several points that can be improved to boost performance and
scalability. This blueprint tackles the following areas: RPC, device processing and the
OVSDB monitor. Every point will be analized in detail in the next
section.
Orthogonal to this blueprint, there’s a spec that was completed in Kilo  to use OVS
Python lib instead of
the CLI &lt;a class="footnote-reference brackets" href="#id4" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; .&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/vsctl-to-ovsdb"&gt;https://blueprints.launchpad.net/neutron/+spec/vsctl-to-ovsdb&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;We propose changes for each area identified in the problem description.&lt;/p&gt;
&lt;section id="rpc"&gt;
&lt;h3&gt;RPC&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;update_device_up and update_device_down are the calls used to notify the plugin that
a device is up or down. At present, these calls accept only one device, but they can be improved
to handle several devices.
The following new RPC calls will be introduced: update_device_list_up and update_device_list_down.
Instead of making an RPC call per device, the agent would make a single RPC call for all the
devices. When possible, the neutron plugin will issue a single db update, instead of individual
updates for each device&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When the agent gets a security_groups_provider_updated it refreshes the filters for all
the ports, not just for the ports affected by the change. This is unnecessarily costly.
A new parameter will be added to security_groups_provider_updated to specify the subnet_id,
so the agent will be able to calculate a list of devices whose filter needs to be updated
instead of refreshing the filters for all of them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;modify the port_update message to indicate which changes affected the port. The L2 agent actually
cares only about changes to the state of the port, the rest of the changes don’t require any
action by the agent.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="smart-resync"&gt;
&lt;h4&gt;Smart resync&lt;/h4&gt;
&lt;p&gt;With the current implementation if there’s an error in the communication with the plugin
during the agent loop, the sync flag is set to true and a complete resync will be
performed by the agent at the next iteration. This means that all the devices will be
processed again by the agent. To avoid that when an error occurs the device being processed
will be put in a list of devices in error. The resync will be performed only for those devices.
The agent’s reaction to errors should be improved as well. The agent should analyze the error
and perform one of the following actions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Retry the failed operation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Resync the device involved&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In case of fatal error (e.g. after number of failures of the same operation &amp;gt; threshold), put
the device in error state&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The L2 agent doesn’t have a reliable way of ensuring the state reported on the server side is
consistent with the state applied on the backend. Providing a solution to this problem is
out of scope for this blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="avoid-processing-a-device-when-there-s-no-need"&gt;
&lt;h4&gt;Avoid processing a device when there’s no need&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The agent keeps track of the ports for which it received a port update notification. During
the agent loop updated ports are processed together with added ports. They both are handled in the
same way but actually in most cases updated ports don’t need any action performed by the agent.
The proposed change is to add a check and process the updated port  only if the update
is a state change. A state change should be defined. ML2, for instance sends port update
messages for an awful lot of things. The ones which are important for the l2 agent are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;name or IP change&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MAC address change (when the code will be merged)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;admin state changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;security group changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;security group membership changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;port security changes (if the corresponding blueprint is accepted and the code is merged)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When ports are updated, port filters are applied again. This is not needed if there’s no change in
the IP address. Add a check for that.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When a security_groups_provider_updated is received then a global refresh of the firewall
is performed.
This can be avoided if we keep track of the subnet for which the provider rule was updated.
The agent can refresh the filter of the devices that belong to that subnet.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="ovs-db-monitor"&gt;
&lt;h4&gt;OVS DB Monitor&lt;/h4&gt;
&lt;p&gt;The OVS DB monitor knows which devices have been added, and which ones have been removed.
It can therefore be used to generate the events that the agent needs to process, at least the
ones initiated by changes on the host such as vif plug and vif unplug.
Nevertheless, we just use the OVS DB monitor to “signal” that an event occurred and then
scan the bridge again to gather information which was already retrieved by the OVS DB monitor.&lt;/p&gt;
&lt;p&gt;Leveraging the OVS DB monitor in this way can also simplify the process of transforming the
agent event processing mechanism from a loop with polling to a queue-based mechanism.
Events can be either initiated on the host itself (e.g.: vif plugged) or from the neutron server
(e.g.: security group membership changed). In many cases these events can be processed independently.
Adding new events to queues will simplify the process of enabling multiple workers for consuming
these events and ensure events with a prerequisite event are executed in the appropriate order.&lt;/p&gt;
&lt;p&gt;There is also a possibility of using different queues for handling events with different priorities
according to their criticality. This is however something that can be done in a subsequent iteration
(it won’t be anymore debt repayment but ‘enhancement’).&lt;/p&gt;
&lt;p&gt;There’s an ongoing effort to modify OVS Python library to make events regarding port added or
deleted available to its client. Even though right now OVS Python lib essentially runs monitor
to update the local cache of the interfaces, it doesn’t make those events (device added or removed)
available to the user of the library. Terry Wilson &lt;a class="reference external" href="https://launchpad.net/~otherwiseguy"&gt;otherwiseguy&lt;/a&gt; is
working on it.&lt;/p&gt;
&lt;p&gt;The L2 agent could make use of this notification system when the change is merged upstream. This
is out of the scope for this blueprint though.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;Modify port update to specify which change occured to the port&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Performance should be improved. It’s not possible to quantify it now but the following is expected:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;reduced wait time for event processing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;reduced risk of event starvation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;faster OVSDB communication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;reduced load over AMQP bus&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;less device processing churn&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change has been discussed during the Kilo design summit and supports the focus
for Kilo to pay down technical debt.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;This blueprint in the end is a list of small changes. Every small change can be
discussed and several slightly different variants can be proposed. But the only
general alternatives to this blueprint, are: to leave the agent as it is or to write a
completely new one.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~rossella-o"&gt;rossella_s&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~marios-b"&gt;marios&lt;/a&gt;
&lt;a class="reference external" href="https://launchpad.net/~salvatore-orlando"&gt;salv-orlando&lt;/a&gt;
&lt;a class="reference external" href="https://launchpad.net/~minsel"&gt;mlavalle&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;(The following items have already patches upstream but no&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;code was merged during the previous release)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Functional testing of the agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RPC improvements&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Agent Loop - device processing&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Avoid processing a device when there’s no need&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add a check to process updated port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Avoid global refresh of the firewall&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use event notification from OVS Python library&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;No new tests&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional tests for ip_lib and ovs_lib&lt;/p&gt;
&lt;p&gt;Currently there’s no functional test for the agent. The following cases will be tested:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;device up&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;device down&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;port update&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;setup tunnel port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;clean up tunnel port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ovs restart&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ping works between 2 ports on same subnet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;default port filters (check that traffic that is not allowed is blocked and vice versa
traffic allowed passes)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;security group rule added&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;security group rule removed&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;New RPC calls will be added update_device_list_up and update_device_list_down&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A new parameter will be added to security_groups_provider_updated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Port update notification will be modified to specify the change that affected the port&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/kilo-neutron-agents-technical-debt"&gt;https://etherpad.openstack.org/p/kilo-neutron-agents-technical-debt&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 23 Sep 2015 00:00:00 </pubDate></item><item><title>Push Notifications for Agents</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/newton/push-notifications.html</link><description>

&lt;p&gt;RFE:
&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1516195"&gt;https://bugs.launchpad.net/neutron/+bug/1516195&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Launchpad blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/push-notifications"&gt;https://blueprints.launchpad.net/neutron/+spec/push-notifications&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The current method we use to get information from the server to the agent
is driven by notification and error-triggered calls to the server by the agent.
So during normal operation, the server will send out a notification that a
specific object has changed (e.g. a port) and then the agent will respond
to that by querying the server for information about that port. If the
agent encounters a failure while processing changes, it will start over
and re-query the server in the process.&lt;/p&gt;
&lt;p&gt;The load on the server from this agent-driven approach can be very
unpredictable depending on the changes to object states on the neutron
server. For example, a single network update will result in a query from
every L2 agent with a port on that network.&lt;/p&gt;
&lt;p&gt;This blueprint aims to change the pattern we use to get information to the
agents to primarily be based on pushing the object state out in the change
notifications. For anything not changed to leverage this method of retrieval
(e.g. initial agent startup still needs to poll), the AMQP timeout handling
will be fixed to ensure it has an exponential back-off to prevent the agents
from stampeding the server.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;An outage of a few agents and their recovery can lead to all of the agents
drowning the neutron servers with requests. This can cause the neutron servers
to fail to respond in time, which results in more retry requests building up,
leaving the entire system useless until operator intervention.&lt;/p&gt;
&lt;p&gt;This is caused by 3 problems:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;We don’t make optimal use of server notifications. There are times when
the server will send a notification to an agent to inform it that something
has changed. Then the agent has to make a call back to the server to get the
relevant details. This means a single L3 rescheduling event of a set of
routers due to a failed L3 agent can result in N more calls to the server
where N is the number of routers. Compounding this issue, a single agent
may make multiple calls to the server for a single operation (e.g. the L2
agent will make one call for port info, and then another for security group
info).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The agents will give up after a short period of time on a request and retry
the request or issue an even more expensive request (e.g. if synchronizing
info for one item fails, a major issue is assumed so a request to sync all
items is issued). So by the time the server finishes fulfilling a request,
the client is no longer waiting for the response so it goes in the
trash. As this compounds, it leaves the server processing a massive queue
of requests that won’t even have listeners for the responses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Related to the second item is the fact that the agents are aggressive in
their retry mechanisms. If a request times out, that request is immediately
retried with the same timeout value; that is, they have no back-off
mechanism. (This has now been addressed by
&lt;a class="reference external" href="https://review.openstack.org/#/c/280595/"&gt;https://review.openstack.org/#/c/280595/&lt;/a&gt; which adds backoff,
sleep, and jitter.)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Eliminate expensive cases where calls are made to the neutron server in
response to a notification generated by the server. In most of these cases
where the agent is just asking for regular neutron objects
(e.g. ports, networks), we can leverage the RPC callbacks mechanism
introduced in Liberty[1] to have the server send the entire changed object
as part of the notification so the agent has the information it needs.&lt;/p&gt;
&lt;p&gt;The main targets for this will be the security group info call,
the get_device_details call, and the sync_routers call. Others will be
included if the change is trivial once these three are done.
The DHCP agent already relies on push notifications, so it will just
be updated to use the revision number to detect the out of order events
it’s susceptible to now.&lt;/p&gt;
&lt;p&gt;For the remaining calls that cannot easily be converted into the callbacks
mechanism (e.g. the security groups call which blends several objects,
the initial synchronization mechanism, and agent-generated calls), a nicer
timeout mechanism will be implemented with an exponential back-off and timeout
increase so a heavily loaded server is not continuously hammered to death.&lt;/p&gt;
&lt;section id="changes-to-rpc-callback-mechanism"&gt;
&lt;h3&gt;Changes to RPC callback mechanism&lt;/h3&gt;
&lt;p&gt;The current issue with the RPC callback mechanism and sending objects as
notifications is a lack of server operation ordering guarantees and
AMQP message ordering guarantees.&lt;/p&gt;
&lt;p&gt;To illustrate the first issue, examine the following order of events that
happen when two servers update the same port:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Server 1 commits update to DB&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server 2 commits update to DB&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server 2 sends notification&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server 1 sends notification&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the agent receives the notifications in the order in which they are
delivered to AMQP, it will think the state delivered by Server 1 is the
current state when it is actually the state committed by Server 2.&lt;/p&gt;
&lt;p&gt;We also have the same issue when oslo messaging doesn’t guarantee
message order (e.g. ZeroMQ). Even if Server 1 sends immediately after
its commit and before Server 2 commits and sends, one or more of the
agents could end up seeing Server 2’s message before Server 1’s.&lt;/p&gt;
&lt;p&gt;To handle this, we will add a revision number, implemented as a monotonic
counter, to each object. This counter will be incremented on any update
so any agent can immediately identify stale messages.&lt;/p&gt;
&lt;p&gt;To address deletes arriving before updates, agents will be expected
to keep a set of the UUIDs that have been deleted. Upon receiving an update,
the agent will check this set for the object’s UUID and ignore the update
since deletes are permanent and UUIDs cannot be re-used. If we do make IDs
recyclable in the future, this can be replaced with a strategy to confirm
ID existence with the server or we can add another internal UUID that
cannot be specified.&lt;/p&gt;
&lt;p&gt;Note that this doesn’t guaruntee message ordering for the agent because
that is a property of the message backend, but it does give the agent the
necessary info to re-order messages when it receives them so they can
determine which one reflects the more recent state of the DB.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;A ‘revision_number’ column will be added to the standard attr table. This
column will just be a simple big integer used as monotonic counter that
will be updated whenever the object is updated on the neutron server.
This revision number can then be used by the agents to automatically
discard any object states that are older than the state they already have.&lt;/p&gt;
&lt;p&gt;This revision_number will use the version counter feature which is built-in
to SQLAlchemy: &lt;a class="reference external" href="http://docs.sqlalchemy.org/en/latest/orm/versioning.html"&gt;http://docs.sqlalchemy.org/en/latest/orm/versioning.html&lt;/a&gt;
Each time an object is updated, the server will perform a compare-and-swap
operation based on the revision number. This ensures that each update must
start with the current revision number or it will fail with a StaleDataError.
The API layer can catch this error with the current DB retry mechanism and
start over with the latest revision number.&lt;/p&gt;
&lt;p&gt;While SQLAlchemy will automatically bump the revision for us when the record
for an object is updated (e.g. a standard attr description field), it will
not update it if it’s a related object changing (e.g. adding an IP address
to the port or changing its status). So we will have to manually trigger
the revision bump (either via a PRECOMMIT callback or inline code) for
any operations that we want to trigger the revision number bump.&lt;/p&gt;
&lt;p&gt;What this guarantees:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;An object in a notification is newer (from a DB state perspective) than
an object with a lower revision number. So any objects with lower revision
numbers can safely be ignored since they represent stale DB state.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What this doesn’t guarantee:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Message ordering ‘on the wire’. An AMQP listener may end up receiving an
older state than a message it has already received. It’s up to the listener
to look at the revision number to determine if the message is stale.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;That each intermediary state is transmitted. If a notification mechanism
reads the DB to get the full object to send, the DB state may have progressed
so it will notify with the latest state than the state that triggered the
original notification. This is acceptable for all of our use cases since we
only care about the current state of the object to wire up the dataplane. It
is also effectively what we have now since the DB state could change between
when the agent gets a notification and when it actually asks the server for
details.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reliability of the notifications themselves. This doesn’t address the issue
we currently have where a dropped notification is not detected.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;Making existing notifications significantly more data-rich. The hope here is
to eliminate many of the expensive RPC calls that each agent makes and have
each agent derive all state from notifications with one sync method for
recovery/initialization that we can focus on optimizing.&lt;/p&gt;
&lt;p&gt;This will result in more data being sent up front by the server to the
messaging layer, but it will eliminate the data that would be sent in
response to a call request from the agent in the current pattern. For a
single agent, the only gain is the elimination of the notification and
call messages; but for multiple agents interested in the same resource,
it eliminates extra DB calls and extra messages from the server to fulfill
those calls.&lt;/p&gt;
&lt;p&gt;This pattern will result in fewer messages sent to oslo messaging because
of the elimination of the calls from the agents that would result in the
same payload we are preemptively broadcasting once instead of casting
multiple times to each requesting agent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Higher ratio of neutron agents per server afforded by a large reduction in
sporadic queries by the agents.&lt;/p&gt;
&lt;p&gt;This comes at a cost of effectively serializing operations on an individual
object due to the compare and swap operation on the server. For example,
if two server threads try to update a single object concurrently and both
read the current state of the object at the same time, one will fail on
commit with a StaleDataError which will be retried by the API layer.
Previously both of these would succeed because the UPDATE statement
would have no compare-and-swap WHERE criteria. However, this is a very
reasonable performance cost to pay considering that concurrent updates to
the same API object are not common.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;N/A - upgrade path will maintain normal N-1 backward compatibility on the
server so all of the current RPC endpoints will be left untouched for one
cycle.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Need to change development guidelines to avoid the implementation of new
direct server calls.&lt;/p&gt;
&lt;p&gt;The notifications will have to send out oslo versioned objects since
notifications don’t have RPC versions. So at a minimum we need to
switch to oslo versioned objects in the notification code if we
can’t get them fully implemented everywhere else. To do this we
can leverage the RPC callbacks mechanism.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Maintain the current information retrieval pattern and just adjust the timeout
mechanism for everything to include back-offs or use cast/cast instead of
calls. This will allow a system to automatically recover from self-induced
death by stampede, but it will not make the performance any more predictable.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;kevinbenton
Ihar Hrachyshka&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Exponential back-off for timeouts on agents&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement ‘revision’ extension to add the revision_number column to the
data-model and expose it as a standard attribute.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write tests to ensure revisions are incremented as expected&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write (at least one) test that verifies a StaleDataError is triggered
in the event of concurrent updates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update DHCP agent to make use of this new ‘revision’ field to discard stale
updates. This will be used as the proof of concept for this approach since
the DHCP agent is currently exposed to operating on stale data with out of
order messages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace the use of sync_routers calls on the L3 agents for the most frequent
operations (e.g. floating IP associations, etc) with RPC callbacks once the
OVO work allows it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stand up grenade partial job to make sure agents using different OVO versions
maintain N-1 compatibility&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update devref for callbacks&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="possible-future-work"&gt;
&lt;h3&gt;Possible Future Work&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Switch to cast/cast pattern so agent isn’t blocked waiting on server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Setup a periodic system based on these revision numbers to have the agents
figure out if they have lost updates from the server. (e.g. periodic
broadcasts of revision numbers and UUIDs, sums of collections of revisions,
etc.).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add an ‘RPC pain multiplier’ option that just causes all calls to the
neutron server to be duplicated X number of times. That way we can set
it to something like 200 for the gate which will force us to make every
call reasonably performant.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allow the HTTP API to perform compare and swap updates by placing an if-match
header with the revision number, which would cause the update to fail if
the version changed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The grenade partial job will be important to ensure we maintain our N-1
backward compatibility with agents from the previous release.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API tests will be added to ensure the basic operation of the revision numbers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functional and unit tests to test the agent reactions to payloads&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Devref guidelines on the pattern for getting information to agents and what
the acceptability criteria are for calls to the server.&lt;/p&gt;
&lt;p&gt;RPC callbacks devref will need to be updated with notification strategy.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/doc/source/devref/rpc_callbacks.rst"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/doc/source/devref/rpc_callbacks.rst&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://www.rabbitmq.com/semantics.html#ordering"&gt;https://www.rabbitmq.com/semantics.html#ordering&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description><pubDate>Thu, 17 Sep 2015 00:00:00 </pubDate></item><item><title>add-neutron-extension-resource-timestamp</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/newton/add-neutron-extension-resource-timestamp.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/add-neutron-extension-resource-timestamp"&gt;https://blueprints.launchpad.net/neutron/+spec/add-neutron-extension-resource-timestamp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron extension resource models like router, floatingip, securitygroup and
securitygroup rules should include timestamp fields “created_at” and
“updated_at”. The fields can make the monitoring changed resource task easier.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Users may be interested in monitoring Neutron extension resources or collecting
statistics on a group of resources in a specific time-frame, for instance,
querying routers that have changed or refreshed in the last several seconds.
In Neutron, we do not have timestamp fields to support this requirement.&lt;/p&gt;
&lt;p&gt;For another example, when a router interface had been updated, the notify
info should be sent to l3 agent, but it cannot know whether the router had
been updated if the message lost. In Neutron, there is no way to vertify
the info had been arrived or lost.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;We propose to add created_at and updated_at fields to resource standardattr
models. In the sqlalchemy model definition, “default” argument is set to
timeutils.utcnow() for created_at and updated_at, so when a resource is
created, sqlalchemy will automatically fill these two fields with the timestamp
the resource is created; “onupdate” argument is also set to timeutils.utcnow()
for updated_at so when a resource is updated, updated_at will be refreshed.
All the timestamp field operations are finished in the database side, so there
is no extra work needed in the plugin side. If the way below is not work well,
we can add the timestamp fields to sqlalchemy model when the creation of
extension resources, and the same as the updated_at.&lt;/p&gt;
&lt;p&gt;Based on these two fields, changed_since filter is introduced for retrieving
resources. It accepts a timestamp and Neutron will return resources with
updated_at field later than this timestamp.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;Currently, HasStandardAttributes model had contained created_at and updated_at.
We could reuse the timestamp_core code to implement. This change won’t impact
on other models which contain standard attributes.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Attribute name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Default Value&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;created_at
updated_at&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;DateTime
DateTime&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;timeutils.utcnow()
timeutils.utcnow()&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Y
Y&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R
R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Timestamp resource is created
Timestamp resource is updated&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;As discussed above, these two fields are maintained by sqlalchemy in Neutron
server. It’s not necessary for users to pass these two values when creating or
updating resource, so only Read operation in CRUD is provided.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Created_at and updated_at will be returned when users issue resource retrieving
requests.&lt;/p&gt;
&lt;p&gt;Resources list API will accept new query string parameter changed_since. Users
can pass timestamp of ISO 8601 format to the list API uri to retrieve resources
operated since a specific time.&lt;/p&gt;
&lt;p&gt;Take router as an example, the request uri looks like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET /v2.0/routers?change_since=2015-07-31T00:00:00
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"router"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"external_gateway_info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"network_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"85d76829-6415-48ff-9c63-5c5ca8c61ac6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"external_fixed_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"subnet_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"255.255.255.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"192.168.10.2"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"router1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"admin_state_up"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"d6554fe62e2f41efbb6e026fad5c1542"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"routes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"a07eea83-7710-4860-931b-5fe220fae533"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2015-07-31T11:50:05"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2015-07-31T11:51:12"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;Neutron python client may add help to inform users the new filter. Neutron
python client supports dynamic assigning search fields so it is easy for it to
support this new filter. Also Neutron python client needs to add the two new
fields when displaying resource information.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Performance of syncing resource status with other systems like a monitor system
or a user interface can be improved. Instead of retrieving all the resources in
every syncing period to update resource status, these systems can just retrieve
resources updated during the syncing interval using changed_since filter.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;NTP service needs to be configured and started to synchronize time among nodes,
so the timestamps saved in created_at and updated_at are valid across nodes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change will bring facility to monitor Neutron resources. Actually most
projects in OpenStack like &lt;a class="reference external" href="https://github.com/openstack/nova/blob/master/nova/db/sqlalchemy/models.py#L43"&gt;Nova&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id1" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; have timestamp fields to track the operation
time of resources.&lt;/p&gt;
&lt;p&gt;One problem of absolute timestamp is that sudden system time change caused by
attack or failure will make the previous cached timestamp invalid. Seeking a
relative timestamp storing strategy may be a better choice, but it’s out of
the extent of this blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="mailto:zhaobo6%40huawei.com"&gt;zhaobo6&lt;span&gt;@&lt;/span&gt;huawei&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update database schema&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add API filter&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update neutron client to support the new filter&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Test if created_at and updated_at can be correctly initiated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test if updated_at can be correctly written when resource updated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test if changed_since filter can be correctly applied.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Test if the new filter can be correctly parsed and validated.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Update Neutron API reference.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Update developer documentation to introduce the new filter.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id1" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/nova/blob/master/nova/db/sqlalchemy/models.py#L43"&gt;https://github.com/openstack/nova/blob/master/nova/db/sqlalchemy/models.py#L43&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Wed, 16 Sep 2015 00:00:00 </pubDate></item><item><title>Security group extension support in PLUMgrid plugin</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/plumgrid-plugin-security-groups.html</link><description>

&lt;p&gt;Launchpad blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/plumgrid-plugin-security-groups"&gt;https://blueprints.launchpad.net/neutron/+spec/plumgrid-plugin-security-groups&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Proposal to add security group extension in PLUMgrid plugin.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, PLUMgrid plugin does not support security group extension. This
feature is required to support PLUMgrid security policy framework and provide
all the functionality exposed in security group API extensions today.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Introduce Neutron security group extension in PLUMgrid plugin. This will
include support for all existing security group and rules APIs:
1) CRUD operations for security groups
2) CRUD operations for security group rules&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None - Existing data model will suffice here.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;PLUMgrid provides a security policy framework which offers all the
functionality exposed in security group extension APIs. Mapping of Neutron
security groups fits well in the subset of cababilities provided by PLUMgrid.&lt;/p&gt;
&lt;p&gt;All the existing worklows supported by Neutron API[1] or python-neutron
client[2] will be suppoted.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Fawad Khaliq &amp;lt;fawadkhaliq&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Extension code in PLUMgrid plugin
Unit test cases for PLUMgrid plugin
PLUMgrid CI update to enable security group testing&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Covered in PLUMgrid plugin unit testing
Leverage existing Tempest infra and run as part of PLUMgrid CI&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] Neutron Security Groups Extension API Reference
&lt;a class="reference external" href="http://docs.openstack.org/api/openstack-network/2.0/content/security_groups.html"&gt;http://docs.openstack.org/api/openstack-network/2.0/content/security_groups.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[2] Security Groups Operations Admin Guide
&lt;a class="reference external" href="http://docs.openstack.org/admin-guide-cloud/networking_adv-features.html#security-groups"&gt;http://docs.openstack.org/admin-guide-cloud/networking_adv-features.html#security-groups&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 02 Sep 2015 00:00:00 </pubDate></item><item><title>Add Tags to Neutron Resources</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/add-tags-to-core-resources.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/add-tags-to-core-resources"&gt;https://blueprints.launchpad.net/neutron/+spec/add-tags-to-core-resources&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron resources in current DB model do not contain any tags, and
don’t have a generic consistent way to add tags or/and any other data
by the user.
Tagging resources can be used by external systems or any other
clients of the Neutron REST API (and NOT backend drivers).&lt;/p&gt;
&lt;p&gt;The following use cases refer to adding tags to networks, but the same
can be applicable to any other Neutron resource:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Ability to map different networks in different OpenStack locations
to one logically same network (for Multi site OpenStack)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ability to map Id’s from different management/orchestration systems to
OpenStack networks in mixed environments, for example for project Kuryr,
map docker network id to neutron network id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Leverage tags by deployment tools&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;allow operators to tag information about provider networks
(e.g. high-bandwith, low-latency, etc)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;new features like get-me-a-network or a similar port scheduler
could choose a network for a port based on tags&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;In most popular REST API interfaces, objects in the domain model can be
“tagged” with zero or more simple strings. These strings may then be used
to group and categorize objects in the domain model.&lt;/p&gt;
&lt;p&gt;In order to align Neutron’s REST API with the Internet’s common understanding
of &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Tag_(metadata)"&gt;resource tagging&lt;/a&gt;, we can add an API that allows normal users
to add, remove and list tags for a neutron resource.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This spec is for adding a new way for &lt;em&gt;API users&lt;/em&gt; to be able to tag
their neutron resources with simple strings.&lt;/p&gt;
&lt;p&gt;Add an API that allows a user to add, remove, and list tags for a resource.&lt;/p&gt;
&lt;p&gt;Similar to the approved nova spec &lt;a class="reference external" href="http://specs.openstack.org/openstack/nova-specs/specs/liberty/approved/tag-instances.html"&gt;tag instances&lt;/a&gt;, and in accordance to
these &lt;a class="reference external" href="http://specs.openstack.org/openstack/api-wg/guidelines/tags.html"&gt;guidelines&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This spec proposes to support adding tags to Neutron resources which
are not meant to be interpreted by any specific backend implementation.
In the proposed implementation tags will only be visible in the API level and
not be available in the plugin level.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;The tag is an opaque string and is not intended to be interpreted or
even read by the Neutron backends.&lt;/p&gt;
&lt;p&gt;For the database schema, the following table constructs would suffice:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;standard_attribute_id&lt;/span&gt; &lt;span class="n"&gt;BIGINT&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt; &lt;span class="n"&gt;FOREIGN&lt;/span&gt; &lt;span class="n"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt; &lt;span class="n"&gt;CHARACTER&lt;/span&gt; &lt;span class="n"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;utf8&lt;/span&gt;
     &lt;span class="n"&gt;COLLATION&lt;/span&gt; &lt;span class="n"&gt;utf8_ci&lt;/span&gt; &lt;span class="n"&gt;PRIMARY&lt;/span&gt; &lt;span class="n"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For example adding a tag “blue” to network with standard_attribute_id 16 will
introduce the following entry:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;standard_attribute_id : 16
tag: “blue”&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;REST API examples can be found in the next section.&lt;/p&gt;
&lt;p&gt;In this table schema the tag is a string value attached to this resource.&lt;/p&gt;
&lt;p&gt;Neutron implementation now have a common resource object for every type which
is saved in the DB. view &lt;a class="reference external" href="https://review.openstack.org/#/c/222079/"&gt;common neutron object&lt;/a&gt; for more details.
standard_attribute_id reference the Neutron resource entry in that common table
for every tag entry we add.
Adding this references in the entry can help us keep data integrity
and make sure that all references for a specific resource are deleted
when the resource itself is deleted.&lt;/p&gt;
&lt;p&gt;Authorization to manage the tag equates with that for the resource which the
tag is attached.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;The tag CRUD operations API would look like the following:&lt;/p&gt;
&lt;p&gt;A list of tags for the specified network returns with the network details
information&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;networks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;network_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;network_id&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="s1"&gt;'tags'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'foo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'bar'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'baz'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Get &lt;strong&gt;only&lt;/strong&gt; a list of tags for the specified network&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET /V2.0/networks/{network_id}.json?fields=tags
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'tags'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'foo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'bar'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'baz'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace set of tags on a network&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;networks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;network_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;with request payload&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'tags'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'foo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'bar'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'baz'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'tags'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'foo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'bar'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'baz'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If the number of tags exceeds the limit of tags per network, shall return
a &lt;cite&gt;400 Bad Request&lt;/cite&gt;
(tags limit is either hard coded or configurable in neutron conf file)&lt;/p&gt;
&lt;p&gt;Add a single tag on a network&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;networks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;network_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Returns &lt;cite&gt;201 Created&lt;/cite&gt;.&lt;/p&gt;
&lt;p&gt;If the tag already exists, no error is raised, it just returns the
&lt;cite&gt;409 Conflict&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;Check if a tag exists or not on a network&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;networks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;network_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Returns &lt;cite&gt;204 No Content&lt;/cite&gt; if tag exist on a network.&lt;/p&gt;
&lt;p&gt;Returns &lt;cite&gt;404 Not Found&lt;/cite&gt; if tag doesn’t exist on a network.&lt;/p&gt;
&lt;p&gt;Remove a single tag on a network&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;networks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;network_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Returns &lt;cite&gt;204 No Content&lt;/cite&gt; upon success. Returns a &lt;cite&gt;404 Not Found&lt;/cite&gt; if you
attempt to delete a tag that does not exist.&lt;/p&gt;
&lt;p&gt;Remove all tags on a network&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;networks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;network_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Returns &lt;cite&gt;204 No Content&lt;/cite&gt;.&lt;/p&gt;
&lt;p&gt;The API that would allow searching/filtering of the &lt;cite&gt;GET /v2.0/networks&lt;/cite&gt;
REST API call would add the following query parameters:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;tags&lt;/cite&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;tags-any&lt;/cite&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;not-tags&lt;/cite&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;not-tags-any&lt;/cite&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To request the list of networks that have a single tag, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tags&lt;/span&gt;&lt;/code&gt; argument
should be set to the desired tag name. Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET /v2.0/networks?tags=red
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To request the list of networks that have two or more tags, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tags&lt;/span&gt;&lt;/code&gt;
argument should be set to the list of tags, separated by commas. In this
situation the tags given must all be present for a network to be included in
the query result. Example that returns networks that have the “red” and “blue”
tags:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET /v2.0/networks?tags=red,blue
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To request the list of networks that have one or more of a list of given tags,
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tags-any&lt;/span&gt;&lt;/code&gt; argument should be set to the list of tags, separated by
commas. In this situation as long as one of the given tags is present the
network will be included in the query result. Example that returns the networks
that have the “red” or the “blue” tag:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET /v2.0/networks?tags-any=red,blue
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To request the list of networks that do not have one or more tags, the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;not-tags&lt;/span&gt;&lt;/code&gt; argument should be set to the list of tags, separated by commas.
In this situation only the networks that do not have any of the given tags will
be included in the query results. Example that returns the networks that do not
have the “red” nor the “blue” tag:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET /v2.0/networks?not-tags=red,blue
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To request the list of networks that do not have at least one of a list of
tags, the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;not-tags-any&lt;/span&gt;&lt;/code&gt; argument should be set to the list of tags,
separated by commas. In this situation only the networks that do not have at
least one of the given tags will be included in the query result. Example that
returns the networks that do not have the “red” tag, or do not have the “blue”
tag:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET /v2.0/networks?not-tags-any=red,blue
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tags&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tags-any&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;not-tags&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;not-tags-any&lt;/span&gt;&lt;/code&gt; arguments can be
combined to build more complex queries. Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET /v2.0/networks?tags=red,blue&amp;amp;tags-any=green,orange
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;The above example returns any networks that have the “red” and “blue” tags,&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;plus at least one of “green” and “orange”.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Complex queries may have contradictory parameters. Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET /v2.0/networks?tags=blue&amp;amp;not-tags=blue
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In this case we should let Neutron find these networks. Obviously
there are no such networks and Neutron will return an empty list.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="cli-examples"&gt;
&lt;h3&gt;CLI Examples&lt;/h3&gt;
&lt;p&gt;The following examples are used to illustrate how the CLI for adding/deleting/searching tags
might look like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="n"&gt;blue&lt;/span&gt;
&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="n"&gt;blue&lt;/span&gt;
&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="n"&gt;blue&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Sun, 23 Aug 2015 00:00:00 </pubDate></item><item><title>add-resource-timestamp</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/add-port-timestamp.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/Neutron/+spec/add-port-timestamp"&gt;https://blueprints.launchpad.net/Neutron/+spec/add-port-timestamp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Resource models like network, subnet and port in Neutron should include
timestamp fields “created_at” and “updated_at”. These two fields can
facilitate the task of monitoring resource changes, which are time-consuming
and inefficient currently.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;End users may be interested in monitoring Neutron resources or collecting
statistics on a group of resources in a specific time-frame, for instance,
querying ports that have changed or refreshed in the last 5 seconds in a
large scale application. In Neutron, we do not have timestamp fields
associated with resources, so there is no way we can query them based on
their operational time.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;We propose to add created_at and updated_at fields to resource models. In the
sqlalchemy model definition, “default” argument is set to timeutils.utcnow()
for created_at and updated_at, so when a resource is created, sqlalchemy will
automatically fill these two fields with the timestamp the resource is created;
“onupdate” argument is also set to timeutils.utcnow() for updated_at so when a
resource is updated, updated_at will be refreshed. All the timestamp field
operations are finished in the database side, so there is no extra work needed
in the plugin side.&lt;/p&gt;
&lt;p&gt;Based on these two fields, change_since filter is introduced for retrieving
resources. It accepts a timestamp and Neutron will return resources with
updated_at field later than this timestamp.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;Two new attributes are added to resource model:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Attribute name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Default Value&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;created_at
updated_at&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;DateTime
DateTime&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;timeutils.utcnow()
timeutils.utcnow()&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Y
Y&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R
R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Timestamp resource is created
Timestamp resource is updated&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;As discussed above, these two fields are maintained by sqlalchemy in Neutron
server. It’s not necessary for users to pass these two values when creating or
updating resource, so only Read operation in CRUD is provided.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Created_at and updated_at will be exposed to users via extension API. If plugin
supports, they are returned when users issue resource retrieving requests.
Also, resources list API accepts new query string parameter change_since. Users
can pass timestamp of ISO 8601 format to the list API uri to retrieve resources
operated since a specific time.&lt;/p&gt;
&lt;p&gt;Take port as an example, the request uri looks like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET /v2.0/ports?changed_since=2015-07-31T00:00:00
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and response:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"ports"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"allowed_address_pairs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
            &lt;span class="s2"&gt;"admin_state_up"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"network_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"70c1db1f-b701-45bd-96e0-a313ee3430b3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"extra_dhcp_opts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
            &lt;span class="s2"&gt;"device_owner"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"network:router_gateway"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"mac_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"fa:16:3e:58:42:ed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"fixed_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"subnet_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"008ba151-0b8c-4a67-98b5-0d2b87666062"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"ip_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"172.24.4.2"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"d80b1a3b-4fc1-49f3-952e-1e2ab7081d8b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"security_groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
            &lt;span class="s2"&gt;"device_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"9ae135f4-b6e0-4dad-9e91-3c223e385824"&lt;/span&gt;
            &lt;span class="s2"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2015&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;07&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="n"&gt;T11&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;05&lt;/span&gt;
            &lt;span class="s2"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2015&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;07&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="n"&gt;T11&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;Neutron python client may add help to inform users the new filter. Neutron
python client supports dynamic assigning search fields so it is easy for it to
support this new filter. Also Neutron python client needs to add the two new
fields when displaying resource information.&lt;/p&gt;
&lt;p&gt;Take port as an example, the command looks like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;changed&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;since&lt;/span&gt; &lt;span class="mi"&gt;2015&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;07&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="n"&gt;T00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Performance of syncing resource status with other systems like a monitor system
or a user interface can be improved. Instead of retrieving all the resources in
every syncing period to update resource status, these systems can just retrieve
resources updated during the syncing interval using change_since filter.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;NTP service needs to be configured and started to synchronize time among nodes,
so the timestamps saved in created_at and updated_at are valid across nodes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change will bring facility to monitor Neutron resources. Actually most
projects in OpenStack like &lt;a class="reference external" href="https://github.com/openstack/nova/blob/master/nova/db/sqlalchemy/models.py#L43"&gt;Nova&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id1" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, &lt;a class="reference external" href="https://github.com/openstack/cinder/blob/master/cinder/db/sqlalchemy/models.py#L35"&gt;Cinder&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id3" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; have timestamp fields to track
the operation time of resources.&lt;/p&gt;
&lt;p&gt;One problem of absolute timestamp is that sudden system time change caused by
attack or failure will make the previous cached timestamp invalid. Seeking a
relative timestamp storing strategy may be a better choice, but it’s out of
the extent of this blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="mailto:caizhiyuan1%40huawei.com"&gt;caizhiyuan1&lt;span&gt;@&lt;/span&gt;huawei&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;TBD&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update database schema&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add API filter&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add related test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update neutron client to support the new filter&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Test if created_at and updated_at can be correctly initiated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test if updated_at can be correctly written when resource updated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test if change_since filter can be correctly applied.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Test if the new filter can be correctly parsed and validated.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Update Neutron API reference.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Update developer documentation to introduce the new filter.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id1" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/nova/blob/master/nova/db/sqlalchemy/models.py#L43"&gt;https://github.com/openstack/nova/blob/master/nova/db/sqlalchemy/models.py#L43&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id3" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/cinder/blob/master/cinder/db/sqlalchemy/models.py#L35"&gt;https://github.com/openstack/cinder/blob/master/cinder/db/sqlalchemy/models.py#L35&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Mon, 10 Aug 2015 00:00:00 </pubDate></item><item><title>Service Flavor Framework</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/neutron-flavor-framework.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-flavor-framework"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-flavor-framework&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This specification details a framework to enable Operators to configure and
Users to select from different abstract representations of a service
implementation in Neutron. The representation decouples the logical
configuration from its instantiation allowing support of multiple possible
implementations to coexist. Decoupling also enables Operators to create user
options according to deployment needs. This proposal does not require any
significant driver integration to implement.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The service provider framework allows services to be backed by multiple
drivers; however there are several limitations with the current approach. The
limitations include:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Operators cannot modify the deployment without user knowledge.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operators cannot easily configure different service levels for same driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operators cannot transparently deploy a service in multi-vendor environment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operators cannot easily reschedule service to another backend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operators cannot influence the scheduling during backend selection.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Users must be aware of the driver implementing the service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vendors cannot differentiate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extensions cannot be easily exposed to the user via REST API.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposed solution is to introduce two new logical entities exposed via the
REST API to decouple the logical configuration from the backend implementation.
The first entity is called Flavor and is an operator curated description of the
backend implementation. Flavor’s attributes include id, name, extension list,
service, service profiles, selection algorithm and enabled flag. The extension
list is used to enable additional REST API functionality for logical
configurations associated with the flavor. An example would be enabling TLS
and/or L7 for load balancing. Users are allowed to query and view the public
attributes of the flavor. The selection algorithm determines the service
profile and the driver schedules the instance to the backend.&lt;/p&gt;
&lt;p&gt;The second entity is Service Profile which has attributes of id, name,
entry point, driver initialization metadata and enabled flag. The Service
Profile enables an operator to associate the driver entrypoint with metadata
necessary to initialize the driver. A benefit of metadata is that the same
driver may back different flavors definitions. Multiple service profiles may be
associated with the same flavor to enable multi-vendor/multi-driver
environments.&lt;/p&gt;
&lt;p&gt;This extension will introduce a new RPC method in the core server. The method
will handle scheduling the logical instance onto the backend. Scheduling will
involve binding the logical configuration to a backend with capacity. Once
scheduled, the plugin will directly dispatch calls to the driver. The
scheduling method implementation will be intentionally kept simple to enable
this work to be completed within the cycle. Future work may include a more
advanced scheduler by incorporating Gantt (a project to make the Nova scheduler
available to other OpenStack components) and/or developing a method for
backends to express load/capacity. Auto-rescheduling and instance health
monitoring are outside the scope of this change and are the responsibility of
the driver. Operators also retain control over cost and scheduling via their
selection of the service profiles.&lt;/p&gt;
&lt;p&gt;While flavors and service profiles could be stored in configuration files, this
spec proposes to store the entities in the database. Storage in a relational
database ensures atomicity and consistency across neutron servers and workers
by avoiding configuration deployment races. Additionally, an operator may
add/update/delete flavors without system downtime. (Note: Flavor and service
profiles may not be changed or removed if in use).&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;User Workflow&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Users will query for a list of enabled flavors filtered by service. The
user will then create the logical entity for the service passing the
flavor id. The user workflow will be unchanged after this time.
If a flavor is selected with multiple service profiles, the profile is
selected via a weighted random algorithm (see below.)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Admin Workflow&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;An admin knowing the hardware/software versions within the deployment will
create flavors to offer. The operator will choose the extensions that a
flavor will support and ensure the appropriate service profiles are
associated.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Future work includes tenant specific flavors and advanced scheduling
(integration into Gantt project and/or filters).&lt;/p&gt;
&lt;p&gt;This proposal enables vendor differentiation since flavor definitions may
include vendor API extensions that the operator may choose to enable.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;Two new logical models will be added to the database.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Flavor&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;id: uuid
name: string
description: text
service: LOADBALANCER, VPN, FIREWALL, L3_ROUTER, etc
supported_extensions: comma separated value string
selection_algorithm: Enum(random, available, least_used)
service_profiles: [(uuid list, weight)] (JSON list)
enabled: boolean&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Service Profile&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;id: uuid
description: text
driver: string
metainfo: string(json encoded dict)
enabled: boolean&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The existing provider attribute will be changed to service_profile_id and used
to associate the root of the service’s logical model with the profile.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;The new logical models will be exposed via the API. The logical model
CRUD operations will only be exposed to administrators with the exception of
read operations on Flavor. All users will be able to query and get the details
on a single flavor with a limited set of attributes (id, name, description,
service and service extensions). Additionally, one administrative action will
be added to each service: reschedule(id). This action will enable an operator
to force the system to reschedule the backend for a logical service.&lt;/p&gt;
&lt;p&gt;FLAVORS (/flavors):&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all
RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all
RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;human-readable
name&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all
RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;human-readable
description&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;service&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all
RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;token mapping
flavor to svc&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;service_profiles&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all
RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[]&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;json list&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;driver mapping
with weight&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;supported_extensions&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all
RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;available api
extensions&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;selection_algorithm&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;enum&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all
RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;random&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;see model&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;how to select
profile&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;enabled&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all
RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;true&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;toggle&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;SERVICE_PROFILES (/service_profiles):&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string
(UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all
RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all
RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;human-readable
description&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;driver&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all
RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;python module
path to driver&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;metainfo&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all
RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;json string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;meta data&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;enabled&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all
RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;true&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;toggle&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;The policy.json will be updated to allow all users to query the flavor
listing and requst details about a specific flavor entry. All other REST
points for create/update/delete operations will admin only. Additionally, the
CRUD operations for Service Profiles will be restricted to administrators.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;The content of current notifications will change minimally to add a new flavor
attribute. This attribute will be used for applications such as billing and can
be captured by Ceilometer. The provider attribute will be retained for
operators that wish to track the user’s flavor and backend.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There will be a minimal overhead incurred when the logical representation is
scheduled onto the actual backend. Once the backend is selected, direct
communications will occur via driver calls.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;The deployer will need to craft flavor configurations that they wish to expose
to their users. During migration the existing provider configurations will be
converted into basic flavor types. Once migrated, the deployer will have the
opportunity to modify the flavor definitions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;The expected developer impact should be minimal as the framework only impacts
the initial scheduling of the logical service onto a backend. The driver
implementations should remain unchanged except for the addition of the capacity
call.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This proposal allows operators to offer services beyond those directly implemented,
and to do so in a way that does not increase community maintenance or burden.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Keep doing nothing.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Doug Wiegley (original spec and code by markmcclain and enikanorov)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement the new models&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement the REST API Extension (including tests)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement the scheduling RPC call.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add support for flavors to LBaaS, VPNaaS, and FWaaS APIs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implementation migration script for existing deployments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensure notifications for Ceilometer are available.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add client API support&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;No dependencies on other work. It should be noted that many other items depend
on flavors.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Tempest testing including new API and scenario tests to validate new entities.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional testing is being excluded from this change because this API
does not directly alter the data path. (Elements that alter the datapath are
covered by other functional test).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;The new API will be tested.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;User documentation will need be included to describe to users how to use
flavors when building their logical topology. Operator documentation will
need to be created to detail how to manage Flavors and Service Profiles.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Additionally, documentation of the new REST endpoints will need to be included
in the Networking API description.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Juno spec gerrit review - &lt;a class="reference external" href="https://review.openstack.org/#/c/102723/"&gt;https://review.openstack.org/#/c/102723/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 08 Jul 2015 00:00:00 </pubDate></item><item><title>LBaaS plugin can delegate VIP allocation to drivers</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/lbaas-driver-vip-delegation.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1463594"&gt;https://bugs.launchpad.net/neutron/+bug/1463594&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently the neutron lbaas plugin will create a neutron port for a VIP and
then pass that information to the driver to continue creation of a load
balancer.  There are some situations in which a driver will require control
of how the VIP is created.  Work on Octavia has brought the realization that
this feature is needed to allow deployments from different providers.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Since the neutron lbaas plugin creates a neutron port as the VIP for drivers
to use, drivers that need to do more complex VIP allocation or drivers that
require the VIP allocation to be delayed further in the workflow will have to
do some untenable workarounds to make work.&lt;/p&gt;
&lt;p&gt;Some examples from a deployers point of view are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Assume an environment in which cells in nova are being used and in which the
VIP is going to be the IP that the nova instance is allocated.  Since cells
are being used, this may mean that the nova scheduler will decide which
segment and subnet the VIP should be allocated from.  If the neutron port is
created before the instance is created, then the segment and/or subnet the
IP was allocated from may cause conflicts with the nova scheduler.  The
cells and network segment are explained and discussed in the RFE [1].&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The VIP allocation may need some external service to do the actual allocation
or extra pre-setup of the VIP, in which case it can’t be created in the
neutron lbaas plugin and would need to be left to the driver to create.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;A non-abstract method will be added in the driver interface.  This way existing
drivers will not need to be changed unless they want to take advantage of this
new ability.  Before the plugin creates the neutron port for the VIP, it will
query the driver and determine whether that new method has been implemented.
If it has been implemented, the driver will call that method and will not
create the neutron port for the VIP.  If it has not been implemented then the
normal port creation and driver call will take place.  Implementing it this way
will not leak implementation details to the user or the deployer as it becomes
just a decision for the driver implementer.&lt;/p&gt;
&lt;p&gt;One minor issue this may cause is if the driver implements the new method
asynchronously.  The method will return without any information of the VIP as
it probably has not been allocated.  This will probably require a thread to
run in the background checking for the allocation and then updating the neutron
lbaas database.  The end user will not see an IP for the VIP immediately upon
return of the create load balancer call.  The population of that field will
end up being delayed, much like how a nova instance does not immediately have
an IP assigned.&lt;/p&gt;
&lt;p&gt;I do think this is an acceptable change to the API behavior
because when the IP is immediately returned, its still not a usable IP until
the load balancer has completed provisioning.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1458890"&gt;https://bugs.launchpad.net/neutron/+bug/1458890&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 17 Jun 2015 00:00:00 </pubDate></item><item><title>Neutron Core and Vendor code decomposition</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/core-vendor-decomposition.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/core-vendor-decomposition"&gt;https://blueprints.launchpad.net/neutron/+spec/core-vendor-decomposition&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Contributing and reviewing existing and/or new vendor code in Neutron is painful
for a number of reasons. We are proposing changes to the existing structure
of the project to address these pain points. More precisely we are promoting
changes in the following areas:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Code structure;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Contribution process: this extends to the following areas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Design and Development;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing and Continuous Integration;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Defect management;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Vendor and community concerns are competing for scarce resources
because our process is currently one-size-fits-all. Holding
plugins/drivers close made sense in the early days, to build the community, but
Neutron has matured as a project.  We have the opportunity to evolve the
relationship between plugin/driver maintainers and the core to ensure that as
a community we can grow ever larger without incurring the bottlenecks and
issues we are currently facing.&lt;/p&gt;
&lt;p&gt;Currently, we have 20+ plugins and 12+ ML2 mechanism drivers. There are
plenty of new plugin/drivers in the pipeline whose specifications and
code contributions need to go through the contribution process where:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;a developer submits a blueprint specification to the neutron-specs repo;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;a developer submits the code patch(es) to the neutron repo;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;at least two members from the core team need to (iteratively) review the spec;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;at least one member of the drivers team needs to approve the spec;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;at least two core reviewers need to (iteratively) review/approve the patch(es);&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This model clearly does not scale because each core can only have limited
knowledge of some parts of the codebase and the sheer amount of vendor-specific
contributions that Neutron as a project has seen so far meant that no single
core reviewer can know it all. This model has also the following issues:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Requires an artificial oversight from the core team, as core reviewers do
not have the ability to fully understand and judge quality of vendor-specific
source, sometimes in the form of interrelated patches made of many
thousands lines of code; granted, a good static code review can help
address issues like styling, use of data structures, algorithms,
modularity, etc, but without the ability to fully understand all the moving
parts it is sometime difficult to assess possible failure modes, potential
bottlenecks, and even why certain fixes after the fact end up being necessary;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Core review may sometimes require playing with the patch, which is made
difficult, if not impossible, by the lack of access to proprietary and/or
external systems;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prevents core reviewer resources from being solely focused on targeting core
concerns of Neutron as a management service;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prevents vendors from having more control over the development and release of
their own code;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prevents vendors from having different levels of engagement with the Neutron
community: the existing model imposes a high acceptance bar. Vendor
developers are invited to actively participate in the day-to-day management
of the project, maintaining their code etc, even though they sometimes fail
to do so. If the code contribution is substantial, it is only customary for
these developers to participate in the cross-cutting issues that may arise
(e.g. gate failures, oslo libraries refreshes, change in style guidelines,
etc); in other words, the current process requires that a vendor generate
goodwill through contribution to non-vendor initiatives such that cores are
willing to review or address vendor’s non-core contributions in a timely
fashion. In an ideal world this would foster community development, but it
presupposes that all vendors have similar resources to devote to Neutron and
that the core team can scale non-linearly (neither of which is the case
today);&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does not promote clear separation of concerns, as the code is in one big
bucket;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The maintainance cost of the entire codebase is unevenly distributed across
the Neutron team;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refactoring effort is hindered by the difficulty of handling code that the
developer is not familiar with;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Negatively impacts unit test feedback runtime, as a lot more tests need to run
at once to for a specific change;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All these issues ultimately affects the pace at which the project can evolve.&lt;/p&gt;
&lt;p&gt;It is worth noting that this problem, and potential solutions, may affect
different people in the OpenStack community in different ways. For instance:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;OpenStack Infra: what tooling would the team need to provide to help the
project? Would they be impacted on a regular basis because of a change
in the way the project decides to organize itself?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vendor Developers: how can a developer get his/her changes merged faster
and with minimal overhead? Writing better code and participating more in
core reviews certainly helps, but this is a bar that not every contributor
can or is willing to set for himself/herself;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vendor Marketeers: how can a marketeer claim that his/her vendor plugin is
OpenStack friendly? In this particular regard, the fact that vendor plugins
are shipped as ‘compatible’ with OpenStack is largely independent from the
code’s origin. The perception that things in openstack.org trunk are
‘good’ is in reality a misconception, and as such it is a task for the
marketing team(s) to fix it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Distros: how can a distro package Neutron by capturing the code necessary,
their external depedencies, and provide configuration tools that allow for
easy consumption of the solution?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron developers: how can a developer support (non)vendor code
contributions without burning out?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operators: do they even care so long as they can get access to a stable,
upgradable and well documented product?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Technical Committee: would the TC members promote this effort,
so long as OpenStack ideals like Openness, Transparency, Commonality,
Integration and Quality are still enforced? As far as openness is concerned,
any new project arrangement must guarantee that the four opens are still
in place (open source, open design, open development, open community [17]);
TC members also represent the Active Technical Contributor, so it is of
paramount importance for them to alleviate the pain in contributing to
OpenStack;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenStack Foundation: so long as the job of promoting the development,
distribution and adoption of the OpenStack cloud operating system is not
hindered by any attempt at making a project functioning better, they should
actually welcome the effort. The Foundation has also the duty, with the
marketplace on openstack.org, to promote drivers compatibiility and soon
there will also be RefStack [14];&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Having said that, the proposed change will primarily address the development
challenges that the Neutron community faces today, leaving social or marketing
perceptions and concerns thereof, a solution to be sought with guidance of
the OpenStack Foundation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposal being made here is an initial step, and something it has been
deemed attainable in the span of a single release. It is not by all means
the end goal, but a good balance that will let us find the golden mean [5]
in iterations. It is also worth noting that this effort is about the core
plugins, rather than advanced services like Load Balancer, VPN and Firewall.
Spinning off those services will be tracked with a different blueprint [8].&lt;/p&gt;
&lt;section id="high-level-codebase-structure"&gt;
&lt;h3&gt;High Level Codebase Structure&lt;/h3&gt;
&lt;p&gt;We propose that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;em&gt;monolithic plugins&lt;/em&gt;, &lt;em&gt;ML2 MechanismDrivers&lt;/em&gt;, and &lt;em&gt;L3 service plugins&lt;/em&gt;
become integration-only to code that lives outside the tree (more details
provided in the section below); the same applies for any vendor-specific
agents: the only part that will remain in the tree is the agent ‘main’ (a
small python file that imports agent code from the vendor library and
starts it). L3 being an integral part of Neutron core will go through the
same process as core plugins and ML2 drivers. The ‘outside the tree’ can be
anything which the vendor is comfortable with: it may be a stackforge repo
for instance, a tarball, a pypi package, etc. It is then important that this
vendor library be publicly accessible for a number of reasons:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Potential licensing conflicts, that might be solved only by getting access
to the vendor library, but more importantly under no circumstances should
a key OpenStack project like Neutron be encouraging closed source
development of a critical component such a plugin or mechanism driver;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ease of packaging support from distros; even though in most cases, distros
will have a relationship with vendors they want to package and validate,
there may still be pure open source players, that may be interested in
getting to use the undelying technology, should that be open source itself.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A plugin/drivers maintainer team self-governs in order to promote sharing,
reuse, innovation, and release of the ‘out-of-tree’ backbone. It should not
be required for any member of the core team to be involved with this process,
although core members of the Neutron team can be in whichever capacity
necessary for out-of-tree development.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="development-strategy"&gt;
&lt;h3&gt;Development Strategy&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The following elements are suggested to remain in the tree for all plugins
and drivers (called vendor integration hereinafter) - at least in the first
iteration of this effort:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Data models;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extension definitions;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configuration files;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Requirements file targeting vendor code;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Things that do not remain in the tree (called vendor library hereinafter):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Vendor specific logic;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Associated unit tests;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The idea here would be to keep in-tree the plugin/driver code that implements
an API, but have it delegate to out-of-tree code for backend-specific
interactions; the vendor integration will then typically involve minor
passthrough/parsing of parameters, minor handling of DB objects as well as
handling of responses, whereas the vendor library will do the heavylifting and
implement the vendor-specific logic. The boundary between the in-tree layer and
the out-of-tree one should be defined by the maintainer while asking these
types of questions:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If something changes in my backend, do I need to alter the integration
layer drastically? Clearly, the least impact there is, the better the
separation being achieved;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If I expose vendor details (e.g. protocols, auth, e.g.), can easily swap
and replace (e.g. a hardware with a newer version being supplied) without
affecting the integration too much? Clearly, the more reusable the
integration the better separation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Furthermore, we can observe that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Regarding db models, we would like to keep backward compatibility
(for already deployed systems) at the present time. There are a number of
technical points to be addressed before moving db models out of tree
completely, e.g., FK, joined query, db migration for existing deployments
and so on, as currently alembic requires extra work to support multiple db
migration paths onto a single database [16]. This technical challenge can
be dealt with in due course, once the major parts of this proposal have
been completed;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Moving config files elsewhere (or even relying on config autogeneration
capabilities) could be explored as a next step. We have been tracking
config changes with DocImpact flags to ensure that OpenStack Manuals are
kept in sync, and we should not break this model;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The vendor code &lt;em&gt;must&lt;/em&gt; be publicly available via pypi, or public
source repository compatible with pip requirements (if packaging is
desired); this requirements file should not be confused with the Neutron
requirements file that lists all common dependencies); instead it is a
file ‘requirements.txt’ that is located in neutron/plugins/pluginXXX/,
whose content is something along the lines of
‘my_plugin_xxx_library&amp;gt;=X.Y.Z’. Vendors should be responsible
for ensuring that their library did not depend on libraries conflicting
with global requirements, but could include libraries not included
in the global requirements. If the vendor library depended on a python
package not captured in the global requirements, this is no different
by what already happens today and we are not trying to address this
in the scope of this effort.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Versioning can be used to pin vendor code to specific versions;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;For the reference implementation: they will still follow the same model, but
the implementation will remain in tree, due to gating requirements; the
reason being that there is no way to externalize the reference implementation
until we have backwards compatible interfaces in the mix. Having to
coordinate the landing of a breaking change in core neutron repo and a fix
in the reference implementation repo so as to avoid breaking openstack
integration jobs would be an extremely tricky proposition.
The proposal documented here is intended to encourage plugins/drivers to
separate themselves into a part that integrates with Neutron and a part that
integrates with a backend. Given that most breakage is going to be in the
integration with Neutron (which remains in the tree) - and that breakage will
only be allowed when fixes can reasonably be expected to be landed before the
end of cycle (e.g. before milestone2) there should substantially less risk
for non-gating plugins/drivers. Trunk will always work: for breaking changes
that can be detected, we can ensure that at least the in-tree part of plugin
drivers are fixed before merge. Plugin/driver-specific breakage will have to
be fixed by the maintainer of that plugin/driver, but as a community we
should address the potential for that kind of breakage separately.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No DevStack changes required: Devstack already has the right hooks [6,7,10];
moreover, the vendor is in full control of the 3rd party CI environment;
they could just install the needed dependencies out of band, while the CI
is setting up the environment and before stacking. Some of them already do
all sorts of stuff.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For instance a vendor integration module can become as simple as one that
contains only the following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Registering config options;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Registering the plugin class;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Registering the models;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Registering the extensions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For instance:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;    &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;DummyPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db_base_plugin_v2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NeutronDbPluginV2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;                      &lt;span class="n"&gt;your_mixin_here&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;    &lt;span class="n"&gt;supported_extension_aliases&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"the_extension_you_implement"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;    &lt;span class="n"&gt;__native_bulk_support&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;    &lt;span class="n"&gt;__native_pagination_support&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;    &lt;span class="n"&gt;__native_sorting_support&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;        &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DummyPlugin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;register_config_opts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vendor_plugin_init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;    &lt;span class="n"&gt;db_base_plugin_v2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NeutronDbPluginV2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;register_dict_extend_funcs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The Nuage plugin [2, 3] follows a slightly similar approach. Since unit test
must be purely testing the units that make up for the vendor library, they no
longer make sense to be part of the Neutron codebase. Having said that, the
vendor integration should be tested via functional testing. The VMware plugin
was also going down that direction [4], where the plugin definition becomes
purely declarative.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing-strategy"&gt;
&lt;h3&gt;Testing Strategy&lt;/h3&gt;
&lt;p&gt;The testing process will change as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;There will be no unit tests for plugins and drivers in the tree, except the
reference implementation. The expectation is that vendors would run unit test
in their own external library (e.g. in stackforge where Jenkins setup is for
free); For unit tests that validate the vendor library, it is responsibility
of the vendor to choose what CI system they see fit to run them; there is no
need or requirement to use OpenStack CI resources if they do not want to;
ultimately these tests can run as part of the 3rd party CI system [9] that is
currently required, based on specific filters, if necessary. It is noteworthy
that this effort may unveil areas of the core code that turn out to be barely
tested. We should strive to identify those, and improve their coverage so
that, in turn, the improvements can be beneficial for the various
vendor integrations as well, as added/revised tests will exercise the shared
framework;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;3rd Party CI will continue to validate vendor integration with Neutron via
Tempest (e.g. functional testing); 3rd Party CI is a communication mechanism.
This objective of this mechanism  is threefold:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;it communicates to plugin/driver maintainers when someone has contributed
a change that is potentially breaking. It is then up to the a given
maintainer to determine whether the failure is transient or real, and
resolve the problem if it is real;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;it communicates to a patch author that they may be breaking a plugin/driver.
If they have the time/energy/relationship with the maintainer of the
plugin/driver in question, then they can (at their discretion) work to
resolve the breakage;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;it communicates to the community at large whether a given plugin/driver
is being actively maintained.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Gating on 3rd party CI &lt;em&gt;is&lt;/em&gt; a terrible idea, though. It introduces too much
variability into the merge process, and we already have more chaos than we
can handle. The proposal in question attempts to minimize some breakage
by keeping plugin/driver interfaces in-tree. We could add sanity unit tests
of interface integration, but it appears that integration failures should
be more effectively caught at a functional and integration level rather
than unit one. Having said that, nothing outlined here would prevent to
adjust test coverage over time.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="review-and-defect-management-strategies"&gt;
&lt;h3&gt;Review and Defect Management Strategies&lt;/h3&gt;
&lt;p&gt;We propose that:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The same bug management process applies: bugs that affect vendor code can be
filed against the Neutron integration, if the integration code is at fault;
otherwise, the code maintainer may decide to fix a bug without oversight, and
issue a new version pin against the requirements file for the code in question
in case the vendor library is being pinned; it makes sense to require 3rd
party CI for a given plugin/driver to pass when changing their dependency
before merging to any branch (i.e. both master and stable branches);&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The same review process applies: vendor specific code follow the same review
guidelines as any other code in the tree, however, the code being reviewed
strictly applies to integration code or requirements’ version bumps; as for
the vendor library, it becomes an external repo; the vendor can choose anyone
to approve/merge changes in this repo;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The same release process applies: this does not change;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The same security vulnerability process applies: this does not change. However,
since the attack surface is a lot larger for the vendor library, it is most
likely that the vulnerability is found there, and the maintainer will need to
issue a fix according to his/her own procedures; if a vulnerability is found in
the vendor integration, the vulnerability fix will need to follow the same
procedures are defined by OpenStack. Vendor may decide to publish the
vulnerability on LP or any other tracking system: completely up to them.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="blueprint-spec-submission-strategy"&gt;
&lt;h3&gt;Blueprint Spec Submission Strategy&lt;/h3&gt;
&lt;p&gt;We propose that:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Provided vendors adhere to the limited development footprint laid out in the
proposal, they should not be required to follow the spec process for changes
that only affect their vendor integration and library.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Proposal of new vendor plugins and drivers should no longer follow the
spec submission process in place for any other Neutron contribution, so long
as the vendor plugin/driver adopts the guidelines outlined in this proposal.
New contributions could simply be submitted for code review, with the proviso
that adequate documentation and 3rd CI party is supplied at the time of
the code submission. For tracking purposes, the review itself can be tagged
with a Launchpad bug report, marked as wishlist; design documents can still
be supplied in form of RST documents, within the same vendor library repo,
for documentation purposes;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Blueprint specifications for new vendor plugin/drivers that target the
current release cyle for Neutron will therefore be evaluated with the
assumption that this proposal goes ahead, and hence marked for abandonment.
Code submission can still go ahead, and evaluated according to the
guidelines laid out in this proposal. Code inclusion will most likely
considered in time for the third milestone of the cycle to allow enough
time for the core team to adequately demonstrate this proposal in practice.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-strategies"&gt;
&lt;h3&gt;Documentation Strategies&lt;/h3&gt;
&lt;p&gt;There is a sister proposal for docs referenced in [15]. The intention going
forward is that the documentation team will fully document the reference
plugins/drivers and add short sections for vendor plugins and drivers, in
the same spirit promoted by this proposal (about code decomposition). Existing
plugins and drivers will have to add references to additional docs, just like
new ones will, once their vendor integration merges in the Neutron repo.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="adoption-and-deprecation-policy"&gt;
&lt;h3&gt;Adoption And Deprecation Policy&lt;/h3&gt;
&lt;p&gt;We propose that:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;All new (core or L3) plugins and drivers follow this model from Kilo;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is strongly recommended that existing plugins and drivers adopt
this model in the Kilo cycle, and structure the code according the
guidelines outlined above;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No in-tree features can be added to existing plugins and drivers: this
means that the feature of existing plugins/drivers code in the main
Neutron tree will be frozen for the Kilo release; some may argue that the
freeze might not be necessary and we could still rely on some review
best effort. However, it is important to recognize that strict discipline
is required to see this proposal through;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Only critical bug fixes will be permitted to existing plugins and drivers;
ML2 needs to be excluded, at least for now, because we gate on ML2+OVS
which precludes splitting any part of it out in advance of backwards
compatible interfaces being introduced. It is nonetheless proposed that we
refactor the OVS ML2 driver such that the drivers themselves contain the
same minimum footprint proposed for all drivers and that they are cleanly
separated from the backend implementation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Plugins and drivers that are still ‘as is’ (i.e. not complying with this
proposal) at the end of Kilo will be evaluated for deprecation and removal;
maintainers will need to make a positive effort to start this process in
the Kilo timeframe; process well underway but to complete in the Lxxx
will still be acceptable; however, it is paramount that maintainers
prioritize their resources so that the rewriting process is not deferred
until Lxxx, to minimize the impact of the code freeze, and to mitigate the
potential danger of deprecation and removal in time for Mxxx.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Having said that, the deprecation target and freeze will need to be assessed
at the various Kilo milestones, to establish how close to completion this
proposal is, and how far each vendor maintainer is in completing the tasks
outilined in the ‘Work Items’ section below. Should this proposal get the go
ahead, then the clock will be set and actions will be tracked for each plugin,
ML2 driver, as well as the exent of progress being made (e.g. setting up of
repos, patches addressing the relevant code, etc).&lt;/p&gt;
&lt;p&gt;NOTE: No action or lack of engagement from the interested parties will need to
be tracked to ensure that, deprecation is considered a last resort measure.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="summary"&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;The approach being proposed here tackles all the issues (outlined above) that
Neutron developers have grown so tired of; it does so by delegating some
control to the vendor, whilst retaining some of degree of visibility into what
is considered part of the Neutron project.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="faq"&gt;
&lt;h3&gt;FAQ&lt;/h3&gt;
&lt;p&gt;Add your question here and we will try to answer to best way we can:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Q: If ML2 plugin refactoring is pursued by the core team. Code-changes for
the same can affect the interfaces and behaviour of existing large set of
vendor mech-drivers in the neutron tree. So, does the vendor mech-drivers
continue to remain in core tree.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A: The proposal is not to move drivers out of the tree. Rather, the
intention is to encourage a separation of concerns such that plugins and
drivers are as lightweight as possible, and serve primarily to integrate
with libraries external to the tree that provide backend-specific
implementation. This would have the advantage of allowing vendors greater
control over their backend-specific code and and offer the possibility of
allowing changes to plugins/drivers with a lighter-weight process (no spec
process and faster merging).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Q: Wouldn’t it be easier if the three code artifacts (Model, Extensions,
and config files) also lived in the vendor repositories? By leaving the
above three in-tree, the proposal still puts significant burden on the
Neutron cores to review vendor code artifacts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A: Short answer is No, as (hopefully) the artifacts are fairly small and
easy to understand. The long answer is: the effort required for full
separation is considerable. The suggested approach would allow plugin/driver
maintainers to gain control over their efforts faster and with less risk. It
will most likely take the entire cycle to get everyone on board and adjusted
to the new model, which does not require any additional work, like new hooks,
different DB timelines, etc. but just the ‘mechanical’ translation.
Once that is cleared out, we can then focus on refining the model and pursue
further delegation to vendor code.
We also need to consider the migration path: we have a couple of things
to consider on splitting db model: for data models, we need to consider the
db migration path and FK relationship to Neutron core models (networks,
ports, etc). Coming up with a concrete plan on how this can be handled ahead
of this proposal is considered a risk worth deferring. API extensions and
configuration files may be able to be moved out, but it has been considered
useful documentation material, at least for the first iteration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Q: The DB models for each vendors will stay in the main repo. This probably
avoid the alembic challenge for migrations, but it also confuses me a bit
when it comes to synchronizing models in master and versioning how the plugin
library. In other words, if you release a version of a library which requires
changes in the data model, then you will have to wait for data model changes
to merged before pinning Neutron to that version of the library. What should
the process be in this case?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A: Ideally, the model changes are backward compatible, but if they were not,
then, as outlined, the process is still pretty straighforward.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Q: What is the distro packaging strategy? For instance, do we need to define
versioning policy for a vendor plugin module? For example, vendor plugin
module for Kilo should have a version of 2015.1.N?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A: We do not require openstack specific versioning of other python
dependencies, and we should not require it of the plugin/driver dependency
libraries either. We could rely on the per-plugin/driver requirements files
in a given Neutron release to authoritatively determine the version of the
library required for a given plugin/driver for that release, and the version
could be updated on stable branches as required.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Q: It seems that the plugin library maintainer is expected to provide
packaging for the appropriate distros. Is this true?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A: Just as distros are responsible for determining how to package
plugin/driver dependencies today, they would continue to do so under this
proposal. Their job would be made easier by the addition of a plugin/driver
requirements file that could be used to determine plugin/driver dependencies
that currently require manual discovery. The expectation here is that the
plugin business logic will have its own lifecycle in a library which is not
part of OpenStack. The relationship between Neutron and the vendor library
would be for instance the same that there is between Neutron and sqlalchemy.
Therefore versioning for the vendor library can be whatever one sees fit.
The plugin itself however, stays in the main neutron repository, but it is
minimised in a way that it could be just a stub. We will still have a Neutron
“vendor X” plugin for openstack 2015.1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Q: How do we deal with Oslo integrations?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A: When oslo integrations occur, 3rd party CI (and a plugin/driver maintainers
internal testing) should detect any breakage in the external dependencies of
the plugins/drivers. We may want to announce when these kinds of changes are
expected such that plugin/driver maintainers can respond in a timely fashion
and minimize the duration of job failure. Only if plugin/driver maintainers
were completely unresponsive to breaking changes in the Neutron tree would
the possibility exist of those changes making it all the way to production.
Were a maintainer to be that unresponsive, the inclusion of their plugin
in the tree would likely be in question. The aim here is to relieve the core
team of some of the maintainance burder in addressing these types of issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Q: How can we ensure that API’s will not be changed and versioned? Say a
internal method of a mixin is updated - then a vendor overwriting or using
this may miss this. In other words, we do not have stable API’s, therefore
in the current model breaking changes can be prevented by doing a one
sweep-fix-all type of patch. With the model being proposed here, how are we
going to deal with this type of issue?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A: The proposal is to keep as strict a separation as possible between Neutron
and vendor concerns, and continuing to develop our test suite to catch
breakage (API or otherwise) when it occurs. Provided plugin/driver maintainer
is diligent in following up on breakage, the only thing that will change
under this proposal is how fast breakage will be fixed (same patch vs one
patch to Neutron + one patch per external plugin dependency). The fact that
the cost of breakage will be increased could actually be a positive thing if
it can encourage the community to take more care in providing cleaner
separation between concerns (via APIs or otherwise). Today both the
integrated gate and non-gated plugins happen to break from time to time; so
long as there is a prompt reaction to the issue, we do not see this model
exacerbating this issue further. As a matter of fact, CI’s are getting
better and the team is getting better at catching these problems and fixing
them swiftly; all we need is to be engaged!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Q: Can you please elaborate a little more on the governane of new repos?
There is at least 1 maintainer needed. How many minimum number of members?
If there is 1 member, he/she will be committing, reviewing and merging
his/her own code?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A: This proposal does not mandate any kind of governance (or even distribution
via a repo) of a given plugin/driver dependency library. We would continue to
require an in-tree maintainer/point of contact for each plugin/driver, as we
do today, and that maintainer would be responsible for coordinating with
out-of-tree development.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Q: Previously, if there was any change affecting plugins/drivers, it was done
in all the code paths to-be-affected to make sure nothing breaks. However,
with split repos, how to make third party CIs pass on changes which break
vendor code and require a change across two or more repos? Looks like we
will have to override third party CI vote either in Neutron or vendor
plugin/driver repo? If the override is absolutely needed, where should it
be done?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A: 3rd party CI votes but does not gate, and this proposal in no way changes
that. When breaking changes land in the Neutron tree, it will be up to the
plugin/driver maintainers to resolve the breakage on their own timeline. In
the short-term we are introducing coordination overhead by externalizing
backend-specific code, but in the long-term this should encourage a decrease
in coupling that minimizes such costs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Q: How do we define some vendor plugin is a part of OpenStack release? Do we
define it? Defined by third party testing integration? It seems related to
distro packaging policy to some extent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A: We can define whether a plugin is part of a given release is the answer to
the question: ‘does the plugin/driver exist in the Neutron tree?’. The
question that we do need to answer is ‘under what conditions is a
plugin/driver allowed to be in the tree’? We are going to have to rely on a
combination of relationship management (PTL &amp;lt;-&amp;gt; plugin/driver maintainer) and
3rd party CI to answer that question, and this proposal does not need to
answer this question. Some plugins already rely on a variation of the
proposed model, and there does not seem to be any issue with distribution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Q: Should Third party CI result be posted to Neutron core change? We need to
define third party testing requirements?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A: They can choose to do so, if they believe the change may break their
support, but this already happens today; 3rd party CI requirements need to
be clarified regardless of this proposal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Q: Does this proposal make any effort into an ML2 Agent no longer feasible?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A: No, effort into developing an ML2 agent would not be the best use of
community resources. For historic reasons Neutron has grown to be not only a
networking orchestration project but also a reference implemention that is
resembling what some might call an SDN controller. We need to move away from
this model, and for these reasons, pursuing an ML2 agent is no longer viable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Q: What about Linux Bridge?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A: Linux Bridge is not currently the option we choose to focus both the
development and testing; any effort in maintaining it at par with OVS would
require resources that need to be identified and quantified. In lack of those
resources, Linux Bridge has already fallen behind and will not be considered
in the refactoring effort, unless someone else is willing to sponsor it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Q: How do we deal with imports of Neutron specifics (like utility functions,
constants, base artifacts, etc) in the vendor library?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A: External libraries that implement backend-specific interaction for
plugins/drivers are expected to explicitly depend on Neutron to allow them
to reference things like db models, utility functions and constants. Since
the Neutron’s dependency on the external libraries is not explicit
(plugin/driver requirements file will not be considered by pip), a circular
dependency will not result. The model would follow loosely what any OpenStack
project already does when referencing Oslo. When it comes to pinning to a
specific ‘snapshot’ of the core codebase, git hashes could be used. The model
would need to ultimately evolve so that a better demarcartion will occur
between core and vendor specifics, which makes the dependency less of a
potential problem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Q: What if a vendor library uses an API defined in the core?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A: Reuse of some plugin methods by an external library is possible through
dependency injection, which are fancy words for ‘pass a reference to the
plugin to the code that needs to call its methods’.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Q: With this approach, would packagers ignore some of the plugins in tree by
not making a package for their library?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A: Before the split, all plugins were ‘magically’ packaged by distributions,
at least their source code. The packager then explicitely needed to add
‘control’ rules to integrate the various parts together with the OS, and/or
config management tools to reflect the configuration choices in the respective
configuration files. This does not necessarily endorse validity of the
vendor solution on the platform, but packagers were left with no choice but
to follow this route in order to avoid dangling code being packaged and
distributed. With this approach, consuming the actual source code becomes
optional, and it is up to the vendor to decide to continue to preserve the
existing packaging model by pulling from the various sources. In other words,
this opens up the question whether all distributions should consider if it is
worth the effort of shipping plugins that are not explicitely covered by
relationship agreements with vendors. Every distro has different internal
processes for tracking packages and releases, and it sensible that distros
take the appropriate actions to ensure the overall quality of the Neutron
solution they sell and support. We should emphasize that according to this
proposal, long term, some plugins may loose packaging and distribution in the
commercial editions of these distros, but at the same time, open source
initiatives can still go ahead unaffected.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Q: The fact that many vendor-specific plugins/drivers are currently in-tree,
creates the impression that a new vendor has ‘failed’ in some sense if they
do not get their new plugin/driver in tree as well - where ‘failed’ has
various possible connotations including ‘not being guaranteed to work with
OpenStack, and to continue to work as OpenStack evolves’, and ‘not having
demonstrated sufficient engagement with the OpenStack community’. Does this
proposal help in addressing this aspect of code contribution?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A: Absolutely! First of all, let us be clear of one thing: in-tree does not
equate success, and out-of-tree does not equate failure. This is a perception
that somewhat built over time into people’s minds, because of past events
that led to the removal of code of questionable quality or because of lack
of testing (most notably Hyper-V in Nova). Today, the reality is completely
different, OpenStack has evolved and 3rd party CI plays a fundamental role
in establishing the sanity of all the components in motion in an OpenStack
based cloud. Furthermore, with this proposal, the failure for not getting
new vendor support in the tree is mitigated by the fact that it is a lot
easier for the core team to go through the checklist of steps to be taken
to consider a vendor integrated with Neutron, without being encumbered by
the need of going through multiple review cycles to get the plugin/driver
in the tree.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;From an end-user standpoint (the tenant or admin that interact with the Neutron
API); this approach has no impact on them.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Minimal. Depending on how Neutron is consumed, deployers need to pull an
extra dependency, which is the vendor library of the plugin of their choice.
This dependency can be pulled in in various ways, with or without the actual
support from the OS/Distro the deployer is using to consume Neutron.&lt;/p&gt;
&lt;p&gt;It is worth mentioning that this approach empowers the distros (namely the
packagers) to choose where to focus resources more effectively. This means
that they can now choose to target packaging only for specific vendor
solutions more explicitely. Although this may sound like a setback for some,
the benefit of automatic packaging was only giving false reassurance that the
overall Neutron solution was going to be free of supportability issues, or
that it was implicitely validated by either the vendor or the distro. Any
customer should do the appropriate due diligence when adopting the combination
of Neutron+Backend, should they choose to access the overall Neutron solution
via two distinct channels. This proposal does hinder this process.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;As outlined in this proposal.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;Very minimal, or nearly none in terms of diverging drastically from the way
we operate today. As a matter of fact, we believe there will be a positive
community impact:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Cores able to iterate faster on the core;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Better separation of responsibilities;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vendors able to iterate faster into their plugin;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Alternatives could be explored with or without tooling assistance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Increase the number of Neutron cores (1)&lt;/p&gt;
&lt;p&gt;We could allow every vendor to have core(s) reviewers so that they can
approve only their own code (i.e. subtree delegation). This poses an
interesting set of challenges:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;What do we do with new contributors?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What does core developer actually mean?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How can we ensure a coherent standard of code reviews?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rubberstamping from Neutron cores (2)&lt;/p&gt;
&lt;p&gt;Neutron cores can become paper pushers and blindly approve changes
that pertains only to a specific vendor. This poses an interesting
set of challenges:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;How do we ensure that cross-cutting concerns are not overlooked?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How do we ensure that vendor maintainers are still held accountable?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adopt a different decomposition of the source tree&lt;/p&gt;
&lt;p&gt;The existing source tree could be decomposed in separate repositories:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;One repo hosts core elements (DB, API, RPC, etc) and fully open source
implementation of L2/L3 API that is currently gated;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One repo for each vendor, that has contributed one or more (monolithic)
plugin;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One repo for all ML2 mechanism drivers; A vendor that contributed both
a monolithic plugin and an ML2 driver should decide where the ML2 driver
needs to belong;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ideally this is decomposition that makes the most sense, if it was not for
the political and social rules that we are constrained by. In other words,
from a pure software development standpoint, this decomposition makes the
most sense, and any objection to this approach could be overcome with
technical solutions. That said, it may be too hard to pursue this approach
in the span of a single release. It might make sense to reassess this
approach in a release from now, once the codebase has gone through this
initial transformation and other efforts (e.g. advanced service spin-off,
API refactoring, etc.) have been completed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using git submodules to decompose the source tree&lt;/p&gt;
&lt;p&gt;This has been strongly discouraged by OpenStack Infra, because of the
complications of managing git submodules:  not only does it add potential
complications in CI tooling, but it is nearly indistinguishable from using
separate repositories and as such does not really address any of the
concerns raised with separate repositories.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using feature branches&lt;/p&gt;
&lt;p&gt;This could be achieved by using long lived branches (similar to the Linux
kernel model where subteam maintainers have there own branch). Short lived
branches do not really lend themselves to representing the lifespan of a
plugin/driver. Even though one of the perks of feature branches is that
they can own different ACLs so a different group of people can get +2/+W
on them, the drawback to this approach is that it does not promote clear
separation and responsibilities between the various parts of the system.
In other words, if we had stable interfaces between these parties, using
feature branches would not provide any benefits more than having these
parties reside in different repositories.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Commentary&lt;/p&gt;
&lt;p&gt;While approaches 1 and 2 may help address change velocity, they may
ultimately lead to an increased instability of the codebase, they do
not promote cleaner interfaces, and they weight down the Neutron team
that would need to deal with a much, much bigger codebase. In other
words, even though these approaches may make sense in the short term,
they may seriously affect the project in the long run.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;For the reference implementation refactoring, code and test re-org:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Armando Migliaccio&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maru Newby&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For examples of how this proposal develops in practice:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Kevin Benton (Big Switch)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Doug Wiegley (A10)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Kyle Mestery (OpenDayLight ML2 Mech Driver)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Yamamoto Takashi (ofagent)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Gary Kotton (VMware)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;add your name here&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For new plugin/driver that want to pioneer this model:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Sandhya Dasu (Cisco UCS Manager ML2 mech driver)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vivekanandan Narasimhan (OVSvApp [12, 13])&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;add your name here&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Announce new policy and deprecation timeline for existing plugins/drivers;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Separate reference implementation in a similar manner but keep the code in
tree (ML2 OVS mech driver + L3 service pluign with l3-agent, which is what
it is currently gated on); This is of paramount importance in order to
flesh out any remaining technical details and pave the way for vendor code
maintaners to follow in the their own code.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;the plugin becomes the integration point to the bulk of the code held in
something like neutron/reference_code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suggested work items for each vendor:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Setup a repo for hosting the vendor library (stackforge is useful because
it provides jenkins integration); there is no naming convention forced
down on vendors, however, should the stackforge route be pursued, vendor
should avoid naming the repo with explicit reference to Neutron: this
protects the vendor in case new naming issues arise (anyone remembers the
Quantum naming debacle?), and it allows the vendor to have the freedom
to target the same Python bindings for potentially different CMS;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Setup code in new repo: it is worth noting that if code is being copied
out of neutron core and into these drivers, the git subtree tool can
preserve history across this operation. OpenStack infra is doing something
similar with puppet modules on [11];&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Setup unit tests;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Publish code to pypi;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change neutron driver/plugin to import pypi module and remove all vendor
internal logic;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;For more details, see section on Testing Strategy.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;For further details, see section on Documentation Strategies.&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;After this proposal, the overall Neutron system will not change in terms of how it
functions. From a user perspective, once the system has been deployed, configured
and up and running, no difference can be perceived. However, a sibling proposal
has been documented in [15]. Operators will be expected to follow documentation
and/or pointers to external references provided by the Upstream OpenStack docs
to understand how to install and configure the system to use specific plugins and
drivers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;No API change has been proposed here, so providing guidelines for contributing
a plugin/driver will suffice. This proposal already outlined quite extensively
some of the work involved, and will be used as base for the in-tree developer
documentation.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[1]  &lt;a class="reference external" href="https://etherpad.openstack.org/p/aE7ydRU35m"&gt;https://etherpad.openstack.org/p/aE7ydRU35m&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[2]  &lt;a class="reference external" href="https://github.com/openstack/neutron/tree/master/neutron/plugins/nuage"&gt;https://github.com/openstack/neutron/tree/master/neutron/plugins/nuage&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[3]  &lt;a class="reference external" href="https://github.com/openstack/neutron/tree/master/neutron/tests/unit/nuage"&gt;https://github.com/openstack/neutron/tree/master/neutron/tests/unit/nuage&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[4]  &lt;a class="reference external" href="https://github.com/openstack/neutron/blob/master/neutron/plugins/vmware/plugin.py"&gt;https://github.com/openstack/neutron/blob/master/neutron/plugins/vmware/plugin.py&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[5]  &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Golden_mean_(philosophy"&gt;http://en.wikipedia.org/wiki/Golden_mean_(philosophy&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[6]  &lt;a class="reference external" href="https://github.com/openstack-dev/devstack/tree/master/lib/neutron_plugins"&gt;https://github.com/openstack-dev/devstack/tree/master/lib/neutron_plugins&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[7]  &lt;a class="reference external" href="https://github.com/openstack-dev/devstack/tree/master/lib/neutron_thirdparty"&gt;https://github.com/openstack-dev/devstack/tree/master/lib/neutron_thirdparty&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[8]  &lt;a class="reference external" href="https://review.openstack.org/#/c/136835/"&gt;https://review.openstack.org/#/c/136835/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[9]  &lt;a class="reference external" href="http://docs.openstack.org/infra/system-config/third_party.html"&gt;http://docs.openstack.org/infra/system-config/third_party.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[10] &lt;a class="reference external" href="https://review.openstack.org/#/c/137054"&gt;https://review.openstack.org/#/c/137054&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[11] &lt;a class="reference external" href="http://specs.openstack.org/openstack-infra/infra-specs/specs/puppet-modules.html"&gt;http://specs.openstack.org/openstack-infra/infra-specs/specs/puppet-modules.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[12] &lt;a class="reference external" href="https://review.openstack.org/#/c/136091/"&gt;https://review.openstack.org/#/c/136091/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[13] &lt;a class="reference external" href="https://review.openstack.org/#/c/104452/"&gt;https://review.openstack.org/#/c/104452/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[14] &lt;a class="reference external" href="https://wiki.openstack.org/wiki/RefStack"&gt;https://wiki.openstack.org/wiki/RefStack&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[15] &lt;a class="reference external" href="https://review.openstack.org/#/c/133372/"&gt;https://review.openstack.org/#/c/133372/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[16] &lt;a class="reference external" href="https://github.com/stackforge/group-based-policy/tree/master/gbp/neutron/db/migration/alembic_migrations"&gt;https://github.com/stackforge/group-based-policy/tree/master/gbp/neutron/db/migration/alembic_migrations&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[17] &lt;a class="reference external" href="https://wiki.openstack.org/wiki/Open"&gt;https://wiki.openstack.org/wiki/Open&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 14 May 2015 00:00:00 </pubDate></item><item><title>Enable spoofchk control for SR-IOV ports</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/sriov-spoofchk.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/sriov-spoofchk"&gt;https://blueprints.launchpad.net/neutron/+spec/sriov-spoofchk&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Allow user to control setting of MAC spoof checking for the SR-IOV ports.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Support for SR-IOV ports appeared in Neutron Juno and allows allows VMs
to access virtual network via SR-IOV VFs. SR-IOV ports in Linux allow
specification of whether source MAC spoof checking should be enabled or
disabled for them. This can be done, for example, using the ip-link(8) tool:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;ip link set eth0 vf 2 spoofchk off&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;This command disables spoof checking for Virtual Function 2 on
Physical Device ‘eth0’.&lt;/p&gt;
&lt;p&gt;This feature is useful for bonding configurations inside guests.
For example, MAC spoof checking should be disabled for 802.3ad (Dynamic
link aggregation) bonds. Please see the ‘Configuring QoS Features with
Intel Flexible Port Partitioning’ whitepaper for more details, link is
available in the ‘References’ section.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposal is to leverage the port security extension. Specifically, for
‘direct’ types of ports port_security_enabled = False would mean that
spoof checking should be disabled.&lt;/p&gt;
&lt;p&gt;Actual setting for the VF will be done by the sriovnicagent using the ip-link(8)
tool.&lt;/p&gt;
&lt;p&gt;Default value for the spoof checking will be enabled, so the change will not
affect a default behavior.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;That could have a security impact if user disables spoof checking for
a specific port, however it is expected and user can manually decide if
that’s applicable for his configuration.&lt;/p&gt;
&lt;p&gt;As spoof checking is enabled by default, there would be no security impact
with the default setting.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;And user will have a facility to control spoof checking settings on specific
Neutron ports.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;python-neutronclient does not need to be modified&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;It’ll have a slight impact on the sriovagent as it’ll have to run one more
external command (ip-link(8)).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This changes has not been discussed so far.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Another possible way of providing control to user is to introduce
a dedicated attribute for spoof checking instead of ‘port_security_enabled’
from the portsecurity extension. It could be named ‘spoofchk’ and be placed
either into portsecurity extension or into portbindings extension.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;novel&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Modify sriovagent to be able to enable or disable spoof checking based on
user setting&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify on API level and in binding handling routines that sriovagent is
not disabled as it being turned off would not allow to meet user’s
expectation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Tempest tests are not planned currently as SR-IOV hardware is not always
available. 3rd party CI testing could be considered, though probably the
feature is relatively minor for that.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;API tests would be added to cover specifics of port_security for ‘direct’
type of ports.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;User documentation will be updated with information about spoof checking
control for ‘direct’ ports and its security considerations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://www.intel.com/content/www/us/en/network-adapters/10-gigabit-network-adapters/config-qos-with-flexible-port-partitioning.html"&gt;http://www.intel.com/content/www/us/en/network-adapters/10-gigabit-network-adapters/config-qos-with-flexible-port-partitioning.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://www.kernel.org/doc/Documentation/networking/bonding.txt"&gt;https://www.kernel.org/doc/Documentation/networking/bonding.txt&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
</description><pubDate>Wed, 13 May 2015 00:00:00 </pubDate></item><item><title>Improve DVR L3 Agent Binding</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/improve-dvr-l3-agent-binding.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/improve-dvr-l3-agent-binding"&gt;https://blueprints.launchpad.net/neutron/+spec/improve-dvr-l3-agent-binding&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron code does not properly handle scheduling for DVR and often confuses why
a router has been scheduled to an L3 agent, especially in cases where an agent
could host both the centralized and a distributed piece of the router.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;There are two ways that a router gets bound to an L3 agent with DVR.  The first
is for the centralized component of the router and is similar to how legacy
routers are bound.  The second is for the distributed component and should be
very different.  Essentially, a distributed router should be hosted by any L3
agent where the same host has a DVR serviceable port.&lt;/p&gt;
&lt;p&gt;Binding the centralized part of the router is very much like binding a legacy
router.  It should be bound to a network node.  When we want to finally enable
HA and DVR together, then it will be bound to multiple.  It makes sense to give
the operator control over the binding through the api L3 extensions.  Yet, it
is this type of binding for which a new table, CentralizedSnatL3AgentBinding,
was created.&lt;/p&gt;
&lt;p&gt;The other kind of binding shares the same table as legacy router bindings yet
it works very differently.  This binding could be computed from other
information in the database.  Basically, you find all of the DVR serviceable
ports on a network where a router is connected.  The set of agents on the hosts
where these ports are bound is the set of agents to which the router should be
bound.  It doesn’t make sense to give direct control over this type of binding
through the API.  Yet this is the binding that shares the bindings table with
legacy routers.&lt;/p&gt;
&lt;p&gt;Can you see why we’re constantly confused about DVR scheduling?&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposed change is to move the binding of the centralized portion of a
router to share the table with legacy routers and hopefully eliminate the
explicit binding of the distributed parts of the router.&lt;/p&gt;
&lt;p&gt;There is a chance of introducing a performance penalty by eliminating the
explicit binding of the distributed parts of the router in the database.  In
that case, a new table may be added for this type of binding.  However, this
will be a last resort.  Every attempt will be made to optimize queries to
enable working without an extra table.  So far, I don’t think the queries will
be too complex.&lt;/p&gt;
&lt;p&gt;It will be required to change the RPC calls between the L3 agent and the
Neutron server.  The problem is that some L3 agents can host either a
centralized part of the router, a distributed part, or both.  The current RPC
mechanisms make it difficult to distinguish which case it is.  There should be
separate RPC calls to query each type independently.&lt;/p&gt;
&lt;p&gt;The DvrRouter class in the L3 agent will be split in to two classes:  one to
represent the centralized component and another for a distributed component of
the router.  These are two distinct components of the router that share almost
nothing in common and should be handled independently.  Yet, the code is
mingled together and has a track record of confusing which type is relevant.
The L3 agent will keep track of them independently.&lt;/p&gt;
&lt;p&gt;Much of the special case code for scheduling the centralized component of a
router can be removed when these bindings are returned to the
RouterL3AgentBinding table.  The only exception will be in determining eligible
agents; an l3 agent in ‘dvr_snat’ mode can host either a legecy or a dvr
central component but one in ‘legacy’ mode can only host a legacy router.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;RouterL3AgentBinding rows for DVR routers will be removed.  The
CentralizedSnatL3AgentBinding table will be removed.  Before it is removed,
these rows will be migrated to the RouterL3AgentBinding table.&lt;/p&gt;
&lt;p&gt;There are a few scenarios which should be considered:&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Add DVR serviceable port to a host.&lt;/p&gt;
&lt;p&gt;This will be a notification to a specific L3 agent based on the host to
which the port is bound.  A query will be performed to list the router
internal ports on the same network as the port.  The L3 agent should now be
hosting a distributed component for each.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove DVR serviceable port to a host.&lt;/p&gt;
&lt;p&gt;This is essentially the reverse of adding a port.  After deleting the port,
the list of routers the L3 agent should handle may be reduced in which case
the L3 agent should clean up.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L3 Agent requests a list of distributed router components it should be
hosting with details.  It should be able to request a single router in
response to a notification or request a full list.  A query will be
performed to list the networks associated with all of the DVR serviceable
ports on the host.  Then, for each network, the connected routers should be
collected in a set.  The final set should be returned to the agent with
details.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;TODO(Carl) Are there more cases?&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;It will not be possible to modify or view the bindings of the distributed parts
of router because they will come and go as ports on the network come and go.
This should have been the case from the beginning.  It doesn’t change the API
definition but it may affect what is seen through the API.  There was never any
valid use case for manipulating the these bindings through the API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;Notifications will be adjusted where there is any ambiguity between centralized
and distributed parts of routers.  It must be clear to the L3 agent which type
is being notified.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;This change will modify the database model and the queries that find router to
L3 agent bindings.  In the case of the distributed parts of a DVR router the
bindings must be computed by examining the ports on a network.  This is
discussed in more detail in the &lt;a class="reference internal" href="#data-model-impact"&gt;Data Model Impact&lt;/a&gt; section.  Initially, it
looks like there will not be a large performance impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;Distributed virtual routing does not yet benefit IPv6.  The two are expected to
coexist in that a distributed router should be able to handle IPv6 correctly
even if not in a distributed manner.  This blueprint will not break this
capability.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This simplifies DVR a bit making it easier to understand how routers are bound
to L3 agents because it will use a more sensible approach.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;I don’t see an alternative way to make DVR binding easier to understand.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~obondarev"&gt;obondarev&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~carl-baldwin"&gt;carl-baldwin&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Break the DvrRouter class in to two classes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify RPC messages to distinguish between centralized and distributed
components.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify dvr scheduling code&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;TODO Flesh this out a bit&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;No new tempest tests will be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional tests will be developed for the L3 agent to test the handling of
combinations of centralized and distributed router components on an L3 agent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;No new api tests will be added.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Sun, 19 Apr 2015 00:00:00 </pubDate></item><item><title>Lbaas, use Octavia as reference implementation</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/lbaas-ref-octavia.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-ref-octavia"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-ref-octavia&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The lbaas team intends to replace the reference implementation
with the service-vm like implementation provided by project
Octavia[1], which uses nova compute to provide scalability
and HA features.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The existing reference implementation does not scale well,
does not handle HA, is fragile in the face of underlying host failures.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;A neutron-lbaas Octavia driver (or shim) will be added to neutron-lbaas,
which will reference the controller/framework implemented by the Octavia
project[1].&lt;/p&gt;
&lt;p&gt;The existing reference implementation, the namespace haproxy driver, will
remain in the neutron-lbaas tree for Liberty, for upgrades.&lt;/p&gt;
&lt;p&gt;The default driver enabled in the neutron-lbaas.conf file will be Octavia,
a dependency on Octavia will be added to the project requirements file,
and packagers will have to install/deploy Octavia as part of an lbaas install.&lt;/p&gt;
&lt;p&gt;The neutron-lbaas devstack plugin will start installing Octavia automatically.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Upgrades will have to manually choose to switch to Octavia. The old driver
will continue to function.&lt;/p&gt;
&lt;p&gt;New installs will need to pull in and start Octavia.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;The existing reference implementation is not well liked. Hopefully, this
starts to change that perception.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;One alternative is to continue to maintain the existing reference/agent
driver, and keep Octavia present as an option. The extra maintenance cycles
of keeping both drivers prime-time is less desirable by the lbaas team.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Octavia team&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Octavia neutron-lbaas driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tweak requirements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Convert tests to stably run with Octavia.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify devstack plugin&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A working Octavia implemention. The switch will happen no later than the
middle of L-3, and only if Octavia is “complete enough” for production use,
as determined by the services lieutenant and/or the PTL.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Existing tests will exercise the Octavia backend. Additional jobs will be
added to continue testing the namespace/haproxy backend, until it is
removed (schedule TBD.)&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Same as existing.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Same as existing.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Same as existing.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;References to the driver/config settings will need to be updated, as will documentation
on how to check if the right agents are running/troubleshooting.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://github.com/stackforge/octavia"&gt;https://github.com/stackforge/octavia&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Apr 2015 00:00:00 </pubDate></item><item><title>Support external physical bridge mapping in linuxbridge</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/phy-net-bridge-mapping.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/phy-net-bridge-mapping"&gt;https://blueprints.launchpad.net/neutron/+spec/phy-net-bridge-mapping&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This proposal implements physical bridge mapping for linuxbridge-agent.
According to this proposal, linuxbridge-agent will be able to be aware of
external user-defined physical bridges and attach tap devices on it.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The linuxbridge-agent currently creates a bridge for each physical network
used as a flat network, moving any existing IP address from the interface
to the newly created bridge. This is very helpful in some cases, but there are
other cases where the ability to use a pre-existing (user-defined) bridge.&lt;/p&gt;
&lt;p&gt;For instance, the same physical network might need to be bridged for other
purposes, or the agent moving the system’s IP might not be desired or cause
some unexpected error for the pre-defined environment.&lt;/p&gt;
&lt;p&gt;According to some enterprise end-users’ feedbacks, they do need this feature
to make neutron compatible with their pre-defined virtual network environment
due to some security regulations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Add a bridge_mappings configuration variable, similar to that used
by the openvswitch-agent, alongside the current physical_interface_mappings
variable.&lt;/p&gt;
&lt;p&gt;When a physical bridge for a flat network is needed, the bridge mappings would
be checked first. If a bridge mapping for the physical network exists, it would
be used.&lt;/p&gt;
&lt;p&gt;If not, the interface mapping would be used and a bridge for the interface
would be created automatically. Sub-interfaces and bridges for VLAN networks
would continue to work as they do now, created by the agent using the interface
mappings.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Add an option called bridge_mappings in
/etc/neutron/plugins/linuxbridge/linuxbridge_conf.ini.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change is a value-added feature for linuxbridge-agent, and it won’t
affect the current development cycle.&lt;/p&gt;
&lt;p&gt;The implementation is simple and straightforward.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;nick-ma-z&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement the feature&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide unit tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;None. This new feature can be fully covered by unit test cases.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Add an option called bridge_mappings in
/etc/neutron/plugins/linuxbridge/linuxbridge_conf.ini.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;See related bug: &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1105488"&gt;https://bugs.launchpad.net/neutron/+bug/1105488&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 14 Apr 2015 00:00:00 </pubDate></item><item><title>Conntrack zones support</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/conntrack-zones.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/conntrack-in-security-group"&gt;https://blueprints.launchpad.net/neutron/+spec/conntrack-in-security-group&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Network isolation could be broken since security groups created for one
network can affect connectivity between ports of other network if they have
same IP addresses as ports on the initial network.&lt;/p&gt;
&lt;p&gt;Forcing connection close via conntrack by IP will break existing connections
on networks which aren’t related to security group being enforced.&lt;/p&gt;
&lt;p&gt;See [1] for the reference.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The goal is to add support for conntrack zones which allow to handle multiple
connections with equal identities in conntrack and NAT.&lt;/p&gt;
&lt;p&gt;A zone is simply a numerical identifier associated with a network
device that is incorporated into the various hashes and used to
distinguish entries in addition to the connection tuples. Additionally
it is used to separate conntrack defragmentation queues. An iptables
target for the raw table could be used alternatively to the network
device for assigning conntrack entries to zones. See [3] for more information.&lt;/p&gt;
&lt;p&gt;In the case of security groups, each conntrack zone should correspond to a
neutron network. Adding some sort of network identifier makes connection tuple
unique.&lt;/p&gt;
&lt;p&gt;In fact, that is already done in ovs agent, where there is a local vlan mapping.
Exactly the same strategy could be applied to conntrack zones.
Local vlan ids could be used as a conntrack zone id.&lt;/p&gt;
&lt;p&gt;Changes are required in Firewall driver. It should keep current network-to-zone
mapping and apply port firewall rules with this additional parameter.
Upon ovs agent start/restart this mapping could be populated from local vlan
mapping. Changing zone identifies is ok because iptables rules are updated
after ovs agent restart.&lt;/p&gt;
&lt;p&gt;This could also be utilized by other agents such as OFAgent.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;This feature should actually improve security by fixing tenant network isolation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None or insignificant.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;yangxurong&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The implementation for ovs agent. See [2]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functional tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implementations for other affected agents.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional test is required.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1359523"&gt;https://bugs.launchpad.net/neutron/+bug/1359523&lt;/a&gt;
[2] &lt;a class="reference external" href="https://review.openstack.org/#/c/118274/"&gt;https://review.openstack.org/#/c/118274/&lt;/a&gt;
[3] &lt;a class="reference external" href="http://lwn.net/Articles/370152/"&gt;http://lwn.net/Articles/370152/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 09 Apr 2015 00:00:00 </pubDate></item><item><title>Replace home grown WSGI layer with Pecan</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/pecan-switch.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/wsgi-pecan-switch"&gt;https://blueprints.launchpad.net/neutron/+spec/wsgi-pecan-switch&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This document describes a plan to replace the current home-grown WSGI
framework, including REST controllers, with a solution entirely based
on the Pecan framework &lt;a class="footnote-reference brackets" href="#id16" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The specification discussed in this document can make use of the V3
plugin specification, though it is no longer assumed to be dependent
on that specification. See &lt;a class="footnote-reference brackets" href="#id17" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; for more details.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;This specification addresses a number of issues arising from the fact that
Neutron so far has been relying on and evolving its own framework for
managing web service lifecycle and dispatch API operations to plugins.&lt;/p&gt;
&lt;p&gt;Namely:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;API resource definition is performed using dictionaries, which contain
information about object attribute types, default values and attribute
validation. This has a number of limits, especially when it comes to
performing validation and serialization of API resources, and it also
encourages a behavior where everything is passed around as dictionaries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The current API extension management framework implies that extensions
can pretty much do everything they want with the API - even redefining
parts of it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is home grown code based on fork() for managing multiple API workers.
While this is generally not a problem, it still is a significant amount of
code that needs to be maintained. Many REST frameworks like Pecan provide
built-in support for spawning multiple API workers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The REST controllers have become heavyweight components since they also
need to take care of tasks such as enforcing quotas and authorizing
API requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The actual response returned by the REST layer is currently built within
the plugin, because there is no object-oriented interface with the plugin.
Indeed, the REST controller passes the resource to the plugin as a dict,
and expects a resource as a dict from the plugin. It assumes that the plugin
builds a dictionary which respects the resource model (ensuring however
that only valid attributes are returned to the API consumer).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Most importantly, the current WSGI/REST framework is a relatively large
size component in Neutron’s codebase. Switching to a well-established
framework will make the whole codebase a lot more maintainable.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;In a nutshell: replace the existing framework with Pecan, remove the current
code, and ensure that operators are unaffected by the change.&lt;/p&gt;
&lt;p&gt;This means that we expect the following for the Kilo release:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;All API requests will be served by Pecan REST controllers
This will have impact on in-tree attribute extensions. Such extensions
indeed will be refactored as they currently define the resources they
handle using the same dict-based style as attributes.py &lt;a class="footnote-reference brackets" href="#id18" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;
There will therefore be a new process for adding extensions to the Neutron
API. This process will be documented as a part of this blueprint.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Service startup will not happen anymore through Python PasteDeploy, and
will be managed by Pecan. Similarly multiple API workers will be handled
through Pecan as well.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Pecan REST controller will simply take care of serializing responses
and deserializing requests into appropriate transfer objects describing
API resources. Until the V3 plugin layer referenced here &lt;a class="footnote-reference brackets" href="#id17" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; is merged,
REST layer will continue to be responsible for authorization and quota
enforcement.
Request validation will occur in the REST API layer. The goal is to
specify constraints using JSON schema. At the time of writing this spec it
has not yet been analyzed whether it is possible to express all the
validation constraints currently applied to the Neutron API using JSON
schema. The final implementation, which is not necessarily the first
iteration,  might either:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Use JSON schema only&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Embed validation logic in API objects (see &lt;a class="footnote-reference brackets" href="#id17" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; more information)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use a mix of JSON schema and custom validation logic, and possibly
encapsulate everything within API objects.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On the other hand, authentication for a request must happen before the
call is dispatched to the plugin layer. Pecan hooks &lt;a class="footnote-reference brackets" href="#id19" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; will be used to
perform authentication at the appropriate time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Pecan framework however only takes care of managing the REST API
server. For this reason as a part of this blueprint the REST and RPC over
AMQP servers will be split. Potential impacts of this change on deployers
are discussed in the relevant section. This split is not expected to have
any other relevant impact on operators, developers, or users.
The API server and RPC server will communicate via RPC where necessary.
Where async notification tasks need to fire, any notification messages will
be handled by post api call hooks. The notification system will be moving
from being a side-effect of the API layer to part of the plugin layer.
The API can fire off RPC notifications or possibly spawn tasks that execute
on RPC/task flow workers.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;No data model change expected.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Even if this patch has a deep impact on the Neutron management layer, the REST
API itself will not change at all, and will preserve its capabilities in terms
of resources, available operations, filtering, pagination and sorting.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;Radical changes in the framework handling REST API requests always have a
potential security impact.&lt;/p&gt;
&lt;p&gt;In this case, since we are moving away from a home grown framework to one
which is already widely adopted across OpenStack projects, the overall
security level should increase.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;The REST API layer is currently responsible for sending notifications such as
those needed by the Telemetry service. With these change the notifications
will not be handled in the REST API layer anymore, but moved within the plugin
interface as specified in &lt;a class="footnote-reference brackets" href="#id17" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;End users will not even notice the difference between a server running the home
grown framework and one which switched to Pecan.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;No significant impact expected.
We have however no measurement available to justify this claim.&lt;/p&gt;
&lt;p&gt;For this reason performance measurements should be done as part of this
blueprint implementation to ensure that switching to Pecan does not
negatively impact application performance.&lt;/p&gt;
&lt;p&gt;For the purpose of this work, Rally will be used to provide before/after
benchmarks.
If other tools such as OsProfiler are deemed useful, they will be used
as well in the evaluation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;IPv6-related APIs and IPAM capabilities will be unchanged.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;We expect the deployer impact to be minimal.
The main difference introduced by this change, from a deployer perspective
is the fact that the HTTP server will be split from the AMQP server.&lt;/p&gt;
&lt;p&gt;For green-field deployments this will not be a problem at all.
It will also provide deployers with the desirable option of deploying the
HTTP and AMQP servers on different nodes.&lt;/p&gt;
&lt;p&gt;For existing deployments, updates should be smooth and transparent.
The only difference would be that after an upgrade there would not be
a single neutron server service, but two - one for the REST API, and one
for RPC over AMQP.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;New extensions will need to be developed in a different way.
This will be thoroughly documented in developer documentation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;Moving away from the home-grown framework will allow the community to focus
exclusively on Neutron’s business logic. Moreover, members of the Neutron
community will also be encouraged to contribute back to Pecan.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Other solutions such as Falcon &lt;a class="footnote-reference brackets" href="#id20" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and WSME + Pecan &lt;a class="footnote-reference brackets" href="#id21" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; have been
considered. However the adoption of Pecan appears the one that better suits
Neutron.&lt;/p&gt;
&lt;p&gt;A mailing list discussion &lt;a class="footnote-reference brackets" href="#id22" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; on REST API frameworks has been used to provide
some guidance. For WSME, even if it is an interesting solution to increase code
maintanability, and ease the development process, we struggled during some
early experiments to make it work with the current extension model. Even if
it might be argued that the problem in this case is the extension model, we are
unable to recommend it as a part of this blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Kevin Benton (kevinbenton)
Brandon Logan (blogan)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Sean Collins (sccal68) [developer docs]
Salvatore Orlando (salv-orlando) [reserve dev]
Mark McClain (markmcclain)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Define framework for Pecan controllers for core and extended resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Re-implement controllers for base and extended resources, paying particular
attention to dealing properly with ‘attribute’ extensions. The deliverable
of this work item will be a new “base controller” which will leverage the
v3 plugin interface proposed in &lt;a class="footnote-reference brackets" href="#id17" id="id11" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Plug authorization and quota enforcement in the “plugin management”
layer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Split out RPC over AMQP server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Redefine unit tests to work with new framework&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Validate new solution with integration testing, perform performance and
scalability analysis.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;While not a direct dependency, the V3 plugin interface &lt;a class="footnote-reference brackets" href="#id17" id="id12" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; is listed in the
case it is proposed again for Liberty.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Once the changes are in place and integrated with the new plugin interface
discussed in &lt;a class="footnote-reference brackets" href="#id17" id="id13" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, gate tests should run as usual. We do not expect this
change to have any impact that might trigger race conditions leading to
intermittent gate failures.&lt;/p&gt;
&lt;p&gt;On the other hand, this change will have a significant impact on unit
testing. Most unit tests exercise the REST API server and with this change
these unit tests will be inevitably broken.
Under this proposal we therefore expect significant changes in the “base
classes” for unit test, such as &lt;a class="footnote-reference brackets" href="#id23" id="id14" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Besides, new modules introduced as a part of this blueprint should be
thoroughly unit tested, with a target level of coverage between 90% and 100%.
Test coverage should be verified with tox -ecover.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;No new tests are anticipated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Even if API functional testing will eventually be a relevant part of Neutron’s
functional testing suite, this is outside the scope of this spec.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Please see previous section.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;As the specification discussed in this document changes the way in which the
Neutron server is deployed because of the split between the HTTP and RPC over
AMQP server, this will need to be appropriately documented in the admin guide.&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;No change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;The new process for developing Neutron extensions should be thoroughly
documented.&lt;/p&gt;
&lt;p&gt;Also the developer documentation for the api layer &lt;a class="footnote-reference brackets" href="#id24" id="id15" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;9&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; needs to be updated
according to the changes being made as part of this blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id16" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Pecan documentation: &lt;a class="reference external" href="http://pecan.readthedocs.org"&gt;http://pecan.readthedocs.org&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id17" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id4"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id5"&gt;3&lt;/a&gt;,&lt;a role="doc-backlink" href="#id7"&gt;4&lt;/a&gt;,&lt;a role="doc-backlink" href="#id11"&gt;5&lt;/a&gt;,&lt;a role="doc-backlink" href="#id12"&gt;6&lt;/a&gt;,&lt;a role="doc-backlink" href="#id13"&gt;7&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;v3 plugin interface: &lt;a class="reference external" href="https://review.openstack.org/#/c/140527/"&gt;https://review.openstack.org/#/c/140527/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id18" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/master/neutron/api/v2/attributes.py"&gt;https://github.com/openstack/neutron/blob/master/neutron/api/v2/attributes.py&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id19" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Pecan hooks: &lt;a class="reference external" href="http://pecan.readthedocs.org/en/latest/hooks.html"&gt;http://pecan.readthedocs.org/en/latest/hooks.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id20" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Falcon WSGI framework: &lt;a class="reference external" href="http://falconframework.org/"&gt;http://falconframework.org/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id21" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;WSME: &lt;a class="reference external" href="http://wsme.readthedocs.org/"&gt;http://wsme.readthedocs.org/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id22" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id10"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2014-March/030385.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2014-March/030385.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id23" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id14"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/tests/unit/test_db_plugin.py"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/tests/unit/test_db_plugin.py&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id24" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id15"&gt;9&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://docs.openstack.org/developer/neutron/devref/api_layer.html"&gt;http://docs.openstack.org/developer/neutron/devref/api_layer.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Thu, 09 Apr 2015 00:00:00 </pubDate></item><item><title>Add enable_new_agents to neutron server</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/enable-new-agents.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/enable-new-agents"&gt;https://blueprints.launchpad.net/neutron/+spec/enable-new-agents&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This proposal adds enable_new_agents config for operator maintenance to agents
in network node. It proposes a way that an agent can start without selectable
for auto-scheduling but manual-scheduling available so that a deployer can test
an agent manually.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Neutron doesn’t have a way to test a newly added network node by deploying test
resource before any customer resource on the node is deployed. When cloud
operators control network resources, they want to prevent users from
controlling the resources. For example, they may try to create test resources
on a new node while deploying the new node. Neutron can prevent users from
creating the resources on the node by agent’s admin_state_up=False, but Neutron
cannot start agent with admin_state_up=False. Neutron always starts agent with
admin_state_up=True. Nova and Cinder have the setting of “enable_new_services”
in each conf to disable the initial service status to achieve this.&lt;/p&gt;
&lt;p&gt;Neutron also has a problem for the maintenance scenario. Neutron can
prevent all users from creating the resources on the agent with
admin_state_up=False, but Neutron usually cannot allow admin user only
to create the resources. Currently, if
enable_services_on_agents_with_admin_state_down configuration
parameter is True, admin can create the resources on the agent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This proposal adds enable_new_agents config for operator maintenance to agents
in network nodes. Neutron agent’s admin_state_up is controlled by this config
while starting. The config is added to neutron-server since the proposal provides
all agents which have scheduling method(i.e.l3-agent, dhcp-agent, lbaas-agent)
and don’t have the method(i.e. ovs-agent, metadata-agent) so that deployers
enable agents easily although this proposal gives a benefit to scheduling agents
only.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron agent starts with admin_state_up=True when enable_new_agents=True.
This behaviour is default. User freely creates their resources on the agent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron agent starts with admin_state_up=False when enable_new_agents=False.
This behaviour is maintenance mode. In the case, user’s resources cannot be
created on the agent until admin changes admin_state_up to True.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The default value is True because this proposal doesn’t intend to change a
traditional behaviour.&lt;/p&gt;
&lt;p&gt;The proposal also presupposes that
enable_services_on_agents_with_admin_state_down is True in Neutron
servers.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;This proposal adds enable_new_agents to neutron.conf. This config is set True
as default value. It doesn’t change a traditional behaviour of the agents.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Hirofumi Ichihara &amp;lt;ichihara-hirofumi&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add enable_new_agents config and the implements&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Add tests which ensure agents start with admin_state_up False.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;The new config options will be documented.&lt;/p&gt;
&lt;p&gt;The following is a maintenance scenario. The maintenance scenario will be
documented.&lt;/p&gt;
&lt;p&gt;Precondition: Neutron servers run with
enable_services_on_agents_with_admin_state_down=True.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Admin prepares a new network node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Admin adds enable_new_agents=False to neutron.conf and starts a neutron
server, then their all agents.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All agents run with admin_state_up=False.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Admin needs to create a network (or router) and allocates it to a target
agent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Admin creates VM connected the network resources, then admin
confirms the capability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Admin deletes all resources and update agents to be
admin_state_up=True after the test.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/enable-new-agents"&gt;https://blueprints.launchpad.net/neutron/+spec/enable-new-agents&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-operators/2015-March/006434.html"&gt;http://lists.openstack.org/pipermail/openstack-operators/2015-March/006434.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 06 Apr 2015 00:00:00 </pubDate></item><item><title>Reference IPAM driver</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/reference-ipam-driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/reference-ipam-driver"&gt;https://blueprints.launchpad.net/neutron/+spec/reference-ipam-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This specification proposes moving Neutron’s IPAM code, currently baked in the
database logic, into an appropriate driver which will be called by Neutron
through the interface being defined in &lt;a class="footnote-reference brackets" href="#id18" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Decoupling IPAM logic from the Neutron management layer has been on the list
of “debt repayment” tasks for a long time. It is also a necessary step towards
the implementation of a pluggable IPAM framework, which has been sanctioned
as one of the priorities for the Kilo release cycle &lt;a class="footnote-reference brackets" href="#id19" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The following specification provides both a long-term picture for the evolution
of the proposed reference IPAM driver and a short-term detailed description of
the changes proposed as part of this blueprint. The discussion on the long-term
evolution is in the section titled “The Big Picture”; readers concerned
exclusively with changes that will be performed as a part of this specification
can safely skip this section.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Neutron’s IPAM logic is baked into the “base” DB class &lt;a class="footnote-reference brackets" href="#id20" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. This has serious
manageability shortcomings, and is also incompatible with the activity promoted
by &lt;a class="footnote-reference brackets" href="#id18" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. The latter point makes it pretty much compulsory to transform this
IPAM logic into a driver which gets called through the IPAM interface.&lt;/p&gt;
&lt;p&gt;Also, this IPAM logic is currently the first source of “lock wait timeout”
issues in neutron DB because of deeply nested (and long) transactions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This specification is complementary to other specifications proposed for the
Kilo release cycle &lt;a class="footnote-reference brackets" href="#id18" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, &lt;a class="footnote-reference brackets" href="#id21" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. Thanks to these effort, IPAM will become
“pluggable”, meaning that deployers will be able to pick the solution that
best suits them to perform IP address management.
On the other hand, the current logic, used in many production deployments,
will become an IPAM driver as well. More precisely this would be the IPAM
driver that would be used in upstream gate tests.
For this reason we will refer to this IPAM driver as the “reference” driver,
without hopefully abusing this term.&lt;/p&gt;
&lt;p&gt;At the end of the Kilo release cycle Neutron will have a driver which does
IP address management exactly in the same way as Neutron does today. As a part
of this blueprint we will also try and fix some of its well known shortcomings,
leveraging community contributions already available for review where possible.&lt;/p&gt;
&lt;p&gt;The reference driver will be implemented by:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Defining a simple data model extrapolating it from the current “baked-in”
IPAM data model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Moving out IPAM routines from the “base” DB class &lt;a class="footnote-reference brackets" href="#id20" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; into the newly
created IPAM driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hooking the IPAM driver into the newly developed IPAM interface &lt;a class="footnote-reference brackets" href="#id18" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;section id="driver-data-model"&gt;
&lt;h3&gt;Driver data model&lt;/h3&gt;
&lt;p&gt;The data model for the reference IPAM driver will be based on the same
principles as the current IPAM logic, namely:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Availability ranges created starting from subnets’ allocation pools.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allocation of IP addresses performed from availability ranges.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Recalculation of availability ranges only when strictly necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allocation outside of allocation pools will be allowed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, the reference IPAM driver will not include, at least in its first
iteration, support for subnet pools &lt;a class="footnote-reference brackets" href="#id25" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. This driver assumes that every
tenant has a single subnet pool whose address range is the entire IP address
space.
Overlapping allocations from this “default” pool are also allowed to ensure
a backward compatible behavior.&lt;/p&gt;
&lt;p&gt;Details about schema changes are discussed in the appropriate section.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="code-refactoring"&gt;
&lt;h3&gt;Code refactoring&lt;/h3&gt;
&lt;p&gt;Code refactoring activities are mostly about moving code which is now part
of neutron.db.db_base_plugin_v2.NeutronDbPluginV2.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;More specifically the following methods will become part of the IPAM driver:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;_allocate_ips_for_port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;_update_ips_for_port
For the two methods above there will be a slighty different semantic and
signature to reflect the operations exposed by the new IPAM interface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;_test_fixed_ips_for_port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;_check_unique_ip&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;_allocate_fixed_ips&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;_allocate_specific_ip&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;_generate_ip&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;_try_generate_ip
The locking query logic used in the above two methods will be replaced with
a lock free algorithm.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;_store_ip_allocation
For this method, some logic will stay in neutron’s DB base class, as it will
be used to provide IP address information for ports to API consumers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;_allocate_pools_for_subnet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;_rebuild_availability_ranges&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;_check_ip_in_allocation_pool&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;_delete_ip_allocation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="plugging-into-ipam-interface"&gt;
&lt;h3&gt;Plugging into IPAM interface&lt;/h3&gt;
&lt;p&gt;The reference driver proposed in this document will implement the inferface
defined in &lt;a class="footnote-reference brackets" href="#id18" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The get_subnet operation will be a no-op in the proposed driver.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;allocate_subnet will setup the availability ranges; allocation pools
should be stored in the base DB class as they are also retrieved via
the API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;remove_subnet will ensure no allocation is still active for the subnet
and clear the availability ranges&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;allocate will implement a logic similar to allocate_ips_for_port, with
the only exception that it will be called not for a port but for every
IP to configure on a port. Recalculation of availability ranges will
still occur here.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;deallocate will simply keep removing IP allocation info. It is likely to
be a no-op for this first implementation of the reference driver.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="the-big-picture"&gt;
&lt;h3&gt;The Big Picture&lt;/h3&gt;
&lt;p&gt;This specification so far discussed how the driver will look in Kilo.
From an architectural perspective it will simply be a class which is loaded
at startup, and where IPAM calls are dispatched.&lt;/p&gt;
&lt;p&gt;This still does not address two important aspects of IPAM in Neutron:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;independence from the core plugin&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;coordination among multiple servers (or even workers)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In Kilo indeed the calls to the IPAM interface will still be in the base DB
class, which is also the base class for the great majority of Neutron plugins.
This means that the reference IPAM driver will actually be called by the
plugin, and not by the neutron management layer. This applies to any other
IPAM driver as well.
This is an architectural flow, even if not a major one, as it means that:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The ability of running a specific IPAM driver depends on the core_plugin
currently configured.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IPAM interface hooks might need to be explicitly added to plugin modules.
Indeed with the current codebase, we’ll need to insert calls to the IPAM
interface at least in the base DB class and in the ML2 plugin class &lt;a class="footnote-reference brackets" href="#id22" id="id11" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As a plugin will still be free to choose how to use the IPAM interface,
the interactions defined in &lt;a class="footnote-reference brackets" href="#id18" id="id12" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; are therefore plugin-specific. This could
lead to unexpected behaviors when running specific combinations of plugins
and IPAM driver.
For instance, a plugin might redefine core methods such as create_port, and
bypass calls to the IPAM driver. As another example, a plugin might decide
to override a method implementation by calling the IPAM driver from within
a DB transaction, thus creating the conditions for eventlet yields leading
to deadlocks in the database.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Therefore IPAM driver calls should be performed by the management layer, and
the result of IPAM operation should then be sent to the plugin layer. This
however will require extensive changes in the plugin interface, and is out
of scope for this release cycle. Ideally this would fit very well in a world
where a “v3” plugin interface is defined which allows to have distinct
interfaces for operating on different resource.&lt;/p&gt;
&lt;p&gt;When multiple servers or workers (or both) are deployed there will also be
several instances of the reference IPAM driver. With the current implementation
this leads to well known race conditions such as &lt;a class="footnote-reference brackets" href="#id24" id="id13" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;. The first iteration
of the IPAM reference driver will likely suffer of the same issues.
In subsequent iteration the community might evaluate scalable and reliable
solution which might include either distributed coordination among driver
instances or a “conductor-style” implementation where drivers forward
operations to a centralized IPAM service.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;Ideally there should not be any change in the schema. However, the IPAM
driver will be in charge of managing the IPAvailabilityRanges table.&lt;/p&gt;
&lt;p&gt;For IPAllocation and IPAllocationPools, ideally these tables should be
split, since they both have a role in the REST layer and in the IPAM
system.&lt;/p&gt;
&lt;p&gt;While splitting this tables provides the best possible separation of concerns
between the plugin and the IPAM driver, it has also some drawbacks. The most
notable ones are duplication of information (eg: an IP address will be both
on the plugin and on the IPAM side), and an increased number of DB operations
for allocating addresses.&lt;/p&gt;
&lt;p&gt;For this reason we will assume, at least for this first implementation, that
te Neutron DB layer and the IPAM driver can share database tables. In this
conditions no database schema changes will be needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;The proposed change won’t alter a bit the syntax and semantics of the
Neutron API.
Any API change behavior resulting from this implementation will be an
unintentional side effect and should therefore be treated as a high
priority bug.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;We do not expect the reference IPAM driver to be less secure than the current
logic, since most of code will remain unchanged in the driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The reference driver will contain logic for preventing lock timeout and
reducing the scope of locking queries. This might result in a performance
improvement under heavy load, but we expect this improvement to not be
relevant. The changes in logic from the ‘baked IPAM’ are aimed mostly
towards reliability.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;No change expected in IPv6-related IPAM features such as SLAAC.
Any change deriving from the implementation of this spec is an unintentional
side effect and should be treated as a high priority bug.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;The reference driver will be the default value for the IPAM driver.
In order to avoid potential mayhem is a deployer is running multiple servers,
the same IPAM driver should be used on every server.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This will be good for the community as it will provide a single place in the
neutron code tree where IPAM SMEs can contribute.&lt;/p&gt;
&lt;p&gt;Note: so far this work is targeting the neutron code tree, but in the future
the IPAM reference driver might be moved outside in line with what’s being
proposed for the plugin/driver split blueprint &lt;a class="footnote-reference brackets" href="#id23" id="id14" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Under the hypothesis that there will be a pluggable IPAM interface there is really
no alternative. Unless wrapping every IPAM interface call with a logic like the
following might be considered an alternative:&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;::&lt;/dt&gt;&lt;dd&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;if cfg.CONF.use_pluggable_ipam:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;self.ipam_driver.do_this(subnet_id, …)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;else:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;previous logic in db base class&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The author of this documentation has high hopes that nobody will consider the
snippet above a viable alternative. Even if it can be a short-time measure to
allow for independently develop the pluggable interface, it’s something that
should be avoided if possible.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;The minimum goal for Kilo is to have a driver which manages IPs in the same
way as the “baked” logic does today.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;salv-orlando&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement the driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write unit tests and functional tests for it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Combine with pluggable interface, face the gate&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;According to the strategy chosen in syncing up with effort &lt;a class="footnote-reference brackets" href="#id18" id="id15" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;, theree might
be vestigial code to remove&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Pluggable IPAM interface &lt;a class="footnote-reference brackets" href="#id18" id="id16" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Introduction of Subnet Pool concept. This is part of &lt;a class="footnote-reference brackets" href="#id21" id="id17" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Testing is going to be tricky because the driver can’t be fully tested until
the pluggable interface is in place. On the other hand for introducing the
pluggable interface one needs a driver in place. In order to break this
deadlock one possibility is to introduce the driver, but limit only to unit and
functional testing until the IPAM interface is in place.&lt;/p&gt;
&lt;p&gt;The following sections will define strategies for both the cases in which the
driver is merged with the pluggable IPAM interface in place and the case in
which the driver is merged without it.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Currently defined scenario tests provide enough coverage for the reference
driver, since it’s going to be functionally equivalent to what the current
“baked in” code does today.&lt;/p&gt;
&lt;p&gt;Obviously coverage by tempest scenario tests will be possible only when the
pluggable IPAM interface will be in place and dispatching calls to the
reference IPAM driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional testing in the classical neutron sense won’t be possible until
the pluggable IPAM interface merges.
However, functional tests intended as exercising the driver trough its
interface should always be possible.&lt;/p&gt;
&lt;p&gt;On the other hand, if the IPAM pluggable interface is already in place,
this will allow us to perform functional testing by exercising the neutron
API thus leveraging the current framework.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;As there will be no API change, no changes to API tests will be needed.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;No change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;The reference IPAM driver should come with appropriate developer documentation&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id18" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id4"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id5"&gt;3&lt;/a&gt;,&lt;a role="doc-backlink" href="#id8"&gt;4&lt;/a&gt;,&lt;a role="doc-backlink" href="#id10"&gt;5&lt;/a&gt;,&lt;a role="doc-backlink" href="#id12"&gt;6&lt;/a&gt;,&lt;a role="doc-backlink" href="#id15"&gt;7&lt;/a&gt;,&lt;a role="doc-backlink" href="#id16"&gt;8&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;Proposed IPAM interface: &lt;a class="reference external" href="https://review.openstack.org/#/c/134339"&gt;https://review.openstack.org/#/c/134339&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id19" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Kilo priorities: &lt;a class="reference external" href="http://specs.openstack.org/openstack/neutron-specs/priorities/kilo-priorities.html"&gt;http://specs.openstack.org/openstack/neutron-specs/priorities/kilo-priorities.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id20" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id3"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id7"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;Base DB plugin module: &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/db/db_base_plugin_v2.py"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/db/db_base_plugin_v2.py&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id21" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id6"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id17"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;Pluggable IPAM specification: &lt;a class="reference external" href="https://review.openstack.org/#/c/97967/"&gt;https://review.openstack.org/#/c/97967/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id22" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id11"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;ML2 plugin: &lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron/tree/neutron/plugins/ml2/plugin.py"&gt;http://git.openstack.org/cgit/openstack/neutron/tree/neutron/plugins/ml2/plugin.py&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id23" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id14"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Plugin decomposition specification: &lt;a class="reference external" href="https://review.openstack.org/#/c/134680/"&gt;https://review.openstack.org/#/c/134680/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id24" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id13"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1332923"&gt;https://bugs.launchpad.net/neutron/+bug/1332923&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id25" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Subnet allocation specification: &lt;a class="reference external" href="https://review.openstack.org/#/c/135771/"&gt;https://review.openstack.org/#/c/135771/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Mon, 30 Mar 2015 00:00:00 </pubDate></item><item><title>Use OVSDB instead of calling ovs-vsctl</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/vsctl-to-ovsdb.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/vsctl-to-ovsdb"&gt;https://blueprints.launchpad.net/neutron/+spec/vsctl-to-ovsdb&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Neutron’s ovs_lib uses the Open vSwitch CLI command &lt;em&gt;ovs-vsctl&lt;/em&gt; to perform
basic vSwitch CRUD operations. This is almost an order of magnitude slower
than using either direct OVSDB protocol commands, or using the Open vSwitch
Python API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;First, an interface for interacting with with the OVSDB should be defined as
an abstract base class. Then, an implementation of this interface using
ovs-vsctl calls should be made and ovs_lib should make all ovsdb-related calls
through this new implementation.&lt;/p&gt;
&lt;p&gt;Next, an implementation of the OVSDB interface should be implemented using
the Open vSwitch IDL Python library. A configuration option will be added
to allow selection of the OVSDB interface to use. It is necessary to allow
this choice as there are differences in how privileges will be handled between
the two OVSDB implementations. The ovs-vsctl implementation uses sudo/rootwrap
whereas the IDL library will require either giving the neutron user permissions
to the ovsdb unix socket, or using TCP/SSL sockets and controlling access via
firewall rules (though likely just using the loopback interface).&lt;/p&gt;
&lt;p&gt;Any distributions or deployment targets that do not support the requirements
for the proposed OVSDB implementation will still be able to use the existing
implementation.&lt;/p&gt;
&lt;p&gt;This will allow leaving the ovs_lib API largely unchanged. On a simple test
creating and deleting 100 ports on an existing bridge, the current ovs_lib
implementation was nearly 10x slower than using the OVS Python API. It should
be noted that ovs_lib was over 100x slower than sending raw OVSDB commands to
Open vSwitch. The performance disparity between the raw OVSDB and existing
OVS Python API is due to the poor performance of the OVS Python API’s own
pure-Python JSON parser which tests show to be ~30x slower than Python’s stdlib
JSON parser which, unfortunately, is not a good fit for OVS’s use case as it
requires having the entire string ready to parse, whereas the OVS code is
structured to parse buffers as they are read. Potentially significant speedups
are possible in OVS’s JSON parser by writing an extension that adds Python
bindings to the C version of their parser.&lt;/p&gt;
&lt;p&gt;The OVS IDL implementation makes use of monitor commands for syncing a local
cache of the OVSDB. Unfortunately, it does not make these monitor events
available to users of the library. To replace ovsdb-monitor, it will be
necessary to either use a lower-level Open vSwitch API running an additional
monitor request to get these event notifications, to modify the IDL library at
runtime, or to try to get code merged to the upstream Open vSwitch library
that optionally exposes these events.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;The existing implementation handles privileges via sudo/rootwrap. The proposed
change would be using a programatic API and would instead rely on the
appropriate permissions being set on underlying Open vSwitch unix domain socket
or through the use of Open vSwitch’s SSL authentication.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;With no changes to the upstream OVS Python API, a 6-7x speed improvement is
possible. With Python bindings to the OVS C JSON parser, it should be possible
to approach the native OVSDB protocol performance which was 100x faster than
the current ovs_lib.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Repeating from the Security section, deployers would have to ensure that the
&lt;em&gt;neutron&lt;/em&gt; user has r/w permissions to the Open vSwitch db.sock. A new config
option specifying the connection string for ovs-server would also be required.
Packagers will need to add a dependency for python-openvswitch (which seems to
be readily available across common distributions as it is part of standard
openvswitch packaging).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;For the initial implementation, there shouldn’t be much change to ovs_lib’s
API.&lt;/p&gt;
&lt;p&gt;It should be noted that users of XenAPI currently use a modified version of
rootwrap to execute ovs-vsctl commands. To use the proposed OVSDB
implementation with the XenAPI, an equivalent wrapper may have to be
developed. This work is outside of the scope of this blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;It would be possible to write our own library around the OVSDB protocol. It
would most likely be faster, but it would most likely end up looking very much
like the OVS Python API by the time we were finished.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;otherwiseguy&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Convert existing OVS unit tests that deal entirely with external Open vSwitch
actions to functional tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Convert existing ovs-vsctl calls to the equivalent OVS Python API calls&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Re-work OVSDB Monitoring to use the OVS Python API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write Python bindings for OVS’s C-based JSON push parser to increase
performance&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Adds a requirement for the OVS python bindings&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Many of the unit tests for ovs_lib will have to be changed because they are
tied far too heavily to specific implementation details, mocking out calls
to ovs-vsctl, etc.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional tests that actually test the CRUD operations against a
real Open vSwitch installation should be created. They should work against
both OVSDB interface implementations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;n/a&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Documentation of the new config option and security considerations will be
necessary.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;The OVSDB abstract base class should be well-documented. In-tree developer
docs describing the ovs_lib implementation will be added.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://tools.ietf.org/html/rfc7047"&gt;http://tools.ietf.org/html/rfc7047&lt;/a&gt;
&lt;a class="reference external" href="https://github.com/openvswitch/ovs/tree/master/python/ovs"&gt;https://github.com/openvswitch/ovs/tree/master/python/ovs&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 26 Mar 2015 00:00:00 </pubDate></item><item><title>OVS agent: Use python binding instead of ovs-ofctl command</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/ovs-ofctl-to-python.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ovs-ofctl-to-python"&gt;https://blueprints.launchpad.net/neutron/+spec/ovs-ofctl-to-python&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;OVS agent uses ovs-ofctl command to program flow.
it works but has some drawbacks:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Involves high overhead; same as ovs-vsctl described in
other blueprint &lt;a class="footnote-reference brackets" href="#vsctl-bp" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Difficult or impossible to handle OpenFlow async messages;
async messsages are useful for monitoring switch state changes
like port additions and removals &lt;a class="footnote-reference brackets" href="#ofagent-port-monitor-bp" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Instead of invoking ovs-ofctl each times, use OpenFlow python library
(“Ryu ofproto library” &lt;a class="footnote-reference brackets" href="#ryu-ofproto" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;) provided by Ryu SDN Framework
(“Ryu” &lt;a class="footnote-reference brackets" href="#ryu" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;) to program OVS.
This approach was taken for ofagent &lt;a class="footnote-reference brackets" href="#ofagent" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and proved to work.&lt;/p&gt;
&lt;p&gt;Plan:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Turn the existing code which uses ovs-ofctl into a driver
&lt;a class="footnote-reference brackets" href="#ovs-agent-ovs-ofctl-driver" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;16&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Introduce Ryu-based driver &lt;a class="footnote-reference brackets" href="#ovs-agent-ryu-driver" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;17&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; as a
non-default option.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maintain both of drivers for a while.  (one release cycle?)
It would need Experimental/non-voting jenkins jobs to cover
the non-default driver.
Looking the result of the jobs, once the Ryu-based driver
gets reasonably stable, consider to switch the default.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deprecate ovs-ofctl driver later&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Implementation details:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;OpenFlow version&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;OVS agent currently uses OpenFlow 1.0.
The new Ryu-based driver will use OpenFlow 1.3 for reasons mentioned
below.  ovs-ofctl based driver will keep using OpenFlow 1.0 with
the exactly same flows as it currently uses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenFlow 1.3 provides some features possibly useful for OVS agent.
For example, ofagent uses metadata to implement “local vlan” isolation.
OVS agent can do the same.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ryu ofproto library API for OpenFlow 1.0 is not sophisticated compared
to later versions like OpenFlow 1.3.  It works well, but only provides
older unsophisticated API &lt;a class="footnote-reference brackets" href="#ryu-old-api" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;13&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenFlow 1.3 works well with the recent versions of Open vSwitch.
Open vSwitch v2.0.0 introduced OpenFlow 1.3 support and
Open vSwitch v2.3.0 enabled it by default.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OVS-agent itself configures the switch to use the appropriate OpenFlow
version.  There’s no need for extra operator investigations.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open vSwitch version in distributions:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Ubuntu 14.04 LTS has Open vSwitch v2.0.1 &lt;a class="footnote-reference brackets" href="#ovs-ubuntu-package" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.
ofagent, which uses OpenFlow 1.3, uses that version for both of
development and CI.  It works well &lt;a class="footnote-reference brackets" href="#ofagent-ci" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;11&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RHEL-OSP uses Open vSwitch 2.1.2 for Juno release.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fedora 20 has Open vSwitch 2.3.0.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;XenAPI:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;XenAPI Integration needs updates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Currently OVS agent uses a special rootwrap &lt;a class="footnote-reference brackets" href="#xen-rootwrap" id="id11" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;14&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;
&lt;a class="footnote-reference brackets" href="#xenapi-readme" id="id12" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;15&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; to proxy ovs-ofctl/ovs-vsctl requests from
neutron node to dom0.  This proposal replaces the use of ovs-ofctl.
This proposal doesn’t change ovs-vsctl part.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As we can assume IP reachability between neutron node and dom0
&lt;a class="footnote-reference brackets" href="#xenapi-meeting-log" id="id13" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;20&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; , a simple set-controller to teach OVS the
IP address of the corresponding neutron node (thus the embedded
OpenFlow controller) should be enough.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OVS-agent will have a new option to specify the address and port to
listen for OpenFlow connections.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nicira extensions (NX)&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Currently OVS agent uses Nicira extensions for OpenFlow 1.0 in
a several places.  Even with OpenFlow 1.3, some of them still
need the extensions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The following is a list of Nicira extensions used by OVS agent.
Ryu&amp;gt;=3.18 supports all of them.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Learn action&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Local ARP responder uses Nicira extensions heavily:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Load&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Move&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NXM_NX_ARP_SHA&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NXM_NX_ARP_THA&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;For longer term, probably it might be cleaner to replace it with
ofagent’s packet-in based implementation entirely.  In that way,
there’s no need to use Nicira extensions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The following Nicira extensions will be replaced by
OpenFlow 1.3 native equivalents.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Tunnel support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Resubmit and tables&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenFlow channel establishment&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Currently, on each invocation, ovs-ofctl command connects to the switch
via unix domain socket.  Instead, this blueprint proposes to make OVS
agent listen on a local TCP port, e.g. 127.0.0.1:6633, and wait for the
switch to connect to that port.  TCP is the typical transport for an
OpenFlow channel and removes a need of rootwrap.   It’s the same as
how ofagent currently works.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To make the above work, the switch needs to be configured to connect to
that port.  OVS agent itself can configure the switch accordingly by
accessing ovsdb on startup.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Example of typical code changes&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Current code:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_flow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"output:&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;out_port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;With Ryu:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ofpp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OFPMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;in_port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;ofpp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OFPActionOutput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;out_port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;instructions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="n"&gt;ofpp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OFPInstructionActions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ofp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OFPIT_APPLY_ACTIONS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                               &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ofpp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OFPFlowMod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_msg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As you see, Ryu version is a straightforward representation of
OpenFlow protocol.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Instead of making OVS agent switch to OpenFlow 1.3, improve Ryu’s
OpenFlow 1.0 support.  This would minimize changes in neutron.
This isn’t an attractive option though, given the limited functionality
of OpenFlow 1.0.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fold ofagent into OVS agent.  It would bring in some additional ofagent
improvements including drastic flow table design changes &lt;a class="footnote-reference brackets" href="#ofagent-flow" id="id14" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;
and packet-in based local arp responder &lt;a class="footnote-reference brackets" href="#ofagent-ovs-comparison" id="id15" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.
If we want to merge these agents in a long term keeping ofagent’s
“avoid OVS-specific features as far as reasonable” property, this option
would be the most straightforward and minimize the total amount of work a lot.
If we go this route, probably the appropriate steps would be:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Port lacking features like DVR, canary table, etc to ofagent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assuming it’s more important to keep compatibility for OVS-agent (right?),
resurrect features which was removed in ofagent. (br-ex support etc)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once ofagent has feature parity, replace OVS-agent with it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;A local user on the node would be able to connect to the OpenFlow port
on which the agent listening and try to confuse the agent.  It isn’t
a problem as the local management network is considered safe, though.&lt;/p&gt;
&lt;p&gt;The OpenFlow channel can be protected using TLS if desirable.
Both of Open vSwitch and Ryu support TLS &lt;a class="footnote-reference brackets" href="#ryu-tls" id="id16" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;12&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.
In that case, we need to introduce some agent options to specify certs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Per FlowMod overhead would be smaller than rootwrap and ovs-ofctl command.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Ryu SDN Framework will be required for OVS agent to work:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The latest version can be pulled via pip.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ryu and its (non-optional) required packages are mostly pure-python
&lt;a class="footnote-reference brackets" href="#ryu-req" id="id17" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;19&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.  A few exceptions like eventlet are already covered by
Neutron itself.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Debian and Ubuntu have official packages too
&lt;a class="footnote-reference brackets" href="#ryu-debian-package" id="id18" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;9&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#ryu-ubuntu-package" id="id19" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;10&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.
However, Ryu version newer than the packages will likely be necessary
for the Nicira extension support mentioned in “Proposed Changes” section.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It isn’t packaged for Fedora Rawhide yet.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Developers of OVS agent need to be familiar with Ryu ofproto library API,
instead of ovs-ofctl command flow syntax.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;yamamoto&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;kakuma&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;See “Proposed Change” section.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Update and improve the existing tests if necessary.&lt;/p&gt;
&lt;p&gt;Ryu SDN Framework will be required for gate jobs.&lt;/p&gt;
&lt;p&gt;Experimental/non-voting jobs for the new driver will be needed.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;The existing tempest tests should work as-is.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Update and improve the existing tests if necessary.&lt;/p&gt;
&lt;p&gt;There’s an on-going effort for functional tests for drivers
&lt;a class="footnote-reference brackets" href="#ovs-agent-ofctl-functional-tests" id="id20" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;18&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; .
Suggestions are welcome.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;A new option to specify address/port to listen for OpenFlow connections
needs to be documented.  It will be used by XenAPI integration.&lt;/p&gt;
&lt;p&gt;If we want to support other transports like TLS, more options will be
needed:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The option to specify the transport&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Transport specific parameters.  E.g. certs for TLS&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;It’s nice to have a documentation on how to debug OpenFlow flows.
Some notes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Even after switching to the proposed Ryu-based driver, you can
keep using ovs-ofctl command etc for debugging purposes as of today.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ryu has a functionality to JSON-serialize OpenFlow messages
&lt;a class="footnote-reference brackets" href="#ryu-to-jsondict" id="id21" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;21&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; .  It might be useful for logging purposes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="vsctl-bp" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/vsctl-to-ovsdb"&gt;https://blueprints.launchpad.net/neutron/+spec/vsctl-to-ovsdb&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ryu" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://osrg.github.io/ryu/"&gt;https://osrg.github.io/ryu/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ryu-ofproto" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://ryu.readthedocs.org/en/latest/ofproto_ref.html"&gt;http://ryu.readthedocs.org/en/latest/ofproto_ref.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ofagent" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/OFAgent"&gt;https://wiki.openstack.org/wiki/Neutron/OFAgent&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ofagent-flow" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id14"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/stable/juno/neutron/plugins/ofagent/agent/flows.py"&gt;https://github.com/openstack/neutron/blob/stable/juno/neutron/plugins/ofagent/agent/flows.py&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ofagent-port-monitor-bp" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ofagent-port-monitor2"&gt;https://blueprints.launchpad.net/neutron/+spec/ofagent-port-monitor2&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ofagent-ovs-comparison" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id15"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/OFAgent/ComparisonWithOVS"&gt;https://wiki.openstack.org/wiki/Neutron/OFAgent/ComparisonWithOVS&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ovs-ubuntu-package" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://packages.ubuntu.com/trusty/net/openvswitch-switch"&gt;http://packages.ubuntu.com/trusty/net/openvswitch-switch&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ryu-debian-package" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id18"&gt;9&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://packages.debian.org/sid/python-ryu"&gt;https://packages.debian.org/sid/python-ryu&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ryu-ubuntu-package" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id19"&gt;10&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://packages.ubuntu.com/vivid/python-ryu"&gt;http://packages.ubuntu.com/vivid/python-ryu&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ofagent-ci" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id10"&gt;11&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/ThirdPartySystems/OFAgent_CI"&gt;https://wiki.openstack.org/wiki/ThirdPartySystems/OFAgent_CI&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ryu-tls" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id16"&gt;12&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://ryu.readthedocs.org/en/latest/tls.html"&gt;http://ryu.readthedocs.org/en/latest/tls.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ryu-old-api" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;13&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://sourceforge.net/p/ryu/mailman/message/31204306/"&gt;http://sourceforge.net/p/ryu/mailman/message/31204306/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="xen-rootwrap" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id11"&gt;14&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/stable/juno/bin/neutron-rootwrap-xen-dom0"&gt;https://github.com/openstack/neutron/blob/stable/juno/bin/neutron-rootwrap-xen-dom0&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="xenapi-readme" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id12"&gt;15&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/stable/juno/neutron/plugins/openvswitch/agent/xenapi/README"&gt;https://github.com/openstack/neutron/blob/stable/juno/neutron/plugins/openvswitch/agent/xenapi/README&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ovs-agent-ovs-ofctl-driver" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;16&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/160245/"&gt;https://review.openstack.org/#/c/160245/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ovs-agent-ryu-driver" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;17&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/153946/"&gt;https://review.openstack.org/#/c/153946/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ovs-agent-ofctl-functional-tests" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id20"&gt;18&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/164584/"&gt;https://review.openstack.org/#/c/164584/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ryu-req" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id17"&gt;19&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/osrg/ryu/blob/master/tools/pip-requires"&gt;https://github.com/osrg/ryu/blob/master/tools/pip-requires&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="xenapi-meeting-log" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id13"&gt;20&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://eavesdrop.openstack.org/meetings/xenapi/2015/xenapi.2015-02-04-15.00.log.html"&gt;http://eavesdrop.openstack.org/meetings/xenapi/2015/xenapi.2015-02-04-15.00.log.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ryu-to-jsondict" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id21"&gt;21&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://ryu.readthedocs.org/en/latest/ofproto_base.html#ryu.ofproto.ofproto_parser.MsgBase.to_jsondict"&gt;http://ryu.readthedocs.org/en/latest/ofproto_base.html#ryu.ofproto.ofproto_parser.MsgBase.to_jsondict&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Thu, 19 Mar 2015 00:00:00 </pubDate></item><item><title>Add REJECT action rule for fwaas</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/fwaas-reject-rule.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/fwaas-reject-rule"&gt;https://blueprints.launchpad.net/neutron/+spec/fwaas-reject-rule&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add REJECT into action rule of FWaaS.
Action rule of current FWaaS contains only ALLOW/DENY. DENY simply discards
the data without a response, but REJECT returns a response.
Connection source by this response can be judged to be “connection was
refused”.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Action rule of current FWaaS contains only ALLOW/DENY.
DENY simply discards the data without a response, but REJECT returns a
response.
Without REJECT feature, end users cannot know whether their accesses are
super late or rejected. This REJECT feature will be a good option for FWaaS.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Add REJECT into action rule of FWaaS.
Connection source by this response can be judged to be “connection was
refused”.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;The db schema will be changed as below.
* add “reject” into action column in firewall_rules table.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Add REJECT into action rule of FWaaS.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;action&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘deny’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘allow’,
‘deny’, or
‘reject’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Action rule&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Another project:
* Horizon&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Higuchi Toshiaki &amp;lt;&lt;a class="reference external" href="mailto:higuchi%40mxj.nes.nec.co.jp"&gt;higuchi&lt;span&gt;@&lt;/span&gt;mxj&lt;span&gt;.&lt;/span&gt;nes&lt;span&gt;.&lt;/span&gt;nec&lt;span&gt;.&lt;/span&gt;co&lt;span&gt;.&lt;/span&gt;jp&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The work items include:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Implement neutron-fwaas changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement python-neutronclient changes for CLI.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement Horizon changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Testing will be added to firewall tests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Scenario tests will be added to validate REJECT action rule of firewall.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Testing will be added to firewall tests.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Admin guide will be updated action rule of FWaaS.&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;User guide will be updated action rule of FWaaS.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 23 Jan 2015 00:00:00 </pubDate></item><item><title>Neutron LBaaS TLS - Specification</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/lbaas-tls.html</link><description>

&lt;p&gt;BP &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-ssl-termination"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-ssl-termination&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Terminating TLS connections on the load balancer is a capability
expected from modern load balancers and incorporated into many applications.
This capability enables better certificate management and improved
application based load balancing e.g. cookie-based persistency,
L7 Policies appliance, etc.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;No TLS offloading capability is available for Neutron LBaaS&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Note: This document is referencing to the new LBaaS objects model
proposed at https://review.openstack.org/#/c/89903&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: This document does not consider flavors framework proposed at
https://review.openstack.org/#/c/90070
Before the flavors framework is in place, specific back-end driver which
does not support TLS capabilities should throw an exception stating a lack
of TLS support once it gets request for listener with TLS configuration.
This document specifies a “core” feature set that every back-end implementing
TLS capabilities must comply.
TLS capabilities of various back-end implementations
may differ in future releases, thus flavors aspect should definitely be part
of TLS capabilities specification&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: Horizon project aspect is not a part of this specification.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Tenant will manage his TLS certificates using Barbican.
Certificates will be stored in Barbican secure containers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Barbican is in charge of containers life cycle management,
containers classification and validation.
LBaaS TLS requires a specific container type (TLS).
Only container of this type will be listed to the tenant for selection
while configuring listener’s TLS containers to use.
Any invalid container usage will raise an error.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Barbican will also manage list of interested consumers for each container.
See spec at &lt;a class="reference external" href="https://review.openstack.org/#/c/99516"&gt;https://review.openstack.org/#/c/99516&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron LBaaS (a consumer, according to Barbican’s terminology) will not
use a regular GET request for container resource in order to get the
container. Instead, it will use a POST request to container’s consumers
resource (&lt;a class="reference external" href="http://admin-api/v1/containers"&gt;http://admin-api/v1/containers&lt;/a&gt;/{container-uuid}/consumers) with
following info:&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;{&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;“type”: “LBaaS”,
“URL”: “&lt;a class="reference external" href="https://lbaas.myurl.net/loadbalancers"&gt;https://lbaas.myurl.net/loadbalancers&lt;/a&gt;/&amp;lt;lb_id&amp;gt;/”&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;
We might want to use specific Listener URL instead of
Loadbalancer’s one, like
“&lt;a class="reference external" href="https://lbaas.myurl.net/lbaas/listeners"&gt;https://lbaas.myurl.net/lbaas/listeners&lt;/a&gt;/&amp;lt;listener_id&amp;gt;”&lt;/p&gt;
&lt;p&gt;As a response, it will get containers data like container’s resource GET
request was used.
Barbican, in its turn will store consumer’s (LBaaS instance URL) data
in its database so this info can be used for getting all consumers of
a specific TLS container.&lt;/p&gt;
&lt;p&gt;As a result, Neutron LBaaS TLS implementation is required to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Use only POST request to container’s consumers resource in order to get
the container’s data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Perform DELETE request to container’s consumers resource when
stop using a container.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Barbican TLS container will contain PEM encoded data. Specific back-end
implementation might convert the certificates data to other format
such as DER, if needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In addition to existing HTTP, HTTPS and TCP, new protocol, TERMINATED_HTTPS
will be added for listener creation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For tenant, creating listener with TERMINATED_HTTPS as a protocol means
desire to offload incoming encrypted traffic. New configuration options
will be available for listener’s configuration including:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Default TLS container id for TLS termination&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TLS containers list for SNI&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In case when specific back-end is not able to support TLS capabilities,
its driver should throw an exception. The exception message should state
that this specific back-end (provider) does not support listeners with TLS
offloading. The clear sign of listener’s requirement for TLS
offloading capabilities is its TERMINATED_HTTPS protocol.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New module will be developed in Neutron LBaaS for Barbican TLS containers
interactions. The module will be used by Neutron LBaaS front-end API code
and providers’ driver code. The module will be used for validation and
data extraction from default TLS container and SNI containers.
This module represents the only legitimate API for Barbican TLS containers
interactions. See ‘SNI certificates list management’ section for detailed
module specification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When creating listener with TERMINATED_HTTPS protocol:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Front-end TLS offloading is always enabled - hard coded as a default
behaviour for listener with TERMINATED_HTTPS protocol&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tenant must supply default TLS container for front-end offloading.
Not supplying a container is an invalid configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TLS supported protocols and cipher suites for termination will be
set to sane values by each back-end’s specific code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SNI certificates list is optional and not mandatory to specify&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SNI certificates list specifying is described
in “SNI certificates list management” section&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Certificate intermediate chain will be stored as a part of Barbican’s
TLS container&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Back-end re-encryption will not be supported in first phase&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Front-end client authentication and back-end server authentication will not
be supported in first phase&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When updating listener with TERMINATED_HTTPS protocol:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In TLS configuration domain, default TLS container ID for front-end
offloading and SNI container IDs list are values that may be changed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In case when defaut TLS container ID is replaced for the listener,
back-end implementation should ensure a lack of a downtime on LB appliance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Same for changing SNI container IDs list, back-end should
avoid LB downtime.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HA-Proxy LBaaS implementaion and other LBaaS implementations should
be modified to support this specification.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;With stated above, following is a description of a basic tenant use case - creating listener with TLS offloading:&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Tenant cteates Barbican TLS container with a certificate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tenant creates listener with TERMINATED_HTTPS as a listener protocol
and specifies the Barbican TLS container ID as a default TLS container
for front-end offloading&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As a result, listener created, offloading encrypted traffic on front-end
with default tenant’s TLS certificate, not re-encrypting traffic to the
back-end.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="requirements-from-barbican"&gt;
&lt;h3&gt;Requirements from Barbican&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Tenant should be able to create and delete
TLS containers using Barbican&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ability to store TLS certificates in Barbican containers
that contain the TLS certificate itself, its private key
and optionaly, intermediate chain&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Creating TLS container with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Certificate : PEM text field&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Private_key: PEM text_field&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(extracted) Private_key_pass_phrase : text field&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Intermediates: PEM text field (optional)
This field is a concatination of PEM encoded certificate blocks
in specific order&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete TLS certificate
&lt;strong&gt;optional:&lt;/strong&gt; Check if certificate is in use by any consumer
and warn before deleting.
Barbican’s BP discussing this feature:
&lt;a class="reference external" href="https://review.openstack.org/#/c/99516/"&gt;https://review.openstack.org/#/c/99516/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get TLS container, including private key in PEM encoded PKCS1 or PKCS7
formats, by container id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get TLS certificate in pem encoded x509 format, by container id&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="restrictions"&gt;
&lt;h3&gt;Restrictions&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;TLS settings are only available for listeners
having TERMINATED_HTTPS as a protocol. In other cases TLS settings
will be disabled and have None or empty values.
There should be a meaningfull error message to a user explaining the exact
reason of a failure in case of an invalid configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Listener protocol is immutable. Changing the protocol will require
radical re-configuration of provider’s back-end system, which seems to be
not  justified for this use case. Tenant should create new listener.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;While updating existing TLS certificate, name and description are only values
allowed to be modified. Creating new TLS container and using it instead of
the old one will be easier option than re-configuring LBaaS back-end
with modified container, at least in first phase.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="sni-certificates-list-management"&gt;
&lt;h3&gt;SNI certificates list management&lt;/h3&gt;
&lt;p&gt;For SNI functionality, tenant will supply list of TLS containers in specific
order.
In case when specific back-end is not able to support SNI capabilities,
its driver should throw an exception. The exception message should state
that this specific back-end (provider) does not support SNI capability.
The clear sign of listener’s requirement for SNI capability is
a none empty SNI container ids list.
However, reference implementation must support SNI capability.&lt;/p&gt;
&lt;p&gt;New separate module will be developed in Neutron LBaaS for Barbican TLS
containers interactions.
The module will use service account for Barbican API interation.
The module will have API for:
* Ensuring Barbican TLS container existence (used by LBaaS front-end API)&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Validating Barbican TLS container (used by LBaaS front-end API)
This API will also “register” LBaaS as a container’s consumer in Barbican’s
repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extracting SubjectCommonName and SubjectAltName information
from certificates’ X509 (used by LBaaS front-end API)
As for now, only dNSName and directoryName types will be extracted from
SubjectAltName sequence, while directoryName type usage is an issue
for further discussion.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extracting certificate’s data from Barbican TLS container
(used by provider/driver code)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unregistering LBaaS as a consumer of the container when container is not
used by any listener any more (used by LBaaS front-end API)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The module will use pyOpenSSL and PyASN1 packages.
Only this new common module should be used by Neutron LBaaS code for Barbican
containers interactions.&lt;/p&gt;
&lt;p&gt;Front-end LBaaS API (plugin) code will use a new developed module for
validating Barbican TLS containers.
Driver, in its turn, can extract SubjectCommonName and SubjectAltName
information from certificates’ X509 via the common module API
and use it for its specific SNI implementation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Specific back-end driver does not have to use SubjectAltName
information. Furthermore, specific driver may throw
an exception saying SubjectAltName is not supported by
its provider&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Any specific driver implementation may extract host names info from
certificates using the mentioned above common module API only, if needed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SNI conflicts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Employing the order of certificates list is not a common requirement
for all back-end implementations.
The order of SNI containers list may be used by specific back-end code,
like Radware’s, for specifying priorities among certificates.
Order is meant to be a hint to resolve conflicts when 2 or more certificates
match the DNS name requested in the SNI client hello.
Specific backends might choose to ignore this order and might employ their
own mechanisms to choose one among the clashing certificates.
For ex. NetScaler employs the best match algorithm and does not require
order for conflict resolution.
It’s also possible that specific driver throws an exception saying there is
a collision and this specific SNI setup will not be supported by the back-end.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Data model changes&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;lbaas_listeners&lt;/em&gt; table will be modified with new&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;default_tls_container_id (nullable string 36) - Barbican’s
TLS container id&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New &lt;em&gt;lbaas_sni&lt;/em&gt; table will be created for storing
ordered list of TLS containers associated to a listener for SNI capabilities.
Association objects is composed of:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;id (immutable string 36) - generated object id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;listener_id (string 36) - associated listener id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tls_container_id (string 36) - associated Barbican TLS container id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;position - (integer) index for preserving the order&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Required database migration&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;add new columns to &lt;em&gt;lbaas_isteners&lt;/em&gt; table&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create new &lt;em&gt;lbaas_sni&lt;/em&gt; table&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;New data initial set&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New columns for &lt;em&gt;lbaas_listeners&lt;/em&gt; table’s existing entries will be set
to defaults&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Listener Attributes&lt;/strong&gt;&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;default-tls-
container-id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW,tenant&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;NULL&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;default TLS cert id
to use for offloading&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;sni_container
_ids&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID
list&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW,tenant&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;NULL&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID list&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ordered list of
TLS containers to use
for SNI              .&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Functions&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create_listener&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Creates new listener&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Request
&lt;em&gt;POST /v2.0/lbaas/listeners
Accept: application/json
{
“listener”:{
&amp;lt;…usual listener parameters&amp;gt;,
“protocol”: “TERMINATED_HTTPS”
“default_tls_container_id”: “7804a0de-7f6b-409a-a47c-a1cc7bc77b4j”,
“sni_container_ids”: None
}
}&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Response
&lt;em&gt;{
“listener”:{
“id”: “8604a0de-7f6b-409a-a47c-a1cc7bc77b2e”
&amp;lt;…usual listener parameters&amp;gt;,
“default_tls_container_id”: “7804a0de-7f6b-409a-a47c-a1cc7bc77b4c”,
“sni_container_ids”: None
“tenant_id”:”6b96ff0cb17a4b859e1e575d221683d3”
}
}&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create_listener (with SNI list)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Creates new listener&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Request
&lt;em&gt;POST /v2.0/lbaas/listeners
Accept: application/json
{
“listener”:{
&amp;lt;…usual listener parameters&amp;gt;,
“protocol”: “TERMINATED_HTTPS”
“default_tls_container_id”: “7804a0de-7f6b-409a-a47c-a1cc7bc77b4j”,
“sni_container_ids”: [5404a0de-7f6b-409a-a47c-a1ccgbc77b3j,
1206a0de-7f6b-409a-a47c-a1ccgbc7bgf3]
}
}&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Response
&lt;em&gt;{
“listener”:{
“id”: “8604a0de-7f6b-409a-a47c-a1cc7bc77b2e”
&amp;lt;…usual listener parameters&amp;gt;,
“default_tls_container_id”: “7804a0de-7f6b-409a-a47c-a1cc7bc77b4c”,
“sni_container_ids”:[5404a0de-7f6b-409a-a47c-a1ccgbc77b3j,
1206a0de-7f6b-409a-a47c-a1ccgbc7bgf3]
“tenant_id”:”6b96ff0cb17a4b859e1e575d221683d3”
}
}&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update_listener&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Updates VIP listener&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Request
&lt;em&gt;PUT /v2.0/lbaas/listeners/&amp;lt;listener-id&amp;gt;
Accept: application/json
{
“listener”:{
&amp;lt;…usual listener parameters&amp;gt;,
“protocol”: “TERMINATED_HTTPS”
“default_tls_container_id”: “7804a0de-7f6b-409a-a47c-a1cc7bc77b4c”,
“sni_container_ids”: None
}
}&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Response
&lt;em&gt;{
“listener”:{
“id”: “8604a0de-7f6b-409a-a47c-a1cc7bc77b2e”
&amp;lt;…usual listener parameters&amp;gt;,
“default_tls_container_id”: “7804a0de-7f6b-409a-a47c-a1cc7bc77b4c”,
“sni_container_ids”: None
“tenant_id”:”6b96ff0cb17a4b859e1e575d221683d3”
}
}&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;Following are security requirements:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Retrieving TLS container from Barbican to LBaaS plugin/driver
must be secured&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sending TLS container contents from driver to back-end system
must be secured&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Storing secrets on neutron server is prohibited&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Back-end systems may need to ensure secured store for secrets
to meet certain security compliance requirements&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="cli-impact"&gt;
&lt;h3&gt;CLI Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Listener creation with TERMINATED_HTTPS protocol (default behavior)
&lt;em&gt;lb-listener-create&lt;/em&gt; &lt;strong&gt;–protocol TERMINATED_HTTPS&lt;/strong&gt;
&lt;em&gt;–protocol-port   443&lt;/em&gt;
&lt;strong&gt;–default_tls_container_id 9a96ff0cb17a4b859e1e575d2216cd23&lt;/strong&gt;
&lt;em&gt;…&amp;lt;usual CLI options&amp;gt;&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Listener creation with TERMINATED_HTTPS protocol and SNI certificates list
&lt;em&gt;lb-listener-create&lt;/em&gt; &lt;strong&gt;–protocol TERMINATED_HTTPS&lt;/strong&gt;
&lt;em&gt;–protocol-port 443&lt;/em&gt;
&lt;strong&gt;–default_tls_container_id 9a96ff0cb17a4b859e1e575d2216cd23
–sni_container_ids list=true
6b96ff0cb17a4b859e1e575d221683d3 4596ff0cb17a4b859e1e575d22168ba1&lt;/strong&gt;
&lt;em&gt;…&amp;lt;usual CLI options&amp;gt;&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;When updating listener without modifying TLS settings
(default container id or SNI list) - Barbican API should not be used
for retrieving container content which was not actually changed.
This will prevent unnecessary resources consumption when, for example,
members are added to the pool used by listener.
It means that each Barbican TLS container will be validated only once
for a listener while it’s still in use by this listener.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Barbican is required to be deployed and functional in order this feature
to work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New dependencies are added for neutron, pyOpenSSL and PyASN1. These
are required by new module for Barbican TLS containers interactions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change has been in review since Juno.  Much discussion has taken place
over IRC and the mailing list.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~evgenyf"&gt;https://launchpad.net/~evgenyf&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Barbican TLS containers interactions module -
&lt;a class="reference external" href="https://launchpad.net/~carlos-garza"&gt;https://launchpad.net/~carlos-garza&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Develop new module for BArbican TLS containers interactions using pyOpenSSL
and PyASN1 packages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement changes in LBaaS DB schema v2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement changes in LBaaS extension v2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement all required CLI changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement all required unit testing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement all required tempest testing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make integration with Barbican certificates storage API
Detailed specificatio of how Barbican’s API for containers should be used
is at &lt;a class="reference external" href="https://review.openstack.org/#/c/99516"&gt;https://review.openstack.org/#/c/99516&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modifying LBaaS HA-Proxy driver to support TLS capability
Detailed specification of this work item
is at &lt;a class="reference external" href="https://review.openstack.org/#/c/100931"&gt;https://review.openstack.org/#/c/100931&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use HA-Proxy version 1.5&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement horizon part of this spec, not as part of Juno release.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Barbican API requirements&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron LBaaS API v2 with new listener object implemented&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New dependencies will be added for neutron, pyOpenSSL and PyASN1. These
are required by new module for Barbican TLS containers interactions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;listener unit testing domains&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;REST API and attributes validation tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DB mixin and schema tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LBaaS Plugin with mocked driver end-to-end tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Specific driver tests for each existing driver supporting TLS offloading&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CLI tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New listener creation with TERMINATED_HTTPS as a protocol&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No default TLS container for termination supplied.
Check error generation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Default TLS container for termination supplied.
Test expected default configuration took place.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Default TLS container supplied.
SNI TLS containers  list was supplied
Test expected configuration took place&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update existing listener with TERMINATED_HTTPS as a protocole&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Change default TLS container. Test expected configuration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add/Modify SNI containers list. Test expected configuration&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CLI tests should test inconsistency issues such as:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;No default offloading TLS container specified when creating listener
with TERMINATES_HTTPS protocole&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;As above.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;As above.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron CLI should be modified with updated
listener commands with TLS options&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Neutron API should be modified with new listener TLS attributes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;TLS RFC &lt;a class="reference external" href="http://tools.ietf.org/html/rfc2818"&gt;http://tools.ietf.org/html/rfc2818&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 15 Dec 2014 00:00:00 </pubDate></item><item><title>Freescale FWaaS Plugin</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/freescale-fwaas-plugin.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/freescale-fwaas-plugin"&gt;https://blueprints.launchpad.net/neutron/+spec/freescale-fwaas-plugin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Note: This Blueprint is proposed for Neutron-FWaaS repository.&lt;/p&gt;
&lt;p&gt;CRD (Cloud Resource Discovery) Service is designed to support Freescale silicon
in data center environment. Like Neutron, it uses keystone authentication for
all ReSTful calls.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Neutron-FWaaS Firewall information (like rules, policies and firewall) is requried
by CRD service to manage Firewall deployment in virtual network appliances and
openflow controller apps.&lt;/p&gt;
&lt;p&gt;In order to send this information to CRD from neutron, a new FWaaS plugin is
required.&lt;/p&gt;
&lt;p&gt;Freescale FWaaS Plugin proxies ReSTful calls (formatted for CRD Service) from
Neutron to CRD Service.&lt;/p&gt;
&lt;p&gt;It supports the Cloud Resource Discovery (CRD) service by updating the Firewall
related data (rules, policies and firewall) into the CRD database.&lt;/p&gt;
&lt;p&gt;CRD service manages creation of firewall on network nodes, virtual network
appliances and openflow controller network applications.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The basic work flow is as shown below.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+-------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                               &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="n"&gt;Neutron&lt;/span&gt; &lt;span class="n"&gt;Service&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                               &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;+--------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Neutron&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;FWaaS&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Freescale&lt;/span&gt; &lt;span class="n"&gt;Firewall&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Service&lt;/span&gt; &lt;span class="n"&gt;Plugin&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----+-----------+--------------+&lt;/span&gt;
                 &lt;span class="o"&gt;|&lt;/span&gt;
                 &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;ReST&lt;/span&gt; &lt;span class="n"&gt;API&lt;/span&gt;
                 &lt;span class="o"&gt;|&lt;/span&gt;
                 &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;+---------&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-----------+&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;CRD&lt;/span&gt; &lt;span class="n"&gt;Service&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;+---------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Freescale Firewall Service plugin sends the Firewall related data to
CRD server.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;The plug-in implements the CRUD operation on the following entities:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Firewall Rules&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Firewall Policies&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Firewall&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The plug-in uses the exisitng firewall database to store the firewall
data.&lt;/p&gt;
&lt;p&gt;The creation of firewall in network node or Virtual Network appliance or
Openflow controller app is decided by CRD service.&lt;/p&gt;
&lt;p&gt;Sequence flow of events for create_firewall is as follows:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;create_firewall&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;neutron&lt;/span&gt;       &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;  &lt;span class="n"&gt;fsl_fw_plugin&lt;/span&gt;
  &lt;span class="n"&gt;fsl_fw_plugin&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;  &lt;span class="n"&gt;crd_service&lt;/span&gt;
  &lt;span class="n"&gt;fsl_fw_plugin&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt; &lt;span class="n"&gt;crd_service&lt;/span&gt;
  &lt;span class="n"&gt;neutron&lt;/span&gt;       &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt; &lt;span class="n"&gt;fsl_fw_plugin&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;Existing models are used.
No new models are created.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Negligible or None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;This change only affects deployments where neutron ‘service_plugins’ is
configured with ‘fsl_firewall’, ‘core_plugin’ is ‘ml2’ and ‘ml2’ plugin is
configured with ‘fslsdn’ mechanism driver.&lt;/p&gt;
&lt;p&gt;‘fslsdn’ mechanism driver configuration is used by this service plugin to
contact CRD service.&lt;/p&gt;
&lt;p&gt;Update [DEFAULT] section of /etc/neutron/neutron.conf as,&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DEFAULT&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;service_plugins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fsl_firewall&lt;/span&gt;
&lt;span class="n"&gt;core_plugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ml2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The following configuration changes are made to enable
Freescale SDN mechanism driver.&lt;/p&gt;
&lt;p&gt;In [ml2] section of /etc/neutron/plugins/ml2/ml2_conf.ini,
modify ‘mechanism_drivers’ attributes as,&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;mechanism_drivers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fslsdn&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Update /etc/neutron/plugins/ml2/ml2_conf_fslsdn.ini, as below.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ml2_fslsdn&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;crd_auth_strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;keystone&lt;/span&gt;
&lt;span class="n"&gt;crd_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="mf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;9797&lt;/span&gt;
&lt;span class="n"&gt;crd_auth_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="mf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="n"&gt;crd_tenant_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;
&lt;span class="n"&gt;crd_password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;crd_user_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;trinath-somanchi&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Freescale FWaaS Service Plugin&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Complete unit test coverage of the code is included.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For tempest test coverage, third party testing is provided.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Freescale CI reports on all changes affecting this Plugin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The testing is run in a setup with an OpenStack deployment (devstack)
connected to an active CRD server.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Complete unit test coverage of the code is included.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Since the usage of this plugin requires ‘ml2’ as core_plugin and ‘fslsdn’ as
mechanism_driver, the above detailed deployer impact will be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None needed beyond documentation changes listed above.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Sun, 14 Dec 2014 00:00:00 </pubDate></item><item><title>Brocade LBaaS Plugin Driver (v2 Data Model Support)</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/brocade-lbaas-v2-driver.html</link><description>

&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;URL of the launchpad blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-brocade-lbaas-driver"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-brocade-lbaas-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Brocade LBaaS Plugin and Driver for the Brocade ADX Load Balancer Devices
for the LBaaS in Neutron.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The driver will implement the interfaces according to the driver interfaces
mentioned in the spec &lt;a class="reference external" href="https://review.openstack.org/100690"&gt;https://review.openstack.org/100690&lt;/a&gt;
for the blueprint
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-objmodel-driver-changes"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-objmodel-driver-changes&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The following managers will be implemented:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;LoadBalancerManager&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ListenerManager&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PoolManager&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MemberManager&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HealthMonitorManager&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Implementation is composed of Plugin Driver and Brocade Device Driver.&lt;/p&gt;
&lt;p&gt;Brocade LBaaS Plugin Driver extends/implements the driver interfaces
as mentioned above and forwards the request to the device driver.&lt;/p&gt;
&lt;p&gt;The device driver communicates with the Brocade ADX Load Balancer
Device (Physical and Virtual) via SOAP/XML APIs.
The device driver use SUDs python module for the SOAP/XML API calls.&lt;/p&gt;
&lt;p&gt;Supported Features&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Protocols:  HTTPS, HTTP, TCP
LB Algorithms: ROUND_ROBIN, LEAST_CONNECTIONS
Session persistence: SOURCE_IP
Health Monitoring: TCP, HTTP, HTTPS
Stats retrieval
CRUD on loadbalancer, listener, pool, healthmonitor, member
Additional lbaas features supported as part of framework in kilo release
(TERMINATED_HTTPS, L7 etc)&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Product Versions supported&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;ADX 12.5 and above
Virtual ADX 3.0, 3.1 and above&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Exceptions&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Brocade LBaaS Device Driver will raise one of the following exceptions&lt;/dt&gt;&lt;dd&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;ConfigError . Raised when a configuration exception occurs&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;on the load balancer device&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;UnsupportedFeature . Raised when a particular feature is not yet&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;supported by the Device Driver&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;UnsupportedOption . Raised when an unsupported value is&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;specified for an attribute.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;Will support ipv6 at the same level as neutron lbaas.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;service_provider entry in the neutron-lbaas.conf file needs to be
updated to reflect Brocade as one of the service_provider for
the plugin to be effective.&lt;/p&gt;
&lt;p&gt;Brocade Device Driver must be installed prior to using this driver&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~pattabi"&gt;https://launchpad.net/~pattabi&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Brocade plugin driver code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Voting CI&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit Tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Brocade QA&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Existing LBaaS tests provide complete coverage, if driver is installed
and configured (as our CI will do)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Brocade ADX CI will run existing LB tempest tests with Brocade ADX/vADX.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Brocade ADX CI will run existing LB functional tests with Brocade ADX/vADX.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Brocade ADX CI will run existing LB API tests with Brocade ADX/vADX.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 11 Dec 2014 00:00:00 </pubDate></item><item><title>IPSec Strongswan VPNaaS Driver</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/ipsec-strongswan-driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ipsec-strongswan-driver"&gt;https://blueprints.launchpad.net/neutron/+spec/ipsec-strongswan-driver&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Ubuntu supports strongSwan in main as of release 14.04. This driver
will provide the choice for the customers to run strongSwan on it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;strongSwan driver is very similar with openswan driver in addition to
quite difference of their configuration files.&lt;/p&gt;
&lt;p&gt;So the currently implemented methods are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;We’d have to create a strongswan_opts based off openswan_opts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide different configuration file template.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a StrongSwanProcess class based off OpenSwanProcess in the
file neutron/services/vpn/device_drivers/ipsec.py (openswan uses pluto
and whack, while strongSwan uses ‘charon’ and ‘stroke’ respectively).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The IPsecDriver._update_nat looks like it sets the right iptables
ipsec needed rules for strongSwan.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;The latest strongSwan 5.x has different attributes than the previous
version. For example, 5.x has abandoned some configurations like
plutostart, nat_traversal, virtual_private, pfs etc, and some
configurations also have the default value like strictpolicy=no,
charonstart=yes.&lt;/p&gt;
&lt;p&gt;OpenSwan has more similiar attributes with the previous version of
strongSwan 5.x, but not with strongSwan 5.x. Initial efforts only
support 5.x and implement an equivalent psk net-to-net vpn service
based on recommended configuration in the link [5] just as openSwan
did in the past. Future blueprints will extend other features for
strongSwan, like API, auth modes, roadwarrior-to-net etc.&lt;/p&gt;
&lt;p&gt;So the capabilites provided by this initail implementation of the
strongSwan driver are the same with openSwan driver [6]:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Net-to-Net Private Network connecting two private networks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multiple VPN connections per tenant.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But the parmeters are somewhat different, like:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;only supporting IKEv2 policy, not support IKEv1.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;only supporting default IPSec policy and DPD now, future blueprints
will extend for more auth modes and more encryption algorithms.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Therefore, the resources API (service, ikepolicy, ipsecpolicy,
ipsec-site-connection) will also do the corresponding code adjustment.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;User will need to configure the INI file for the strongSwan driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;No effect to the VPNaaS performance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Other alternatives will be lack of community support.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Zhang Hua &amp;lt;&lt;a class="reference external" href="mailto:joshua.zhang%40canonical.com"&gt;joshua&lt;span&gt;.&lt;/span&gt;zhang&lt;span&gt;@&lt;/span&gt;canonical&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;StrongSwanProcess code in neutron/services/vpn/device_drivers/ipsec.py&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Work out a configuration file for best practice&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests &amp;amp; Advanced Service tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A netns wrapper to support running strongSwan in different namespace.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update API documentation to reflect strongSwan capabilites.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update user documentation to indicate how to use strongSwan option.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced Service tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functional tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Not applicable. use advanced service tests to cover.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;New neutron functional tests will be added to cover below scenario.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;new a functional test named test_vpnagent_create_process&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;overide the configuration item vpn_device_driver=
neutron.services.vpn.device_drivers.ipsec.StrongSwanDriver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;invoke create_process method then to check if ipsec process has been
started and strongSwan configuration file has been created correctly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Not applicable.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;The default vpn_device_driver is still openSwan, so need to update
vpn_device_driver to use strongSwan in the file /etc/neutron/vpn_agent.ini
in addition to installing strongSwan package.
vpn_device_driver=neutron.services.vpn.device_drivers.ipsec.StrongSwanDriver&lt;/p&gt;
&lt;p&gt;API document mentioned above should also be updated, as part of this effort.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[1] IPSec strongswan driver code: &lt;a class="reference external" href="https://review.openstack.org/#/c/100791/"&gt;https://review.openstack.org/#/c/100791/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[2] IPSec openswan driver bluprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ipsec-vpn-reference"&gt;https://blueprints.launchpad.net/neutron/+spec/ipsec-vpn-reference&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[3] IPSec openswan driver code: &lt;a class="reference external" href="https://review.openstack.org/#/c/33148/"&gt;https://review.openstack.org/#/c/33148/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[4] IPSec openswan driver spec:
&lt;a class="reference external" href="https://docs.google.com/presentation/d/1uoYMl2fAEHTpogAe27xtGpPcbhm7Y3tlHIw_G1Dy5aQ/edit"&gt;https://docs.google.com/presentation/d/1uoYMl2fAEHTpogAe27xtGpPcbhm7Y3tlHIw_G1Dy5aQ/edit&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[5] &lt;a class="reference external" href="http://www.strongswan.org/uml/testresults/ikev2/net2net-psk/"&gt;http://www.strongswan.org/uml/testresults/ikev2/net2net-psk/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[6] &lt;a class="reference external" href="http://docs.openstack.org/api/openstack-network/2.0/content/vpnaas_ext.html"&gt;http://docs.openstack.org/api/openstack-network/2.0/content/vpnaas_ext.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 11 Dec 2014 00:00:00 </pubDate></item><item><title>ML2: Hierarchical Port Binding</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/ml2-hierarchical-port-binding.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ml2-hierarchical-port-binding"&gt;https://blueprints.launchpad.net/neutron/+spec/ml2-hierarchical-port-binding&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint extends ML2 port binding to support hierarchical
network topologies.&lt;/p&gt;
&lt;p&gt;Note to reviewers: A similar blueprint was accepted for the Juno
release and successfully implemented, but the review was not completed
early enough in the cycle for the code to be merged. This
specification has been significantly updated to reflect decisions made
during implementation and in response to review comments, as well as
to improve understandability. It describes the final state of the code
reviewed during Juno. Other than rebasing, no significant changes should
be required to the previously reviewed code.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The ML2 plugin does not adequately support hierarchical network
topologies. A hierarchical virtual network uses different network
segments, potentially of different types (VLAN, VXLAN, GRE,
proprietary fabric, …), at different levels. It might be made up of
one or more top-level static network segments along with dynamically
allocated network segments at lower levels. For example, virtual
network traffic between ToR and core switches could be encapsulated
using VXLAN segments, while traffic for those same virtual networks
between the ToR switches and the compute nodes could use dynamically
allocated VLANs segments.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                        &lt;span class="o"&gt;+-------------+&lt;/span&gt;
                        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
                        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Core&lt;/span&gt; &lt;span class="n"&gt;Switch&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;
                        &lt;span class="o"&gt;+---+-----+---+&lt;/span&gt;
                &lt;span class="n"&gt;VXLAN&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="n"&gt;VXLAN&lt;/span&gt;
                &lt;span class="o"&gt;+-----------+&lt;/span&gt;     &lt;span class="o"&gt;+------------+&lt;/span&gt;
                &lt;span class="o"&gt;|&lt;/span&gt;                              &lt;span class="o"&gt;|&lt;/span&gt;
         &lt;span class="o"&gt;+------+-----+&lt;/span&gt;                 &lt;span class="o"&gt;+------+-----+&lt;/span&gt;
         &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ToR&lt;/span&gt; &lt;span class="n"&gt;Switch&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ToR&lt;/span&gt; &lt;span class="n"&gt;Switch&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
         &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
         &lt;span class="o"&gt;+---+---+----+&lt;/span&gt;                 &lt;span class="o"&gt;+---+----+---+&lt;/span&gt;
     &lt;span class="n"&gt;VLAN&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;VLAN&lt;/span&gt;           &lt;span class="n"&gt;VLAN&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;VLAN&lt;/span&gt;
     &lt;span class="o"&gt;+-------+&lt;/span&gt;   &lt;span class="o"&gt;+----+&lt;/span&gt;                &lt;span class="o"&gt;+----+&lt;/span&gt;    &lt;span class="o"&gt;+------+&lt;/span&gt;
     &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----+----+&lt;/span&gt;      &lt;span class="o"&gt;+----+----+&lt;/span&gt;      &lt;span class="o"&gt;+----+----+&lt;/span&gt;      &lt;span class="o"&gt;+----+----+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Compute&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Compute&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Compute&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Compute&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+---------+&lt;/span&gt;      &lt;span class="o"&gt;+---------+&lt;/span&gt;      &lt;span class="o"&gt;+---------+&lt;/span&gt;      &lt;span class="o"&gt;+---------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Dynamically allocating segments at lower levels of the hierarchy is
particularly important in allowing Neutron deployments to scale beyond
the 4K limit per physical network for VLANs. VLAN allocations can be
managed at lower levels of the hierarchy, allowing many more than 4K
virtual networks to exist and be accessible to compute nodes as VLANs,
as long as each link from ToR switch to compute node needs no more
than 4K VLANs simultaneously.&lt;/p&gt;
&lt;p&gt;Support for allocating dynamic segments was merged to ML2 during
Juno. But there is currently no way for these dynamic segments to be
allocated by one mechanism driver supporting the ToR switch, and used
by a different mechanism driver supporting the L2 agent on the compute
node. What is needed is the ability for an initial mechanism driver to
partially bind to a static segment of a port’s virtual network, and
provide a dynamic segment that can be bound by a different mechanism
driver at the next level, continuing until the binding is complete.&lt;/p&gt;
&lt;p&gt;Note that the diagram above shows static VXLAN segments connecting ToR
and core switches, but this most likely isn’t the current ‘vxlan’
network_type where tunnel endpoints are managed via RPCs between the
Neutron server and L2 agents. It would instead be a network_type
specific to both the encapsulation format and the way tunnel endpoints
are managed among the switches. Each network_type value should
identify a well-defined standard or proprietary protocol, enabling
interoperability where desired, and coexistance within heterogeneous
deployments.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;ML2 will support hierarchical network topologies by binding ports to
mechanism drivers and network segments at each level of the
hierarchy. For example, one mechanism driver might bind to a static
VXLAN segment of the network, causing a ToR switch to bridge that
network to a dynamically allocated VLAN on the link(s) to the compute
node(s) connected to that switch, while a second mechanism driver,
such as the existing OVS or HyperV driver, would bind the compute node
to that dynamic VLAN.&lt;/p&gt;
&lt;p&gt;Supporting hierarchical network topologies impacts the ML2 driver APIs
and ML2’s port binding data model, but does not change Neutron’s REST
APIs in any way.&lt;/p&gt;
&lt;p&gt;A new function and property will be added to the PortContext class in
the driver API to enable hierarchical port binding.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;PortContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;

    &lt;span class="nd"&gt;@abc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;continue_binding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;segment_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;next_segments_to_bind&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="nd"&gt;@abc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abstractproperty&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;segments_to_bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The new continue_binding() method can be called from within a
mechanism driver’s bind_port() method as an alternative to the
existing set_binding() method. As is currently the case, if a
mechanism driver can complete a binding, it calls
PortContext.set_binding(segment_id, vif_type, vif_details, status). If
the mechanism driver can only partially establish a binding, it will
instead call continue_binding(segment_id, next_segments_to_bind). If
the mechanism driver cannot bind at all, it simply returns without
calling either of these.&lt;/p&gt;
&lt;p&gt;As with set_binding(), the segment_id passed to continue_binding()
indicates the segment that this driver is binding to. The new_segments
parameter specifies the set of network segments that can be used by
the next stage of binding for the port. It will typically contain a
dynamically allocated segment that the next driver will use to
continue or complete the binding.&lt;/p&gt;
&lt;p&gt;Currently, mechanism drivers try to bind using the segments from the
PortContext.network.network_segments property. These are the network’s
static segments. The new PortContext.segments_to_bind property should
now be used instead by all drivers. For the initial stage of binding,
it will contain the same segments as
PortContext.network.network_segments. But for subsequent stages, it
will contain the segment(s) passed as next_segments_to_bind to
PortContext.continue_binding() by the previous stage driver.&lt;/p&gt;
&lt;p&gt;The ML2 plugin currently tries to bind using all registered mechanism
drivers in the order they are specified in the mechanism_drivers
config variable. To support hierarchical binding, only a minor change
is needed to avoid any possibility of binding loops in misconfigured
or misbehaving deployments. At each stage of binding, any drivers that
have already bound at a higher level using any of the current level’s
set of segments to bind are excluded. This approach allows the same
driver to partially bind at multiple levels of a hierarchical network
using different segments, but not using the same segment. Also, if a
limit on the total number of binding levels is exceeded, binding will
fail and an error will be logged.&lt;/p&gt;
&lt;p&gt;Finally, to enable mechanism drivers to see the details of
hierarchical (as well as normal) bindings, the PortContext’s
bound_segment, original_bound_segment, bound_driver, and
original_bound_driver properties will be replaced with a new set of
properties:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;PortContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;

    &lt;span class="nd"&gt;@abc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abstractproperty&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;binding_levels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="nd"&gt;@abc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abstractproperty&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;original_binding_levels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="nd"&gt;@abc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abstractproperty&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;top_bound_segment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="nd"&gt;@abc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abstractproperty&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;original_top_bound_segment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="nd"&gt;@abc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abstractproperty&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;bottom_bound_segment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="nd"&gt;@abc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abstractproperty&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;original_bottom_bound_segment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The binding_levels and original_binding_levels properties return a
list of dictionaries describing each binding level if the port is/was
fully or partially bound. Keys for BOUND_DRIVER and BOUND_SEGMENT are
defined, and additional keys can be added in future versions if
needed. The first entry describes the top-level binding, which always
involves one of the port’s network’s static segments. When fully
bound, the last entry describes the bottom-level binding that supplied
the port’s binding:vif_type and binding:vif_details attribute values.&lt;/p&gt;
&lt;p&gt;In the presence of hierarchical bindings, some mechanism drivers that
used the old bound_segment, original_bound_segment, bound_driver,
and/or original_bound_driver properties need to access the top-level
binding, while other drivers need to access the bottom-level
binding. Therefore, the old properties will be replaced by new sets of
properties providing access to each of these.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;In order to store multiple levels of binding information for access by
mechanism drivers, changes to the ML2 database schema are
required. The driver and segment columns will be moved from the
existing ml2_port_bindings and ml2_dvr_port_bindings tables to a new
ml2_port_binding_levels table. This table will have port_id, host, and
level columns as primary keys. No separate DVR-specific table will be
needed.&lt;/p&gt;
&lt;p&gt;A DB migration will be provided that moves existing binding data to
the new table on upgrade. Downgrades will preserve existing
single-level binding data, but there is no sensible way to preserve
existing multi-level bindings on downgrade.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;No REST API changes are proposed in this specification.&lt;/p&gt;
&lt;p&gt;Using the existing providernet and multiprovidernet API extensions,
only the top-level static segments of a network are accessible. There
is no current need to expose dynamic segments through REST APIs. The
portbindings extension could potentially be modified in the future to
expose more information about multi-level bindings if needed.&lt;/p&gt;
&lt;p&gt;As mechanism drivers for specific network fabric technologies are
developed, new network_type values may be defined that will be visible
through the providernet and multiprovidernet extensions. But no new
network_type values are being introduced in this specific BP.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;Hierarchical network topologies should enable OpenStack deployments to
scale to larger numbers of networks.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Hierarchical network topologies may improve tenant network throughput
by utilizing low-overhead encapsulation techiniques such as VLAN at
the compute node level, while specialized network switches handle the
more advanced encapsulation needed to scale to very large numbers of
networks.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;No impact, since this blueprint is at layer 2.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;No change is required when deploying non-hierarchical network
topologies. When deploying hierarchical network topologies, additional
mechanism drivers will need to be configured. Additionally, when VLANs
are used for the bottom-level bindings, L2 agent configurations will
be impacted as described in the next few paragraphs.&lt;/p&gt;
&lt;p&gt;Mechanism drivers determine whether they can bind to a network segment
by looking at the network_type and any other relevant information. For
example, if network_type is ‘flat’ or ‘vlan’, the L2 agent mechanism
drivers look at the physical_network and, using agents_db info, make
sure the L2 agent on that host has a mapping for the segment’s
physical_network. This is how the existing mechanism drivers work, and
this will not be changed by this BP.&lt;/p&gt;
&lt;p&gt;With hierarchical port binding, where a ToR switch is using dynamic
VLAN segments and the hosts connected to it are using a standard L2
agent, the L2 agents on the hosts will be configured with a mapping
for a physical_network name that corresponds to the scope at which the
switch assigns dynamic VLANs.&lt;/p&gt;
&lt;p&gt;If dynamic VLAN segments are assigned at the switch scope, then each
ToR switch should have a unique corresponding physical_network
name. The switch’s mechanism driver will use this physical_network
name in the dynamic segments it creates as partial bindings. The L2
agents on the hosts connected to that switch must have a (bridge or
interface) mapping for that same physical_network name, allowing any
of the normal L2 agent mechanism drivers to complete the binding.&lt;/p&gt;
&lt;p&gt;If dynamic VLAN segments are instead assigned at the switch port
scope, then each switch port would have a corresponding unique
physical_network name, and only the host connected to that port should
have a mapping for that physical_network.&lt;/p&gt;
&lt;p&gt;Since multi-level network deployments will typically involve a
particular vendor’s propriery switches, that vendor should supply
documentation and deployment tools to assist the administrator.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Mechanism drivers that support hierarchical bindings will use the
additional driver API call(s). Other drivers will only need a very
minor update to use PortContext.segments_to_bind in place of
PortContext.network.network_segments, and the new properies for
accessing the top or bottom bound segment or driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change provides new capabilities for ML2 mechanism drivers to
support hierarachical network topologies. This supports the
community’s interest in allowing Neutron to scale to larger
deployments. It has been discussed at ML2 sub-team meetings, and at
the Juno and Kilo summits.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The alternative is for vendors that need to support hierarchical
network topologies to do so through monolithic plugins rather than
ML2, or through ML2 mechanism drivers that require customized L2
agents.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;rkukura&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;asomya&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;As was done during Juno, the implementation will consist of a series of three patches:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The driver API changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The DB schema changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The binding logic changes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Use of this feature requires the dynamic segment feature that was
merged during Juno.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will verify all the new driver API methods and properties,
and that hierarchical port bindings can be established with a test
mechanism driver. Real mechanism drivers using hierarchical bindings
will be tested in the correspinding 3rd party CI, where the required
switch hardware is available.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;No new tempest tests are required because there is no change in
application level behavior. 3rd party CI testing using the existing
tempest tests will adequately exercise the hierarchical port binding
functionality.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;No new functional tests are required because there are no system level
interactions that cannot be tested in unit tests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;There are no REST API changes to test.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Deployer documentation is the responsibility of 3rd parties that
provide mechanism drivers that establish hierarchical bindings.&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;No user documentation changes are required.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;The primary developer documentation is derived from the doc strings in
the driver API source file, which describe the APIs and their behavior
in detail. If an ML2 driver writers guide is ever written, it will
need to cover hierarchical port binding.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 08 Dec 2014 00:00:00 </pubDate></item><item><title>RPC Docs and Namespaces</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/rpc-docs-and-namespaces.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/rpc-docs-and-namespaces"&gt;https://blueprints.launchpad.net/neutron/+spec/rpc-docs-and-namespaces&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint aims to enhance the existing usage of oslo.messaging to make the
version scheme more clear to developers.  Several people have expressed that the
current code is difficult to understand, so this spec aims to improve that.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Neutron uses the oslo.messaging library to provide an internal communication
channel between Neutron services.  This communication is typically done via
AMQP, but those details are mostly hidden by the use of oslo.messaging and it
could be some other protocol in the future.&lt;/p&gt;
&lt;p&gt;RPC APIs are defined in Neutron in two parts: client side and server side.&lt;/p&gt;
&lt;section id="client-side"&gt;
&lt;h3&gt;Client Side&lt;/h3&gt;
&lt;p&gt;Here is an example of an rpc client definition:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;oslo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;messaging&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;neutron.common&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;rpc&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;n_rpc&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ClientAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""Client side RPC interface definition.&lt;/span&gt;

&lt;span class="sd"&gt;    API version history:&lt;/span&gt;
&lt;span class="sd"&gt;        1.0 - Initial version&lt;/span&gt;
&lt;span class="sd"&gt;        1.1 - Added my_remote_method_2&lt;/span&gt;
&lt;span class="sd"&gt;    """&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;messaging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1.0'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n_rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;my_remote_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;cctxt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cctxt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'my_remote_method'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;my_remote_method_2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;cctxt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1.1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cctxt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'my_remote_method_2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This class defines the client side interface for an rpc API.  The interface has
2 methods.  The first method existed in version 1.0 of the interface.  The
second method was added in version 1.1.  When the newer method is called, it
specifies that the remote side must implement at least version 1.1 to handle
this request.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="server-side"&gt;
&lt;h3&gt;Server Side&lt;/h3&gt;
&lt;p&gt;The server side of an rpc interface looks like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;oslo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;messaging&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ServerAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;messaging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1.1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;my_remote_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'foo'&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;my_remote_method_2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'bar'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This class implements the server side of the interface.  The messaging.Target()
defined says that this class currently implements version 1.1 of the interface.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="versioning"&gt;
&lt;h3&gt;Versioning&lt;/h3&gt;
&lt;p&gt;Note that changes to rpc interfaces must always be done in a backwards
compatible way.  The server side should always be able to handle older clients
(within the same major version series, such as 1.X).&lt;/p&gt;
&lt;p&gt;It is possible to bump the major version number and drop some code only needed
for backwards compatibility.  For more information about how to do that, see
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/RpcMajorVersionUpdates"&gt;https://wiki.openstack.org/wiki/RpcMajorVersionUpdates&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Each stream of version numbers is associated with a target.  On the client side,
you set up a target that identifies the destination of your method call.  Every
method exposed at that target is a single API from the oslo.messaging
perspective, regardless of the implementation details on the other side.&lt;/p&gt;
&lt;p&gt;Unfortunately, in the Neutron code today, it’s inconsistent and generally
difficult to tell what is considered a part of the same version stream or is
separate.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="a-demonstrative-example-dhcp-agent"&gt;
&lt;h3&gt;A demonstrative example: DHCP Agent&lt;/h3&gt;
&lt;p&gt;There is an RPC interface defined that allows the Neutron plugin to
remotely invoke methods in the DHCP agent.  The client side is defined in
neutron.api.rpc.agentnotifiers.dhcp_rpc_agent_api.DhcpAgentNotifyApi.  The
server side of this interface that runs in the DHCP agent is
neutron.agent.dhcp_agent.DhcpAgent.&lt;/p&gt;
&lt;p&gt;The DHCP agent includes a client API, neutron.agent.dhcp_agent.DhcpPluginAPI.
The DHCP agent uses this class to call remote methods back in the Neutron
server.  The server side is defined in
neutron.api.rpc.handlers.dhcp_rpc.DhcpRpcCallback.  This is where versioning
starts to get complicated.&lt;/p&gt;
&lt;p&gt;A version number is associated with an oslo.messaging.Target.  The target of a
message is specified using a topic (and optionally a specific host on that
topic).  Everything exposed via the same target must be versioned as a part of
the same version stream.  The DhcpRpcCallback API is exposed on the ‘q-plugin’
topic.  Several other things are exposed on the same topic.  For example, when
using the ml2 plugin, the relevant code is:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;endpoints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RpcCallbacks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;notifier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type_manager&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                  &lt;span class="n"&gt;securitygroups_rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecurityGroupServerRpcCallback&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                  &lt;span class="n"&gt;dvr_rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DVRServerRpcCallback&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                  &lt;span class="n"&gt;dhcp_rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DhcpRpcCallback&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                  &lt;span class="n"&gt;agents_db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AgentExtRpcCallback&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                  &lt;span class="n"&gt;metadata_rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MetadataRpcCallback&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With the way the code is written today, the API exposed via the ‘q-plugin’ topic
is the &lt;em&gt;union&lt;/em&gt; of the APIs defined by the following classes:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plugins&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ml2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RpcCallbacks&lt;/span&gt;
    &lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plugins&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ml2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drivers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type_tunnel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TunnelRpcCallbackMixin&lt;/span&gt;
&lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;securitygroups_rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecurityGroupServerRpcCallback&lt;/span&gt;
&lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dvr_rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DVRServerRpcCallback&lt;/span&gt;
&lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dhcp_rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DhcpRpcCallback&lt;/span&gt;
&lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agents_db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AgentExtRpcCallback&lt;/span&gt;
&lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata_rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MetadataRpcCallback&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;That means that an API change to &lt;em&gt;ANY&lt;/em&gt; of these APIs means an increase in a
version number stream that spans all of these interfaces.  However, the
implementation seems to suggest that they are versioned independently, but it’s
not consistent.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This spec proposes two changes.  The goal of the changes is to help make it more
clear what the scope of the version numbers are.  It should make handling of
these version numbers a bit easier to understand and hopefully less error prone
as a result.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For every client and server rpc interface definition in Neutron, add
documentation that makes it very clear where the corresponding other side of the
interface lives in the code.  Also, the documentation will list any other
classes that are included in the same version stream.&lt;/p&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;Use namespaces&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When defining an oslo.messaging.Target, you can add a namespace.  This allows
you to expose multiple interfaces on the same topic but still version them
independently.&lt;/p&gt;
&lt;p&gt;If we revisit the example of the ‘q-plugin’ topic and the ml2 driver, we have
several interfaces exposed on the same topic in the default namespace.
Namespaces will be used to separate these interfaces so that each interface can
be versioned independently.&lt;/p&gt;
&lt;p&gt;For example, one of the interfaces exposed is
neutron.api.rpc.handlers.dhcp_rpc.DhcpRpcCallback.  The beginning of that
implementation looks like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;DhcpRpcCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""DHCP agent RPC callback in plugin implementations."""&lt;/span&gt;

    &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;messaging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1.1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Instead, the target will now be defined with a namespace:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;DhcpRpcCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""DHCP agent RPC callback in plugin implementations."""&lt;/span&gt;

    &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;messaging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'dhcp'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1.1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Similarly, the client side must be updated as well.
neutron.agent.dhcp_agent.DhcpPluginAPI.__init__ includes the following code:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;messaging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1.0'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n_rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The change here is quite similar to what’s done on the server side:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;messaging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'dhcp'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1.0'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n_rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now, when the client makes a request it is being much more explicit.  The server
side will only look for the requested method on the endpoint marked with the
‘dhcp’ namespce, instead of all included endpoints.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Technically, this change is not backwards compatible.  The reality is that only
matters if you expect any sort of live upgrade to work.  Since live upgrades
aren’t actually expected to work, this spec proposes just accepting this
theoretical incompatibility since it doesn’t matter in practice, yet.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;The developer impact should be minimal.  Hopefully the impact is just that when
developers come across the need to change one of these interfaces, it’s a bit
more clear what other parts of the code are impacted.  Developers will also have
to be aware of the new namespace usage for any new interfaces added in the
future.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;The only things proposed here are documentation and use of a standard
oslo.messaging APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Instead of using namespaces, you could expose each interface on its own topic.
Namespaces are a bit more convenient, as a service tends to have one topic set
up using common code.  That common code would have to be reworked to support an
arbitrary list of endpoints mapped to topics.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;russellb&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Convert code base to use namespaces as appropriate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add doc strings to all rpc client and server interfaces.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;drop-rpc-compat blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/drop-rpc-compat"&gt;https://blueprints.launchpad.net/neutron/+spec/drop-rpc-compat&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Existing testing will validate that these changes have not caused regressions.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Additional developer documentation is a key deliverable of this blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;oslo.messaging documentation:
&lt;a class="reference external" href="http://docs.openstack.org/developer/oslo.messaging/"&gt;http://docs.openstack.org/developer/oslo.messaging/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 08 Dec 2014 00:00:00 </pubDate></item><item><title>Proposal for Neutron Services spin-off(s)</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/services-split.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/services-split"&gt;https://blueprints.launchpad.net/neutron/+spec/services-split&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This proposal deals with the technical aspects of splitting the neutron repo
into four repos, one for basic L2/L3 plumbing, and one each for LBaaS, FWaaS,
and VPNaaS.  The repos will be referred to as “neutron”, “vpnaas”, “fwaas”,
and “lbaas” within this spec, until project names for the repos are selected.&lt;/p&gt;
&lt;p&gt;This spec does not cover governance concerns.  For that issue, refer to the
mailing list thread at the end of this document, or talk to the Networking
Program PTL.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The following blurb is shamelessly stolen from an email thread started by
Mark McClain:&lt;/p&gt;
&lt;p&gt;Over the last several months, the members of the Networking Program have been
discussing ways to improve the management of our program.  When the Quantum
project was initially launched, we envisioned a combined service that included
all things network related.  This vision served us well in the early days as
the team mostly focused on building out layers 2 and 3; however, we have run into
growth challenges as the project started building out layers 4 through 7.
Initially, we thought that development would float across all layers of the
networking stack, but the reality is that the development concentrates around
either layer 2 and 3 or layers 4 through 7.  In the last few cycles, we have also
discovered that these concentrations have different velocities and a single
core team forces one to match the other to the detriment of the one forced to
slow down.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Going forward we want to divide the Neutron repository into multiple separate
repositories lead by a common Networking PTL. The current mission of the
program will remain unchanged.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The repo will be split via infra scripts which will preserve history for all
changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The existing lbaas code will move into the lbaas repo, to be supported
by that team going forward.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The existing fwaas code will move into the fwaas repo, to be supported
by that team going forward.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The existing vpnaas code will move into the vpnaas repo, to be supported
by that team going forward.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unlike core neutron, vendor code will remain in each of the service repos,
while we are still attempting to build community/critical mass.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The service repos will include Neutron as a requirement.  This may flip
for the very short-term until the L3 agent is refactored to not derive
from the firewall class.  Package maintainers &lt;em&gt;must&lt;/em&gt; install the services
along with Neutron for any upgrade from Icehouse/Juno to Kilo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The service repos will support the same tox environments as neutron.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bugfixes for services will need to continue to be backported into the Neutron
stable branches for several releases.  Backporting should preserve change-id
and commit message.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In Kilo, the API client/CLI will be via the neutronclient.  This does not
preclude creating a standalone client/API, but it will not be a split
requirement.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This is about splitting repos.  Nothing in this spec should be viewed as
deprecating any currently shipping service code, even if it moves repos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Third-party CIs must point at the relevant repo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In Kilo, the four repos will play nicely together on master, but not
between any other versions/branches.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="kilo-1-to-occur-during-neutron-meetup-12-8"&gt;
&lt;h3&gt;Kilo-1 (to occur during neutron meetup, 12/8)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Before the split, an infra/project-config change for the new repos, and
new core teams will be created.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After the split, all WildcardaaS code and db models will be in their new repo,
with history preserved.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After the split, no lbaas/fwaas/vpnaas services code to be in the neutron
repo, with non-relavant history pruned (exception: extensions and l3 agent,
see below.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extensions will stay in neutron until post rest-refactor, to avoid breaking
the co-gate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Service repos will continue to use the database defined in neutron.conf,
but will have their own tables and alembic chains.  Foreign keys between
migration chains will not be allowed; existing foreign key relationships
should be dealt with during kilo refactors/cleanup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Service repos will use their own config file, located under /etc/neutron.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Code merged onto the existing ‘feature/lbaasv2’ neutron feature branch will
be merged into the lbaas repo as part of the split.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All outstanding gerrit reviews for services, currently submitted against
Neutron, will have to be abandoned and resubmitted against the relevant
service repo. Spec reviews will remain as-is, as the spec repo is not changing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tox will pass cleanly in all projects immediately post-split, except for the
silly never-passing py3 environments.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="kilo-2"&gt;
&lt;h3&gt;Kilo-2&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Deadline for third-party CIs to be updated for new repos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Post REST-refactor, extensions will be moved to the service repos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refactor L3 agent to not depends on services code.  This work is part of
the current Kilo L3 refactor.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="kilo-3"&gt;
&lt;h3&gt;Kilo-3&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;No more foreign keys crossing alembic chains.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L3 agent refactor complete, break circular exception between neutron/services
for the l3_agent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API tests into each service repo.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="l-release"&gt;
&lt;h3&gt;L release&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Anywhere that services import neutron, evaluate whether it is using neutron
as a library appropriately, or if it implies a missing interface in the
Neutron API.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="m-release"&gt;
&lt;h3&gt;M release&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Services have their own REST endpoints, databases, config files, and CLI/API
clients.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;Services data models will be moved to the service repos, and removed from
neutron.&lt;/p&gt;
&lt;p&gt;The service repos will each have their own database migration chains.&lt;/p&gt;
&lt;p&gt;An initial db migration state will be created by starting from the neutron
db state as of the split and stripping non-service related tables.&lt;/p&gt;
&lt;p&gt;Foreign keys referencing neutron models will be continue to store the uuid of the
neutron object, but the associated orm reference will be converted to query the
neutron database.  Existing foreign key associations: Firewall, none.
LBaaS: VIP model references Port.  VPN: VPNService references subnet and router.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;The REST API will be identical immediately before and after the split.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;The new service projects will have their own database tables, migration chains,
and config files.  In addition, by the end of Kilo, neutron will need to load
all of the services API extensions from the out-of-neutron repos.&lt;/p&gt;
&lt;p&gt;For Kilo, neutron will assume that the services repos exist, and include the
path to their API extensions in the neutron.conf file by default
(api_extensions_path).&lt;/p&gt;
&lt;p&gt;In the upgrade scenario, the REST controller will bounce, but active services
(load balancers, etc) will remain active.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Anyone importing neutron.services will have to import the new project modules
instead.&lt;/p&gt;
&lt;p&gt;Patches might need to be resubmitted against the correct repo.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This will enable teams focused exclusively on one or more advanced services to
make a bigger impact and ensure progress.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Do nothing and keep it all in one repo.  This is the status quo, and is
untenable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron split into two repos, one neutron, one advanced services.  The benefits
of this approach are a larger initial community, a simpler split, and
somewhere for new advanced services to “incubate” in-tree other than Neutron.
The downsides are similar to continuing to have services in
Neutron itself: less focus, larger chance of the priorities of a popular
service overriding a less popular or newer one, and less separation of concerns.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Services to stackforge.  Completely separate governance, must be incubated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Services split with its own REST server endpoint.  More separation of concerns,
more work required.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Services have their own databases entirely.  Enforces better separation, but
likely overkill before there are separate REST endpoints.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify gerrit to allow different core teams in one repo.  This does not
encourage separation of concerns, and gerrit does not support this today.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Split repos but continue to use neutron db (own tables, own chains)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The service repos will need to use neutron as a library, and should have a
dependency on Neutron. But, to accomodate seamless upgrades from
Icehouse/Juno to Kilo, the dependencies could be flipped for one cycle:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For Kilo, neutron will have a dependency on each of the service repos, to
make install of the services automatic with Neutron for Kilo.  Also, only
for Kilo, neutron will have a hacking rule to prevent importing any of the
service repos, in preparation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For Kilo, to prevent a circular dependency, the services can assume that
the neutron code is installed, and import it as needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For L, the dependency will be removed from neutron, and each of the service
repos will add a neutron dependency of their own.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~dougwig"&gt;https://launchpad.net/~dougwig&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;LBaaS assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~dougwig"&gt;https://launchpad.net/~dougwig&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;FWaaS assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~snaiksat"&gt;https://launchpad.net/~snaiksat&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;VPNaaS assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~pcm"&gt;https://launchpad.net/~pcm&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~mestery"&gt;https://launchpad.net/~mestery&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Work items for the split:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Identify files for each repo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adapt oslo graduation script for git split.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Merge in lbaasv2 feature branch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adjust imports in new repos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add requirements to each project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add hacking rule to neutron to prevent service import, with the exception
of the existing import in the L3 agent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify or add neutron’s ability to load out-of-tree service plugins.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create initial services db migration files, make sure all get applied.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fix references to neutron in various files (e.g. README)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finalize project names&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Infra patch to create new repos/groups&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get unit tests passing cleanly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Work items that are implied in doing the split, but which will happen separately/afterwards:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Anywhere that services import neutron, evaluate whether it is using neutron
as a library appropriately, or if it implies a missing interface in the
Neutron API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refactor L3 agent to not reach into the guts of services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API tests into each service repo.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Infra creating separate repos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;REST refactor not colliding at the same time.  This needs to happen before
or after.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Unit tests will split between repos, matching the code split.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests will initially remain unchanged, as the service endpoint will
be identical before and after the split.  Setup steps that touch db and/or
config files may need to be updated to reflect new locations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced services test will be removed from the “integrated gate”. load
balancing &amp;amp; friends will co-gate with neutron only, and not anymore with
nova, cinder and the others.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Unchanged, unless tests are in neutron by the split, then they will move.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Tests which load extensions by their extension namespace will be updated for
the new paths.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Unchanged, unless tests are in neutron by the split, then they will move.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Documentation referencing neutron.conf and the neutron db will need to be
modified to reflect the new config file and database.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Documentation referencing neutron.conf and the neutron db will need to be
modified to reflect the new config file and database.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2014-November/050961.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2014-November/050961.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Summit etherpad - &lt;a class="reference external" href="https://etherpad.openstack.org/p/neutron-services"&gt;https://etherpad.openstack.org/p/neutron-services&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Repo creation - &lt;a class="reference external" href="https://review.openstack.org/#/c/138475/"&gt;https://review.openstack.org/#/c/138475/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Governance change - &lt;a class="reference external" href="https://review.openstack.org/138479"&gt;https://review.openstack.org/138479&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 08 Dec 2014 00:00:00 </pubDate></item><item><title>Radware LBaaS Driver</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/radware-lbaas-driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/radware-lbaas-driver"&gt;https://blueprints.launchpad.net/neutron/+spec/radware-lbaas-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron/LBaaS driver for Radware ADC.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;The new driver would allow using Radware ADC appliances&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;as backends for Neutron/LBaaS functionality.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The driver (v2 driver based on v2 object model and API) will implement the
interfaces in the LoadBalancerBaseDriver, using vDirect REST API,
a JSON HTTP interface for configuring Radware appliances.
The following managers will be implemented:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;LoadBalancerManager&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ListenerManager&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PoolManager&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MemberManager&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HealthMonitorManager&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee: &lt;a class="reference external" href="https://launchpad.net/~avishayb"&gt;https://launchpad.net/~avishayb&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Radware driver code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Voting CI&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/101084/"&gt;https://review.openstack.org/#/c/101084/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional Tests sohuld be added for driver&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Sun, 07 Dec 2014 00:00:00 </pubDate></item><item><title>Neutron LBaaS v2 driver for Citrix NetScaler appliances</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/netscaler-lbaas-v2-driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/netscaler-lbaas-v2-driver"&gt;https://blueprints.launchpad.net/neutron/+spec/netscaler-lbaas-v2-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron LBaaS v2 driver for Citrix NetScaler appliances.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Enable NetScaler appliances to be LBaaS backends.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The driver will implement the LBaaS v2 driver interface, as a shim to a
middle ware NetScaler Control Center, ultimately configuring LB in
NetScaler appliances. This implementation will be similar to the
current v1 driver.&lt;/p&gt;
&lt;p&gt;This driver will include TLS and L7 functionality included in LBaaS v2.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;Driver communicates with infrastructure hardware via https.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;Will support ipv6 at the same level as neutron lbaas.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;NetScaler Control Center virtual appliance must be deployed prior to using this driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~vijay-venkatachalam"&gt;https://launchpad.net/~vijay-venkatachalam&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Driver shim&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests for shim&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;3rd-party CI&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;LBaaS v2&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Third-party CI will run existing LB tempest tests with NetScaler Control Center as middleware
and NetScaler VPX appliances as backends.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Third-party CI will run existing LB functional tests with NetScaler Control Center as middleware
and NetScaler VPX appliances as backends.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Third-party CI will run existing LBaaS API tests with NetScaler Control Center as middleware
and NetScaler VPX appliances as backends.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;LBaaS v2 - &lt;a class="reference external" href="https://review.openstack.org/#/c/138205/"&gt;https://review.openstack.org/#/c/138205/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Sat, 06 Dec 2014 00:00:00 </pubDate></item><item><title>LBaaS reference implementation TLS support</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/lbaas-ref-driver-impl-tls.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-ref-impl-tls-support"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-ref-impl-tls-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;LBaaS reference HAProxy implementation needs improvement to support
TLS including SNI.&lt;/p&gt;
&lt;p&gt;This blueprint describes the changes that should be made to the HAProxy
reference implementation to allow features provided by the blueprints:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-ssl-termination"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-ssl-termination&lt;/a&gt;
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-refactor-haproxy-namespace-driver-to-new-driver-interface"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-refactor-haproxy-namespace-driver-to-new-driver-interface&lt;/a&gt;
and its successors to be implemented.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The reference driver and its utilities currently do not support ‘advanced’
features hindering the forward development of advanced API features suggested in
the ‘lbaas-ssl-termination’ blueprint.&lt;/p&gt;
&lt;p&gt;In order to support TLS offloading configurations the reference driver (HAProxy)
must be updated to ensure proper ‘backend’ behavior and capabilities.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Features not currently supported in HAProxy 1.4 (current stable):&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;TLS termination.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TLS Source IP session persistence&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;X-Forwarded-For headers for TLS connections.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TLS Source IP load balancing method&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TLS re-encryption&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;This spec will not include scope for L7, source_ip session persistence, TLS
session ID session persistence, source_ip load balancing algorithm, TLS
re-encryption as well as x-forwarded-for or certificate based client
authentication.&lt;/p&gt;
&lt;p&gt;Scope of this spec is to include TLS which includes SNI support.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The current reference driver named ‘namespace_driver’ utilizes HAProxy 1.4.
Update to use HAProxy 1.5(dependent on packaging)&lt;/p&gt;
&lt;p&gt;In order to implement these features a few things need to be done:&lt;/p&gt;
&lt;p&gt;1. Update HAProxy config. The configuration will be built using Jinja
as specified in spec: “&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/"&gt;https://blueprints.launchpad.net/neutron/+spec/&lt;/a&gt;
lbaas-refactor-haproxy-namespace-driver-to-new-driver-interface” and will
expand on it to include TLS features.&lt;/p&gt;
&lt;p&gt;The configuration utility will configure new directories and files for
HAProxy and certificates in the structure below. This will ensure no name
collisions.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$state_path/lbaas/$lb_uuid/
$state_path/lbaas/$lb_uuid/$cert1_barbican_id.pem
$state_path/lbaas/$lb_uuid/$cert2_barbican_id.pem
$state_path/lbaas/$lb_uuid/$certN_barbican_id.pem
$state_path/lbaas/$lb_uuid/haproxy.conf
$state_path/lbaas/$lb_uuid/run/
$state_path/lbaas/$lb_uuid/run/haproxy.pid
$state_path/lbaas/$lb_uuid/run/haproxy_stats.sock
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;2. The pem file containing the private key will be written
with permissions such that its only readable by root to protect security
credentials.&lt;/p&gt;
&lt;p&gt;Modification of neutron.agent.linux.util#replace_file to accept an optional
‘file_mode’ argument to specify permissions other then default ‘0644’. This
protects against race condition where attacker reads the private key
before the file permissions are set.&lt;/p&gt;
&lt;p&gt;3. There are also tear down methods i.e. undeploy_instance that will need to be
updated for proper clean up. (kill pids)&lt;/p&gt;
&lt;p&gt;Additional Thoughts:
Those using devstack will not be able to use this feature unless manually
installed or devstack itself is updated. This would need to be updated
on that side at some point.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None. This blueprint is intended to provide capabilities that can be supported
in future versions of the REST API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;Users private key will be written into a file readable by root on the local file
system of the network node.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;Devstack will need to be updated to install the new packages(HAProxy 1.5).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Additional calls will have to be made to spawn additional instances.&lt;/p&gt;
&lt;p&gt;TLS offloading increases overhead to the network node.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Deployer will need to ensure new dependencies are installed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Developers will need to ensure they are using the additional utilities based
on the lb configuration.&lt;/p&gt;
&lt;p&gt;Developers will need to create a utility to retrieve Barbican secrets/data.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change has been in review since Juno.  Much discussion has taken place
over IRC and the mailing list.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Alternatively, if we would like to support different TLS offloading tools like
Stud we could support plugin or extensions that are loaded in front of HAProxy.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;phillip-toohill&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;dlundquist&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Update haproxy ‘haproxy.conf’ and jinja templates to handle new configurations.
Update namespace_driver methods for new actions.
Testing.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Depends on blueprints:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement&lt;/a&gt;
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-ssl-termination"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-ssl-termination&lt;/a&gt;
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-refactor-haproxy-namespace-driver-to-new-driver-interface"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-refactor-haproxy-namespace-driver-to-new-driver-interface&lt;/a&gt;
and its successors noted within.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add TLS to existing LBaaS tempest tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Test to verify SSL termination&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Document behavior and capabilities of the refactored reference implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Document behavior and capabilities of the refactored reference implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.haproxy.org/"&gt;http://www.haproxy.org/&lt;/a&gt;
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement&lt;/a&gt;
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-refactor-haproxy-namespace-driver-to-new-driver-interface"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-refactor-haproxy-namespace-driver-to-new-driver-interface&lt;/a&gt;
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-ssl-termination"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-ssl-termination&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 05 Dec 2014 00:00:00 </pubDate></item><item><title>LBaaS Refactor HAProxy namespace driver</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/lbaas-refactor-haproxy-namespace-driver-to-new-driver-interface.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-refactor-haproxy-namespace-driver-to-new-driver-interface"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-refactor-haproxy-namespace-driver-to-new-driver-interface&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With the new LBaaS object model and driver interface we no longer have a
working reference implementation.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Existing HAProxy namespace driver does not implement new LBaaS driver API or
support multiple listeners load balancer as supported by new LBaaS object
model.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Refactor LBaaS HAProxy namespace driver to use new object model driver
interface.&lt;/p&gt;
&lt;p&gt;Use Jinja2 to render HAProxy configuration template, rather than the custom
configuration generation.&lt;/p&gt;
&lt;p&gt;HAProxy configurations may include multiple listeners per load balancer in a
single HAProxy process.&lt;/p&gt;
&lt;p&gt;Separate files in $state_path/lbaas/$lb_uuid/ placing files written by HAProxy
under $state_path/lbaas/$lb_uuid/run to prepare for storing TLS private keys
under $state_path/lbaas/$lb_uuid/. Renaming configuration file, PID file and
statistics socket stored in $state_path/lbaas/$lb_uuid/ to avoid name conflicts
with Stunnel. Further TLS related changes are outside the scope of this spec.
The new directory structure will look like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;$state_path/lbaas/$lb_uuid/
$state_path/lbaas/$lb_uuid/haproxy.conf
$state_path/lbaas/$lb_uuid/run/
$state_path/lbaas/$lb_uuid/run/haproxy.pid
$state_path/lbaas/$lb_uuid/run/haproxy_stats.sock
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The driver will need to detect if the sock and/or PID files are not present in
the new locations, and upgrade the running load balancer namespace to this new
file system. This will result in a brief interruption of load balancer service
while HAProxy is shutdown and configuration updated.&lt;/p&gt;
&lt;p&gt;Further TLS and Layer 7 content filtering/manipulation are outside the scope of
this spec, but other specs may depend on this.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;Restricting write access to $state_path/lbaas/$lb_uuid/ to root, and placing
HAProxy modified files in $state_path/lbaas/$lb_uuid/run/.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Preformance should remain similar to existing HAProxy namespace driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;The deployer will need to stop the lbaas-agent before while restarting
neutron-server upgrade the database schema and RPC protocol.&lt;/p&gt;
&lt;p&gt;The deployer should also note the interruption in load balancer services and
each namespace’s file system is updated to the new configuration.&lt;/p&gt;
&lt;p&gt;Adding Jinja2 requirement for HAProxy namespace driver functionality, this is
already used within Neutron by the VPNaaS driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;This will significantly affect the HAProxy namespace driver in order to
accommodate the new driver interface and multiple listeners.&lt;/p&gt;
&lt;p&gt;Addition of Jinja2 requirement for LBaaS support may require DevStack updates.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change has been in review since Juno.  Much discussion has taken place
over IRC and the mailing list.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Implement a different LBaaS reference driver.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~dlundquist"&gt;https://launchpad.net/~dlundquist&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~phillip-toohill"&gt;https://launchpad.net/~phillip-toohill&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Develop Jinja2 template for HAProxy configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update HAProxy namespace driver.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;LBaaS API and object model improvements&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LBaaS object model driver changes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Implementation of this spec will allow end to end testing of new LBaaS object
model.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Existing LBaaS tests should be modified to test LBaaS v2&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;End-to-end LBaaS v2 tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Existing LBaaS ref driver documentation needs to be updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;specs/juno/lbaas-api-and-objmodel-improvement.rst&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;specs/juno/lbaas-objmodel-driver-changes.rst&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Fri, 05 Dec 2014 00:00:00 </pubDate></item><item><title>Example Spec - The title of your blueprint</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/a10-lbaas-v2-driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/a10-lbaas-v2-driver"&gt;https://blueprints.launchpad.net/neutron/+spec/a10-lbaas-v2-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron LBaaS v2 driver for A10 Networks appliances.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Enable A10 Networks appliances to be LBaaS backends.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The driver will implement the LBaaS v2 driver interface, as a shim to an
open-source pypi package, similar to the current v1 driver.&lt;/p&gt;
&lt;p&gt;This driver will include TLS and L7 functionality included in LBaaS v2.&lt;/p&gt;
&lt;p&gt;This driver will not support APP_COOKIE persistence.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;Driver communicates with infrastructure hardware via https.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;Will support ipv6 at the same level as neutron lbaas.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Pypi package ‘a10-neutron-lbaas’ must be installed prior to using this driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~dougwig"&gt;https://launchpad.net/~dougwig&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Driver shim (this spec is likely longer than the driver will be.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests for shim being shimmy&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;3rd-party CI&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;LBaaS v2&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Third-party CI will run existing LB tempest tests with A10 appliances.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Third-party CI will run existing LB functional tests with A10 appliances.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Third-party CI will run existing LB API tests with A10 appliances.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;LBaaS v2 - &lt;a class="reference external" href="https://review.openstack.org/#/c/138205/"&gt;https://review.openstack.org/#/c/138205/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 03 Dec 2014 00:00:00 </pubDate></item><item><title>FWaaS Insertion Model on Routers</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/fwaas-router-insertion.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/fwaas-router-insertion"&gt;https://blueprints.launchpad.net/neutron/+spec/fwaas-router-insertion&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The blueprint proposes  a change to the FWaaS insertion model to associate a
Firewall with a specified set of Routers (can be a single Router) as opposed
to the current model of association with all Routers in the tenant.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The FWaaS model defines 3 resources: Firewall rules, Firewall policies and
Firewalls. The Firewall rules has attributes to specify a filter rule. The
Firewall policy is a container for a collection of rules. The Firewall itself
is associated with a Firewall policy and thereby indirectly to a set of rules.
Currently no insertion point can be defined for a Firewall, and there is no
intent to abstract the insertion from the service itself to allow for various
types of insertion points(L3, Bump in the wire etc).&lt;/p&gt;
&lt;p&gt;The FWaaS reference implementation inserts the Firewall on all ‘qr-’ interfaces on
all routers in the tenant. The plan was to allow the insertion point to be driven by
the Service Insertion proposals[1][2]. Given that the Service Insertion proposals
have not yet been adopted for various reasons, the objective of this effort is to
restrict the scope to FWaaS and insertion on a specified set of Routers.&lt;/p&gt;
&lt;p&gt;In the current model and implementation we can only support a single Firewall on a
tenant as the Firewall is present on all Routers. This does not provide the ability
to selectively firewall traffic for a subnet or a set of subnets in the tenant topology.
This requires all Rules for a tenant topology to be collected together in the policy
associated with the Firewall. This is both inefficient and prone to errors.&lt;/p&gt;
&lt;p&gt;Routers are not tracked on the Firewall DB so it is not always straightforward to reflect
the Firewall state based on the state transtions on one of potentially many Routers
associated with the Firewall. We can handle the case when a new Router is added but it
is more involved to handle Router deletions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;It is being proposed to associate a Firewall with a set of Routers which is specified
in the API. Resource validation can be performed and appropriate action can be taken
by the Plugin. The insertion point as the Router(s) will be tracked in the Firewall DB.&lt;/p&gt;
&lt;p&gt;With some trepidation the additional attribute can be proposed as an extension
or this can be added as an attribute to the Firewall extension. With the rework
happening in this area, this effort will align with the community direction here.&lt;/p&gt;
&lt;p&gt;A minor variation with this same fundamental intent of the Firewall being associated
with a set of Routers is more favored based on discussions with members of the FWaaS
subteam and associated individuals with interactions with Customers and Deployers.
Rather than just associating a set of Routers and implicitly on all their interfaces,
an option to selectively apply to a specified set of the Router interfaces across the
Routers is also proposed as a phase 2 of the implementation. This can support backends
that might need the Firewall association with a list of ports. The default behavior
is to  apply on all interfaces of the Router(s).&lt;/p&gt;
&lt;p&gt;With this variation on the theme, the  list of interfaces in addition to the Router will
be accomodated as an attribute to the Firewall extension or proposed as an extension.&lt;/p&gt;
&lt;p&gt;With this change we can support multiple Firewalls within a tenant with better
discrimination based on the Router insertion point rather than have all rules for the
entire topology applied every where. The constraint of a port being a member of a single
Firewall will be enforced for consistent behavior. So with the default of applying on all
interfaces of a Router - the constraint will imply that a Router can only accomodate a
single Firewall. With the port list, to apply on a subset of Router interfaces, we can
support multiple Firewalls on a Router as well.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;The proposal is to associate the Firewall with the list of Routers provided in the
Create or Update workflows. Appropriate Foreign Key constraints will be applied.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Attribute name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;fwid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uuid&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Y&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;R&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Firewall id&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;router_ids&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Y&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;CRU&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Associated Routers&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The port-id list attribute will be added to the above model as Phase 2 of
the implementation.&lt;/p&gt;
&lt;p&gt;Database Migration:
The current implementation installs the Firewall on all Routers in the tenant. The
Routers are not tracked in the Firewall Database. On upgrade, as part of the migration
it is proposed that each Router in the tenant will be added as a Router associated with
the Firewall as in the new Data Model. Downgrade will not be supported.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;This would be the addition to the Firewall resource. As mentioned earlier, an approach
consistent with the extensions rework will be adopted. Support for Routers is added in
Phase 1.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s1"&gt;'firewalls'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s1"&gt;'router_ids'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And the list of ports as targeted for Phase 2.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s1"&gt;'firewalls'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s1"&gt;'router_ports'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                         &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_none_to_empty_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;The FWaaS Agent will not need to consume all router_add events as in the current model.
No changes to any messaging is planned.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;In the current model, FWaaS does not specify any insertion point. The API in the
proposed model will accomodate a set of Routers as an additional attribute . As
in the current model, the Firewall state will start in PENDING_CREATE (or CREATED in
DVR mode) and will go to ACTIVE with successful completion of messaging with the FWaaS
Agent and the iptables backend. The CLI representations below are some possible
suggestions.&lt;/p&gt;
&lt;p&gt;neutron firewall-create FW-POLICY –router &amp;lt;r1&amp;gt; –router &amp;lt;r2&amp;gt;&lt;/p&gt;
&lt;p&gt;neutron firewall-create FW-POLICY –routers “&amp;lt;r1&amp;gt; &amp;lt;r2&amp;gt; … &amp;lt;rm&amp;gt;”&lt;/p&gt;
&lt;p&gt;And this implicitly installs the Firewall on all internal interfaces of each
router specified.&lt;/p&gt;
&lt;p&gt;If this new attribute is not specified on firewall-create, the firewall logical
resource will be created and be in PENDING_CREATE (or CREATED in DVR mode) state. This
enables decoupling the Firewall Resource creation from Router creation. This can support
a scenario where Firewalls can be pre-provisioned and can later be bound to specific
Routers which can get created at a later point on a tenant network.&lt;/p&gt;
&lt;p&gt;This is similar to the current model when there are no routers present in the tenant.
With this proposal, the Firewall state will change to ACTIVE on a firewall-update with
the insertion point details. The CLI representation below is one possible suggestion.&lt;/p&gt;
&lt;p&gt;neutron firewall-update FIREWALL –router &amp;lt;r1&amp;gt; –router &amp;lt;r2&amp;gt;&lt;/p&gt;
&lt;p&gt;In Phase 2, with the additional attribute of port list, the Create would be something
of the form:&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;neutron firewall-create &lt;/dt&gt;&lt;dd&gt;&lt;p&gt;FW-POLICY –router &amp;lt;r1&amp;gt; –router &amp;lt;r2&amp;gt;  –port-id &amp;lt;p1&amp;gt; –port-id &amp;lt;p2&amp;gt; …&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;neutron firewall-create &lt;/dt&gt;&lt;dd&gt;&lt;p&gt;FW-POLICY –routers “&amp;lt;r1&amp;gt; &amp;lt;r2&amp;gt; … &amp;lt;rm&amp;gt;” –port-ids “&amp;lt;p1&amp;gt; &amp;lt;p2&amp;gt; … &amp;lt;pn&amp;gt;”&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The port list is again optional in the update workflow. If it is not provided, the
Firewall is applied to all the internal interfaces of the Routers. And when the list of
ports is provided, it is applied on those internal interfaces mapped to the
corresponding Routers. This is identical to the create workflow.&lt;/p&gt;
&lt;p&gt;The update workflow will also support updating the routers and/or the list of ports on a
ACTIVE Firewall. All updates are effected with proper validation of ports, routers and
port ownership with the Routers. This can be represented as below.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;neutron firewall-update FIREWALL &lt;/dt&gt;&lt;dd&gt;&lt;p&gt;–router &amp;lt;r1&amp;gt; –router &amp;lt;r2&amp;gt; –port-id &amp;lt;p1&amp;gt; –port-id &amp;lt;p2&amp;gt; …&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;No impacts.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;With support for migration, upgrades will be handled with a move to the new Data
model.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Any Plugins that rely on the Firewall being installed on all Routers in the tenant and
are based directly off the reference implementation will need to be changed. This model
has been brought up in the FWaaS IRC and by reaching out to the FWaaS developers. No
significant impact has been noted. This spec also serves to address any concerns.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change has been discussed in the past and attempts were made to address this
through the Service Insertion blueprints. The need to address this issue has been
discussed within the FWaaS subteam. And this has been brought up at the recent summit
by Mark and discussed with other cores. Some of the details on the approach has been
discussed amongst the FWaaS subteam at the summit and continued over at the FWaaS IRC.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Look again at one of the earlier Service Insertion proposals.[1][2]&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;The first phase will target applying on the specified routers. The addition of the
option to specify a list of ports will be phased after this.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;skandasw&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Phase 1
* Refactor Plugin for new routers attribute.
* DB changes to associate the routers for the firewall.
* Migration changes on upgrade.
* Agent interaction changes to the messaging dict to include the routers.
* Refactor FW Agent, to deal with specified routers and remove handling for new routers.&lt;/p&gt;
&lt;p&gt;Phase 2 (Low Priority)
* Refactoring for additional port list attribute as above.
* Validation logic on ports on Routers and multiple Firewalls on Router.
* Agent changes to messaging for interface attributes.
* Refactor iptables driver to support specific interface in filter rules.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;No direct dependency but with the services spinout, L3 Agent refactor this can cause
some pain. But it is seen that some of this can be complementary.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Existing tempest test will be modified to add additional attributes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Basic functionality is not being changed so the changes to functional tests
will just involve the addition of specifying new insertion point attributes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Changes to add the new attributes.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;User Documentation will be updated to include the new attributes and minor change to
the workflow wherein now the insertion points will need to be specified.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;API changes will be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1]https://blueprints.launchpad.net/neutron/+spec/neutron-services-insertion-chaining-steering
[2]https://blueprints.launchpad.net/neutron/+spec/service-base-class-and-insertion&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 03 Dec 2014 00:00:00 </pubDate></item><item><title>LBaaS API and Object Model improvement</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/lbaas-api-and-objmodel-improvement.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;LBaaS needs improved API and object model to provide base line for
new API parts that provide advanced use cases such as L7, TLS, HA, etc.&lt;/p&gt;
&lt;p&gt;This blueprint describes the changes that should be made to object model
so that further design and implementation of L7 switching, TLS and HA feature is
possible.  The new API that exposes the new entities will be done in an separate
extension.&lt;/p&gt;
&lt;p&gt;This blueprint is not describing design of L7, TLS API parts but may briefly
assume some aspects of possible design of those features. Nor does it describe
the changes to the API that will fit with this object model.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The “advanced” LB configuration which is supported by all LB vendors,
both hw and sw, may consist of multiple service endpoints on one ip address,
and multiple pools. Here, ‘service endpoint’ means IP address + port.&lt;/p&gt;
&lt;p&gt;The problem with existing API/object model is that it only accounts for
single VIP and single pool per loadbalancer.&lt;/p&gt;
&lt;p&gt;One of the biggest issue of the existing API and object model is that
Pool is playing ‘root object’ role and this solely prevents multiple pools
per single configuration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;There are a few things that needs to be done in order to make LBaaS API
suitable for addition of TLS, L7 and HA features.&lt;/p&gt;
&lt;p&gt;1. This will entirely be a new extension and service plugin.  LBaaS V1 code
should not be affected, but there may be exceptions.&lt;/p&gt;
&lt;p&gt;2. Currently Pool object is the root object(*), which is logically incorrect
and confusing. From API perspective that means that creating Pool object will
not be a starting point of the workflow.&lt;/p&gt;
&lt;ol class="arabic simple" start="3"&gt;
&lt;li&gt;&lt;p&gt;Member object will add subnet_id as an optional attribute.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;4. VIP object will not be used.  Its attributes will be added to the
LoadBalancer object and the Listener object.&lt;/p&gt;
&lt;p&gt;5. LoadBalancer object becomes the root object(*) of the LBaaS object model. It
will hold the attributes that pertain to the vip and will be the parent of one
or many listeners.&lt;/p&gt;
&lt;p&gt;6. Additional object Listener is introduced,
which is a placeholder for former VIP parameters such as protocol_port,
and protocol, see detailed description below&lt;/p&gt;
&lt;p&gt;LoadBalancer and Listener relate as 1:M. Listener will initially only be a
child of a LoadBalancer, so its life-cycle is limited to a LoadBalancer.
Deleting a LoadBalancer will not be alllowed when it has children Listeners.&lt;/p&gt;
&lt;p&gt;In the future, this relationship may become M:N if it is decided it is needed.
The M:N change will be an additive change so it will not break contract,
however, this blueprint will not attempt this.&lt;/p&gt;
&lt;p&gt;7. To prevent entities in the database being out of sync with the backend due
to concurrent requests, no operations will be allowed if an entity is in a
transient state (PENDING_CREATE, PENDING_UPDATE, PENDING_DELETE).&lt;/p&gt;
&lt;ol class="arabic simple" start="8"&gt;
&lt;li&gt;&lt;p&gt;Pool to Health Monitor relationship will change from M:N to 1:1 for now.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;9. Attributes of health monitor and member will stay nearly identical except
for references to parents.&lt;/p&gt;
&lt;p&gt;10. A new synchronous haproxy driver will be created to easily test out the
API and DB changes.  It will not be meant for production use.  Refactoring the
agent haproxy driver will be left to another blueprint.&lt;/p&gt;
&lt;p&gt;11. Since there are two types of statuses we should worry about, LoadBalancer
and Listener will have both provisioning_status and operating_status fields,
while Pool and Member will have an operating_status field.&lt;/p&gt;
&lt;p&gt;12. operating_status will be an enum of (‘ONLINE’, ‘OFFLINE’, ‘DEGRADED’,
‘ERROR’)&lt;/p&gt;
&lt;p&gt;13. provisioning_status will be an enum of (‘ACTIVE’, ‘PENDING_CREATE’,
‘PENDING_UPDATE’, ‘PENDING_DELETE’, ‘ERROR’)&lt;/p&gt;
&lt;p&gt;14. Every update of a LoadBalancer, including updates to and adding/removing
children entities, will put the LoadBalancer into a PENDING_UPDATE
provisioning_status.  No other updates to that LoadBalancer or its children
will be allowed until the operation has completed.&lt;/p&gt;
&lt;p&gt;(*) Root object is an object that represents ‘service instance’.
It could be deployed/undeployed, turned on/off, or capability requirements
may be applied to it. It also is a starting point of configuration workflow.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://docs.google.com/a/mirantis.com/document/d/1mTfkkdnPAd4tWOMZAdwHEx7IuFZDULjG9bTmWyXe-zo/edit"&gt;https://docs.google.com/a/mirantis.com/document/d/1mTfkkdnPAd4tWOMZAdwHEx7IuFZDULjG9bTmWyXe-zo/edit&lt;/a&gt;
The documents describes differently structured API that uses ‘single-call’ approach.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/neutron-lbaas-api-proposals"&gt;https://etherpad.openstack.org/p/neutron-lbaas-api-proposals&lt;/a&gt;
Brief description of how other APIs for other object models look like&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2014-November/051147.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2014-November/051147.html&lt;/a&gt;
Samuel Bercovici’s idea of solving the status issue of shared objects&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;LBaaS v1 tables will remain unchanged and the following tables will be added
for LBaaS v2 use:
* neutron.lbaas_loadbalancers
* neutron.lbaas_listeners
* neutron.lbaas_pools
* neutron.lbaas_members
* neutron.lbaas_healthmonitors
* neutron.lbaas_sessionpersistences
* neutron.lbaas_listener_statistics&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;lbaas_loadbalancers&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;id - unique identifier&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tenant_id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;description&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;vip_port_id - the neutron port tied to the vip (this can be used to get the
vip_subnet, and vip_address).  This will be stored in the database but not
exposed through the API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;vip_subnet_id - the subnet a neutron port should be created on&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;vip_address - the address of the subnet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;provisioning_status&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;operating_status&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;admin_state_up&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;listeners - a list of back-references child listener ids&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;provider - provider in which this load balancer should be provisioned&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;lbaas_listeners&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;id - identity&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tenant_id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;loadbalancer_id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;default_pool_id - ID of default pool. Must have compatible protocol with
listener.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;protocol - Protocol to load balancer: HTTP, HTTPS, TCP, UDP&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;protocol_port - port number to listen&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;admin_state_up - admin state (True or False)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;provisioning_status&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;operating_status&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Listener model will later be amended with L7 and TLS-related attributes which
are out of scope of this blueprint.&lt;/p&gt;
&lt;ol class="arabic simple" start="3"&gt;
&lt;li&gt;&lt;p&gt;lbaas_pools&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;id - identity&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tenant_id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;description&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;protocol - Protocol to load balance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;lb_method - load balancing method&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;healthmonitor_id - id of health monitor&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;admin_state_up - admin state (True/False). That attribute defines
administrative state of the pool on all of the backends where it is actually
deployed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;operating_status&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol class="arabic simple" start="4"&gt;
&lt;li&gt;&lt;p&gt;lbaas_members&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;id - identity&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tenant_id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;address - ip address&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pool_id - required parent pool&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;subnet_id - optional subnet this member is on&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;protocol_port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;weight&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;operating_status&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;admin_state_up&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol class="arabic simple" start="5"&gt;
&lt;li&gt;&lt;p&gt;lbaas_healthmonitors&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;id - id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tenant_id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;type - (TCP, HTTP)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delay&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;timeout&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;max_retries&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;http_method&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;url_path&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;expected_codes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;admin_state_up&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol class="arabic simple" start="6"&gt;
&lt;li&gt;&lt;p&gt;lbaas_sessionpersistences&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;pool_id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;type - (HTTP_COOKIE, SOURCE_IP, APP_COOKIE)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cookie_name&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol class="arabic simple" start="7"&gt;
&lt;li&gt;&lt;p&gt;lbaas_listener_statistics&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;listener_id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;bytes_in&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;bytes_out&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;active_connections&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;total_connections&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;A separate extension will be created exposing the following resources:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;/lbaas/loadbalancers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;/lbaas/listeners&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;/lbaas/pools&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;/lbaas/pools/{pool_id}/members&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;/lbaas/healthmonitors&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Resource Attributes:&lt;/p&gt;
&lt;p&gt;/lbaas/loadbalancers&lt;/p&gt;
&lt;table class="docutils align-default" id="id1"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;CSVTable&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;tenant_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all (No Update)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;tenant identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human-readable&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human-readable&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;vip_subnet_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all (No Update)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;creates vip on this subnet&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;vip_address&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (IP Address)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all (No Update)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;IPv4 or IPv6&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Frontend IP address&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;admin_state_up&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;enabled&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;provisioning_status&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;provisioning status&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;operating_status&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;operational status&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Deleting a load balancer will only succeed if it is not a parent of any
listeners.&lt;/p&gt;
&lt;p&gt;/lbaas/listeners&lt;/p&gt;
&lt;table class="docutils align-default" id="id2"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;CSVTable&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;tenant_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;tenant identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human-readable&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human-readable&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;loadbalancer_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all (No Update)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;parent load balancer&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;connection_limit&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;-1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;max connections to the protocol port&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;protocol&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all (No Update)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘TCP’,’HTTP’,’HTTPS’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;listening protocol&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;protocol_port&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0-65535&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;listening port&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;admin_state_up&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;enabled&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;provisioning_status&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;provisioning status&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;operating_status&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;operational status&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Note that loadbalancer_id is required for now.  This will not preclude later
implementations that may want to allow M:N loadbalancer to listeners as this
is only an API attribute and thus can be changed from required to optional.&lt;/p&gt;
&lt;p&gt;Note that default_pool_id is not specified here as the pool will define
its parent listener.&lt;/p&gt;
&lt;p&gt;Deleting a Listener will only succeed if it is not the parent of a pool.&lt;/p&gt;
&lt;p&gt;/lbaas/pools&lt;/p&gt;
&lt;table class="docutils align-default" id="id3"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;CSVTable&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;tenant_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;tenant identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human-readable&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;description&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Human-readable&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;listener_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all (No Update)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;parent listener&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;protocol&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all (No Update)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘TCP’,’HTTP’,’HTTPS’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;protocol to send to members&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;lb_algorithm&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘ROUND_ROBIN’,’LEAST_CONNECTIONS’,SOURCE_IP&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;load balancing algorithm&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;session_persistence&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dictionary&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;{}&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;type: ‘SOURCE_IP’,’HTTP_COOKIE’,’APP_COOKIE’, cookie_name: string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;session persistence definition&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;admin_state_up&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;enabled&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;operating_status&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;operational status&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;members&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;list of members belonging to this pool&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Note that listener_id is required for now.  There will be validation that
the listener has only one pool as a child.&lt;/p&gt;
&lt;p&gt;This should not preclude a later implementation of M:N listener to pools.&lt;/p&gt;
&lt;p&gt;Deleting a pool will not succeed if it is the parent of a health monitor.  It
will however succeed if it is the parent of any children, and those children
will be deleted as well.&lt;/p&gt;
&lt;p&gt;/lbaas/pools/{pool_id}/members&lt;/p&gt;
&lt;table class="docutils align-default" id="id4"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;CSVTable&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;tenant_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;tenant identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;address&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (IP)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all (No Update)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;IPv4 or IPv6&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;IP Address member is listening&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;protocol_port&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0-65535&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;port member is listening&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;weight&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;traffic distribution weight&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;subnet_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all (No Update)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;subnet to access member port&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;admin_state_up&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;True&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;enabled&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;operating_status&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;operational status&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;/lbaas/healthmonitors&lt;/p&gt;
&lt;table class="docutils align-default" id="id5"&gt;
&lt;caption&gt;&lt;span class="caption-text"&gt;CSVTable&lt;/span&gt;&lt;/caption&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;tenant_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;tenant identity&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all (No Update)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘HTTP’,’HTTPS’,’PING’,’TCP’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;type of health check&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;pool_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string (UUID)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all (No Update)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;id of pool to monitor&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;delay&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;seconds before health check&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;timeout&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;seconds for a failed check&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;max_retries&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;required&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;number of failed checks before member is considered OFFLINE&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;http_method&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW,all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘GET’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘GET’,’POST’,’PUT’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;http verb to send http checks&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;url_path&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘/’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;url to send http checks&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;expected_codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;‘200’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;comma delimited HTTP response codes&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;expected HTTP response codes for a successful check&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;admin_state_up&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;TRUE&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;enabled&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Note that pool_id is a required attribute.  Similar to listener_id on the pool
object, this does not preclude later implementations of 1:M pool to health
monitor relationship.&lt;/p&gt;
&lt;p&gt;(*) denotes a required attribute&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;Standard Neutron tenant object ownership rules will apply.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;p&gt;New notifications:
- loadbalancer
- listener
- pool
- healthmonitor
- member&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;Users may have access to a new lbaas resources.  The CLI commands will be
slightly different depending on which extension that is loaded.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;LBaaS V1 and LBaaS V2 can coexist in the codebase, but should not be run at
the same time.  This will have to be enforced in the code.&lt;/p&gt;
&lt;p&gt;No migration path from LBaaS V1 to V2 will be done for this blueprint, however
another blueprint should do this as it will be a complicated effort.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;A new extension, service plugin, and driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change has been in review since Juno.  Much discussion has taken place
over IRC and the mailing list.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignees:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;brandon-logan&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;object model change&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;new loadbalancer extension for new API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;unit tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/106089/"&gt;https://review.openstack.org/#/c/106089/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional Tests for the load balancer plugin.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;All new resources added by the extension will have positive and negative
tests.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Differences between LBaaS V1 and V2 should be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;There should be a new LBaaS V2 API document section documenting the new
resources added by the extension.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/juno-lbaas-design-session"&gt;https://etherpad.openstack.org/p/juno-lbaas-design-session&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 01 Dec 2014 00:00:00 </pubDate></item><item><title>Neutron OVS agent on Windows</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/hyper-v-ovs-agent.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/hyper-v-ovs-agent"&gt;https://blueprints.launchpad.net/neutron/+spec/hyper-v-ovs-agent&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Thanks to the porting of Open vSwitch to Hyper-V is is now also possible to
have the Neutron OVS L2 agent to work on both Linux and Windows. Most of the
porting activity consists in replacing Linux specific dependencies with
portable alternatives in the Neutron OVS agent, considering in particular that
the agent primarily execs OVS CLI commands, and that OVS has an identical
command line interface on both Linux and Windows.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Current implementation of OVS agent has a few GNU/Linux specific components:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The use of rootwrap. This is not necessary on Windows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;fcntl is used in agent.linux.utils which is imported by
agent.linux.ovs_lib. It is also used by eventlet to set non blocking I/O.
fcntl is not available on Windows, so any dependency on this will be
replaced with Windows compatible alternatives.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ovsdb_monitor.SimpleInterfaceMonitor currently only works on GNU/Linux.
The reason for this is that agent.linux.async_process.AsyncProcess() uses
platform specific components like the kill command. A Windows alternative
will be created to address this.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Considering that OVS agent currently uses a series of exec calls to ovs-vsctl
and ovs-ofctl ovs_lib and parts (if not all) of utils will be almost identical
on both Linux and Windows. This implies that they will have to be moved from
neutron.agent.linux to a common location, e.g.: neutron.agent.common.
A base class will be created and platform specific differences will be
abstracted (for example, the need for rootwrap).&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;This change will require the user to install Open vSwitch on Hyper-V before
deploying neutron ovs agent, and make the binaries
available in the PATH.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The Neutron Hyper-V agent offers already support for the ML2 plugin, which in
turn allows interoperability with
othe mechanism drivers, inclusing Open vSwitch.
The main limitation of this option is that since Hyper-V does not support
VXLAN or GRE encapsulation natively, networking is limited to the VLAN and
flat options.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;gabriel-samfira&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Move neutron.agent.linux.ovs_lib and parts of neutron.agent.linux.utils to
neutron.agent.common&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a base class for interactig with Open vSwitch, and abstract away the
differences that are platform specific.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;remove the need for roowrap. Only enable it on GNU/Linux&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update/add unit tests accordingly&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;This change does not directly depend on any other blueprint. It is however
related to:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/hyper-v-ovs-vif"&gt;https://blueprints.launchpad.net/nova/+spec/hyper-v-ovs-vif&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;This feature will be tested by the Hyper-V CI.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Current tempest tests are sufficient.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional tests will be added as needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Documentation should reflect that OVS agent now works on Hyper-V as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/hyper-v-ovs-vif"&gt;https://blueprints.launchpad.net/nova/+spec/hyper-v-ovs-vif&lt;/a&gt;
[2] &lt;a class="reference external" href="https://github.com/openvswitch/ovs"&gt;https://github.com/openvswitch/ovs&lt;/a&gt;
[3] &lt;a class="reference external" href="http://www.cloudbase.it/open-vswitch-on-hyper-v"&gt;http://www.cloudbase.it/open-vswitch-on-hyper-v&lt;/a&gt;
[4] &lt;a class="reference external" href="https://github.com/gabriel-samfira/neutron/tree/windows-ovs-agent-poc"&gt;https://github.com/gabriel-samfira/neutron/tree/windows-ovs-agent-poc&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 25 Nov 2014 00:00:00 </pubDate></item><item><title>Brocade Neutron FWaaS driver for Vyatta vRouter</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/brocade-vyatta-fwaas-plugin.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/brocade-vyatta-fwaas-plugin"&gt;https://blueprints.launchpad.net/neutron/+spec/brocade-vyatta-fwaas-plugin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Introduce the Brocade Vyatta Firewall device driver to provide FWaaS solution
using Vyatta vRouter VM running as a Neutron router. The driver implements
‘Perimeter Firewall’ functionality to filter traffic between tenant private
networks and external networks.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Brocade Vyatta vRouter is a multi-service product that provides various L3
and L4 services like Routing, NAT, Firewall, VPN, etc. While basic neutron
router L3 functions are available using Brocade Vyatta L3 plugin [1]
vRouter’s Firewall functionality is currently not configurable through
existing Neutron FWaaS APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This blueprint proposes a new vendor device-driver for Neutron FWaaS agent.
There is no change proposed in the FWaaS service plugin side as existing
reference FWaaS plugin is sufficient.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                    &lt;span class="o"&gt;+----------------------+&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;Vyatta&lt;/span&gt; &lt;span class="n"&gt;L3&lt;/span&gt; &lt;span class="n"&gt;NAT&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;Agent&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+------------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;FWaaS&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;    &lt;span class="n"&gt;RPC&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;FWaaS&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+------------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;    &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="n"&gt;plugin&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;Vyatta&lt;/span&gt; &lt;span class="n"&gt;FWaaS&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;Device&lt;/span&gt; &lt;span class="n"&gt;Driver&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;---------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                    &lt;span class="o"&gt;+-+--------+---------+-+&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                               &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                               &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                               &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;REST&lt;/span&gt; &lt;span class="n"&gt;API&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                               &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                      &lt;span class="o"&gt;+--------&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;---------+&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Vyatta&lt;/span&gt; &lt;span class="n"&gt;vRouter&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;                      &lt;span class="o"&gt;+------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Vyatta L3 NAT agent uses Neutron L3 NAT agent to associate the firewall to
the router interfaces.&lt;/p&gt;
&lt;p&gt;Vyatta FWaaS device driver will invoke the Vyatta vRouter REST APIs for the
below CRUD APIs as and when determined by the FWaaS agent&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;create_firewall&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update_firewall&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete_firewall&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All these functions are similar to the existing reference FWaaS device-driver
implementation.
Due to limitations of the existing neutron firewall plugin, firewall rules
will get applied to all the tenant routers. Also this effort will be aligned
with the community direction of the firewall insertion mode on a single
router spec[3].&lt;/p&gt;
&lt;p&gt;Note, we are aware of the current L3 agent refactoring proposed for Kilo [4].
Given the device driver interface is planned to be kept as-is the changes
proposed in this blueprint will integrate with minimal impact vis-a-vis the
refactoring.&lt;/p&gt;
&lt;p&gt;This effort is part of a wider set of blueprints to offer Neutron L3 and L4
services using Vyatta vRouter VM:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[1] introduces neutron router functionality using Vyatta vRouter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[2] introduces VPN service using the Vyatta vRouter.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;The device driver will use a common RESTapi client library that uses
basic-auth authentication to connect to Vyatta vRouter.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;When a tenant creates a Firewall using Neutron API it will be created on the
carrier-grade Vyatta vRouter.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Operators should first configure Brocade Vyatta L3 plugin as described in [1].
Neutron firewall plugin, Vyatta L3 agent and the firewall driver should be
configured. Once configured, Vyatta FWaaS driver will be invoked for the
Firewall CRUD operations on the tenant Router.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;Validating Neutron FWaaS APIs with multiple vendor, including this one from
Brocade, will help to move out of current experimental state for these APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;vishwanathj&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;natarajk.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add new Vyatta firewall device driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add unit tests required to test the device driver.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Brocade Vyatta L3 Plugin [1]&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;3rd party testing will be provided (Brocade Vyatta CI).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Brocade Vyatta CI will report on all changes affecting this plugin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing is done using devstack and Vyatta vRouter.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Scenario tests will be added to validate the Vyatta FWaaS implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;No new API tests are planned as no APIs are changed as part of this blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Brocade specific documentation will be updated on the availability of this
functionality in Neutron and the fwaas_device_driver configuration required
to enable it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[1] &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/l3-plugin-brocade-vyatta-vrouter"&gt;https://blueprints.launchpad.net/neutron/+spec/l3-plugin-brocade-vyatta-vrouter&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[2] &lt;a class="reference external" href="https://docs.google.com/document/d/1PJaKvsX2MzMRlLGfR0fBkrMraHYF0flvl0sqyZ704tA/"&gt;https://docs.google.com/document/d/1PJaKvsX2MzMRlLGfR0fBkrMraHYF0flvl0sqyZ704tA/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[3] &lt;a class="reference external" href="https://review.openstack.org/#/c/138672/"&gt;https://review.openstack.org/#/c/138672/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[4] &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/restructure-l3-agent"&gt;https://blueprints.launchpad.net/neutron/+spec/restructure-l3-agent&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 24 Nov 2014 00:00:00 </pubDate></item><item><title>Cisco VPNaaS with in-band Cisco CSR router</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/cisco-vpnaas-and-router-integration.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/cisco-vpnaas-and-router-integration"&gt;https://blueprints.launchpad.net/neutron/+spec/cisco-vpnaas-and-router-integration&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Enhance the Cisco IPSec site-to-site VPNaaS solution, by integrating it with
a Cisco Cloud Services Router (CSR) running as a Neutron router. This allows
easy configuration of a site-to-site connection using a dynamically created
router making it practical for production use.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;In the current Proof of Concept Cisco VPNaaS, a Cisco CSR VM runs
out-of-band from OpenStack, and in parallel with a reference Neutron router.
The Cisco CSR is started manually, and independently of OpenStack. The router
is statically provisioned and information on the Cisco CSR is stored in an
.ini file for use by the Cisco VPNaaS driver.&lt;/p&gt;
&lt;p&gt;When a VPN IPSec site-to-site connection is established, the VPNaaS drivers
use the .ini information [1] to communicate with the Cisco CSR and configure
the VPN IPSec site-to-site connection. A packet redirect is configured on the
Neutron router, to send all packets for the remote end, to the Cisco CSR.&lt;/p&gt;
&lt;p&gt;The issues with this are:
* Cisco CSR is manually started and provisioned for use.
* The .INI file must be manually updated (error prone).
* We are effectively using two routers to provide VPNaaS capability.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;With a previous blueprint [1], the Cisco VPNaaS driver was modified to
obtain router information from an .INI file at the time of &lt;strong&gt;use&lt;/strong&gt;, rather
than at startup, allowing a manual way to dynamically configure VPNaaS.&lt;/p&gt;
&lt;p&gt;This blueprint is a follow up refactoring of the driver, eliminating the need
for the .INI file, and fully automating the dynamic creation of site-to-site
connections. This makes the solution practical for operators to use in
production.&lt;/p&gt;
&lt;p&gt;To do this, it makes use of the newly added L3 router plugin, which handles
the creation and initial provisioning of the Cisco CSR router, and contains
all the needed router information.&lt;/p&gt;
&lt;p&gt;The VPN service driver directly calls the L3 router plugin to obtain the
management IP, username, password, inner and outer interface names, and VRF
for the router.&lt;/p&gt;
&lt;p&gt;This has the following advantages:
* CSR is automatically created by the L3 router plugin (vs manual startup)[2].
* No longer need two routers for IPSec connection.
* No longer need .INI for router information (obtain from router plugin).
* Can dynamically create IPSec site-to-site connections.&lt;/p&gt;
&lt;p&gt;The user would simply create a CSR router, and then select that as the router
for VPNaaS configurations.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;Eliminates the need for operator to manually start and provision the Cisco CSR
and create the .ini file.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Wall clock time to create a VPN connection improves, as the Neutron commands
will take all needed actions (no manual INI file changes needed).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;This is expected to work in an IPv6 environment.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;No longer need to manually create a Cisco CSR out-of-band for use with VPNaaS.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This completes incorporation of a Cisco based VPNaaS solution for Neutron
that is in line with the reference implementation, instead of a bolt-on
solution used by the current proof-of-concept implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;There is no alternative that will give an automated, dynamic, and scalable
solution. The current mechanism, provides a proof of concept solution, but
fails to meet the needs of this spec, due to the manual interaction required.&lt;/p&gt;
&lt;p&gt;A follow on blueprint will work towards integrating the VPN drivers with the
L3 Config Agent to reduce resource requirements. This blueprint is a step
towards that “evolution”.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;pmichali&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Removal of device driver code that reads the .ini file with Cisco CSR info.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modification of service driver to obtain Cisco CSR info and pass to device
driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create methods in L3 router plugin to provide the router info needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modification of the device driver to use the passed information, instead of
.ini file info.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update unit tests to reflect changes made.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None. All required components are already up-streamed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will be updated accordingly.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;No changes needed as is refactoring of existing implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;No changes needed as is refactoring of existing implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Not applicable.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;There are no changes to the Openstack documentation for this blueprint.
The vendor deployment/install documentation will be updated (mostly to
remove many steps).&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Not applicable.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[1] &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/cisco-vpnaas-with-cisco-csr-router"&gt;https://blueprints.launchpad.net/neutron/+spec/cisco-vpnaas-with-cisco-csr-router&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[2] &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/cisco-routing-service-vm"&gt;https://blueprints.launchpad.net/neutron/+spec/cisco-routing-service-vm&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[3] Out-of-band VPN setup: &lt;a class="reference external" href="http://docwiki.cisco.com/wiki/Install_and_Setup_of_Cisco_Cloud_Services_Router_(CSR)_for_OpenStack_VPN"&gt;http://docwiki.cisco.com/wiki/Install_and_Setup_of_Cisco_Cloud_Services_Router_(CSR)_for_OpenStack_VPN&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 24 Nov 2014 00:00:00 </pubDate></item><item><title>Dropping rpc API compat layer</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/drop-rpc-compat.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/drop-rpc-compat"&gt;https://blueprints.launchpad.net/neutron/+spec/drop-rpc-compat&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This proposal is to make more direct use of oslo.messaging APIs throughout
Neutron instead of a compatibility layer based on an old API.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Neutron has migrated from the rpc code in oslo-incubator to the oslo.messaging
library.  The oslo.messaging library has a different (but better) API.  To ease
the transition to oslo.messaging, Neutron has used some compatibility code to
convert the older style API usage to oslo.messaging APIs.  This proposal is to
make more direct use of oslo.messaging APIs throughout Neutron.&lt;/p&gt;
&lt;p&gt;Moving toward more direct usage of oslo.messaging APIs will improve consistency
with other projects, since all projects should be converging on the newer style
APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The following classes are items considered as a part of the compatibility layer.
The direct use of each of these things will be removed and replaced with direct
use of equivalent and underlying oslo.messaging APIs.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;neutron.common.rpc.&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;RpcProxy
RpcCallback
RPCException
RemoteError
MessagingTimeout&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;This looks like a small list, but it’s more invasive than it looks.  It will be
broken up into several iterative patches that are more easily reviewed and
merged over time.&lt;/p&gt;
&lt;p&gt;Here are some examples of the most invasive conversions (RpcProxy and
RpcCallback):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;oslo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;messaging&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;neutron.common&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;rpc&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;n_rpc&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Old style client interface using RpcProxy:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ClientAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n_rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RpcProxy&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;BASE_RPC_API_VERSION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1.0'&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DhcpPluginApi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default_version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BASE_RPC_API_VERSION&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;remote_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;make_msg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'remote_method'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                       &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;remote_method_2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;make_msg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'remote_method_2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                       &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                         &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1.1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;New style client interface:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ClientAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;messaging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1.0'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n_rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;remote_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;cctxt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cctxt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'remote_method'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;remote_method_2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;cctxt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1.1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cctxt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'remote_method_2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Old style server interface:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ServerAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n_rpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RpcCallback&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;RPC_API_VERSION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1.1'&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;remote_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'foo'&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;remote_method_2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'bar'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;New style server interface:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ServerAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;messaging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1.1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;remote_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'foo'&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;remote_method_2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'bar'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Negligible.   In theory, this is removing a compatibility layer so there should
be less code, but the overall performance impact of removing the layer is
negligible in the broader scope of things.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;There are several impacts to developers.  Developers used to the older rpc API
(and the equivalent compatibility layers) will have to learn what’s different.
Arguably, it’s conceptually quite similar so this shouldn’t have a large impact.
The oslo.messaging library itself has documentation.  Looking at all of the
existing code once it has been converted will help quite a bit as well, since
you can just follow the existing pattern.&lt;/p&gt;
&lt;p&gt;The other impact is patch conflicts.  Since this work involves some minor
refactoring across the tree, it may conflict with other code in progress.  This
will only occur in the case of features that modify rpc APIs.  The changes will
be done in a series of smaller changes, which will help with rebasing and fixing
conflicts against smaller sets of updates at a time.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The alternative is to leave the compatibility layer in place.  The downsides of
this are that Neutron’s use of oslo.messaging will diverge further and further
from what the rest of OpenStack messaging usage looks like.  It may also make it
more difficult to take advantage of new features in oslo.messaging in the
future.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;russellb&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The usage of each class listed in the proposed change section will be removed
one at a time.  The removal of each will be broken up into several changes, one
per interface (rpc API).&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;None&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The unit tests will be updated as required.  New ones will be added in key
places where unit test coverage may be missing.&lt;/p&gt;
&lt;p&gt;There are no functional changes here, so all of the existing unit and functional
tests will be relied upon to help ensure that no regressions are introduced.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Existing oslo.messaging documentation:
&lt;a class="reference external" href="http://docs.openstack.org/developer/oslo.messaging/"&gt;http://docs.openstack.org/developer/oslo.messaging/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 24 Nov 2014 00:00:00 </pubDate></item><item><title>ML2 Mechanism Driver for Cisco Nexus1000V switch</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/ml2-n1kv-mechanism-driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ml2-n1kv-mechanism-driver"&gt;https://blueprints.launchpad.net/neutron/+spec/ml2-n1kv-mechanism-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The purpose of this blueprint is to add support for Cisco Nexus1000V switch
in OpenStack neutron as a ML2 mechanism driver.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Cisco Nexus 1000V for KVM is a distributed virtual switch that works with
the Linux Kernel-based virtual machine (KVM) open source hypervisor.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Virtual Supervisor Module (VSM): Controller of the Cisco Nexus1000V
distributed virtual switch based on Cisco NX-OS software.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Virtual Ethernet Module (VEM): Data plane software installed on the Compute
nodes. All VEMs are controlled by VSM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Network Profiles: Container for one or more networks. VLAN and VXLAN
type of network profiles will be supported in the initial version.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Policy Profiles: Policy profiles are the primary mechanism by which network
policy is defined and applied to VM ports in a Nexus 1000V system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VM Network: VM Network refers to a combination of network-segment and
policy-profile. It maintains a count of ports that use the above
combination.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This blueprint proposes the first step in migration of the Cisco Nexus1000V
monolithic plugin to a mechanism driver for ML2 plugin. This mechansim driver
will interact with the VSM via REST APIs to dynamically configure and manage
networking for instances created via OpenStack.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The diagram below provides a high level overview of the interactions between
Cisco Nexus1000V switch and OpenStack components.&lt;/p&gt;
&lt;p&gt;Flows:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;        &lt;span class="o"&gt;+--------------------------+&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Neutron&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;ML2&lt;/span&gt; &lt;span class="n"&gt;Plugin&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;+------------+&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;N1KV&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Mechanism&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;+--------------------+&lt;/span&gt;
&lt;span class="o"&gt;+-------|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Driver&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;+-+--+---------+&lt;/span&gt;    &lt;span class="n"&gt;REST&lt;/span&gt; &lt;span class="n"&gt;API&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;Cisco&lt;/span&gt; &lt;span class="n"&gt;N1KV&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+---+&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;N1KV&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;  &lt;span class="o"&gt;+-----------------+&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+-----------+--------------+&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;Virtual&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                                                &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;Supervisor&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                                                &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;Module&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+--------------------------+&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;N1KV&lt;/span&gt; &lt;span class="n"&gt;VEM&lt;/span&gt;          &lt;span class="o"&gt;+-----------------+&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+--------------------------+&lt;/span&gt;                 &lt;span class="o"&gt;+-+------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+---+&lt;/span&gt;       &lt;span class="n"&gt;Compute&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+--------------------------+&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                                      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                                      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+--------------------------+&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;N1KV&lt;/span&gt; &lt;span class="n"&gt;VEM&lt;/span&gt;          &lt;span class="o"&gt;+-------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+--------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-------+&lt;/span&gt;       &lt;span class="n"&gt;Compute&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;+--------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The Cisco Nexus1000V mechanism driver will handle all the postcommit events
for network, subnets and ports. This data will be used to configure the VSM.
The VSM and VEM will be responsible for port bring up on the compute nodes.&lt;/p&gt;
&lt;p&gt;The mechanism driver will initialize a default network profile and a policy
profile on the VSM. All networks will have a binding to this default
network profile. All ports will have a binding to this default policy profile.
Dynamic binding of network and policy profiles will be implemented in the
future once extensions are supported for mechanism drivers.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;This mechanism driver introduces four new tables which are specific to the
N1KV mechanism driver.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;NetworkProfile: Stores network profile name and type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;N1kvNetworkBinding: Stores the binding between network profile and
network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PolicyProfile: Stores policy profile name and UUID.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;N1kvPortBinding: Stores the binding between policy profile and
port.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;A database migration is included to create the tables for these models.&lt;/p&gt;
&lt;p&gt;A script to migrate data for users of monolithic plugin will be provided in
the next iteration of this driver when we add support for extensions.&lt;/p&gt;
&lt;p&gt;No existing models are changed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The performance of Cisco N1KV ML2 mechanism driver will depend on the
responsiveness of the VSM.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;The deployer must provide the following in order to be able to connect to a
VSM.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;IP address of VSM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Admin credentials (username and password) to log into VSM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add “cisco_n1kv” as a ML2 driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the “vlan” type driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the “vxlan” type driver.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These should be provided in:
/opt/stack/neutron/etc/neutron/plugins/ml2/ml2_conf_cisco.ini&lt;/p&gt;
&lt;p&gt;Example:
[ml2_cisco_n1kv]&lt;/p&gt;
&lt;p&gt;# N1KV Format.
# [N1KV:&amp;lt;IP address of VSM&amp;gt;]
# username=&amp;lt;credential username&amp;gt;
# password=&amp;lt;credential password&amp;gt;&lt;/p&gt;
&lt;p&gt;The Nexus1000V monolithic plugin will be deprecated once the Nexus1000V ML2
mechanism driver achieves feature parity with the monolithic plugin.
Feature parity denotes full support for existing Nexus1000V specific resource
and attribute extensions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change adds a new mechanism driver for ML2 plugin aligning with the
community direction.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Alternative is to use the existing monolithic Nexus1000V plugin.
We add this blueprint in order to interoperate with other mechanism drivers
and align with community direction.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;abhraut&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;sthillma&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Work Items can be roughly divided into the following tasks:
* Mechanism driver to handle network/subnet/port CRUD requests.
* N1KV Client to perform HTTP requests to the VSM.
* Unit test cases to test the mechanism driver and client code.
* Tempest test cases to peform functional testing.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Following third party library used:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;requests: Requests is a python library for making HTTP requests which is
well documented at &lt;a class="reference external" href="http://docs.python-requests.org/en/latest/"&gt;http://docs.python-requests.org/en/latest/&lt;/a&gt;
Link to code -&amp;gt; &lt;a class="reference external" href="https://github.com/kennethreitz/requests"&gt;https://github.com/kennethreitz/requests&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Third party testing will be provided. The Cisco CI will report on all changes
affecting this mechanism driver. The testing will run on a setup with an
OpenStack deployment connected to a VSM and VEM.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;New functional tests will be added by mocking the VSM responses.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Configuration details for this mechanism driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.cisco.com/go/nexus1000v"&gt;http://www.cisco.com/go/nexus1000v&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 24 Nov 2014 00:00:00 </pubDate></item><item><title>VLAN trunking networks for NFV</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/nfv-vlan-trunks.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/nfv-vlan-trunks"&gt;https://blueprints.launchpad.net/neutron/+spec/nfv-vlan-trunks&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Many commonly used Neutron plugin configurations create networks that do
not permit VLAN tagged traffic to transit the network.  This includes ML2
when using the OVS driver or the VLAN driver.  Some plugins, conversely,
are totally fine at passing all forms of ethernet frame.  It’s impossible
to tell (via the API) which is in use as a tenant and it’s also impossible
to indicate to a plugin what kind of network is required.&lt;/p&gt;
&lt;p&gt;VLANs are required for many NFV functions.  This spec proposes making it
possible to request a VLAN transparent network - that is, one where VLAN
tagged traffic will be forwarded to other hosts - when one is requested,
and know that a network is in fact a trunk network.&lt;/p&gt;
&lt;p&gt;It is a common requirement of NFV VMs that they talk over many
separate L2 channels.  The number of channels is far in excess of the
number of ports that the VM has and can change over time.  VLAN tags
are often used for separating these channels, so that the number of
ports can be static while still allowing flexibility in the number of
channels.&lt;/p&gt;
&lt;p&gt;In Neutron, different network plugins create networks with different
properties, and there is no specific definition of the meaning of the
word ‘network’.  Mostly, but not always, networks are L2 broadcast
domains with learning-switch behaviour, although as long as antispoof
filters are in place the network can be implemented either as an L2 or
an L3 domain.  Generally, as long as networks meet a minimum
requirement that IPv4 and IPv6 unicast traffic, ARPs and NDs, work as
expected, no-one will criticise a plugin.  VLAN transparency is not
a part of this current minimum requirement, and some plugins do not,
by oversight or design, allow VLAN packets to flow.  It is not possible
to control this behaviour or detect it via the API, and this proposal aims
to change that.&lt;/p&gt;
&lt;p&gt;(Other blueprints propose solutions to decomposing trunks into
networks from its individual VLANs, address management on trunk
networks, and so on.  This makes no attempt to address anything other
than the simple L2 properties of networks.  This spec addresses different
use cases to those that deal with management of ports by Openstack -
specifically, the case where two VLAN-aware VMs wish to talk to each
other over a number of VLANs, possibly with tags that change over time,
and without informing Openstack at each stage of which VLANs and
addresses are in use.)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This proposal suggests that a request-discover mechanism be put into
place, so that:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;existing plugins that will pass VLAN tagged traffic can identify
themselves as such&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;existing plugins that cannot pass VLAN tagged traffic can also
identify themselves as such&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;legacy plugins that have not been adapted to report their behaviour
are identifiable&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;future plugins can have selective behaviour, where a network may or
may not pass VLAN traffic depending on user request - which permits
the plugin to make decisions in favour of efficiency where the
functionality is not required (such as using an L3 domain).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additionally, port firewall behaviour - currently undefined for VLAN
tagged packets - will be defined as applying consistently to the outermost
encap of the packet.  That is, antispoof and security groups detailing
matching IP ports will apply to packets with an IP ethertype, but will
&lt;em&gt;not&lt;/em&gt; apply to packets with a VLAN ethertype containing an IP ethertype.
This is because it is highly unlikely that a VLAN will have the same
address and be serving the same services as the VM’s untagged interface
on the same vNIC, and so using the same filtering is almost certain to
render the VLAN tagging useless for practical purposes.&lt;/p&gt;
&lt;section id="request"&gt;
&lt;h3&gt;Request&lt;/h3&gt;
&lt;p&gt;During net-create, the user may at their option request that a VLAN
transparent trunk network is created by passing a ‘vlan-transparent’
boolean property on the net-create request, request, set to ‘true’.
(Setting the property to ‘false’ is equivalent to not specifying the
property in the description below.)&lt;/p&gt;
&lt;p&gt;Plugins that have not been adapted to understand the property will ignore
this flag and create the network regardless.&lt;/p&gt;
&lt;p&gt;Plugins that are aware of the meaning of this property but do not
understand the flag, or cannot deliver VLAN transparent trunk networks,
will refuse to create a network and return an appropriate error to
the user.&lt;/p&gt;
&lt;p&gt;Plugins that are aware of this flag and capable of delivering a VLAN
transparent network will do so.&lt;/p&gt;
&lt;p&gt;Plugins may change behaviour based on this flag:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;they may create a VLAN transparent network (at potentially higher
resource cost) if the flag is set, and save on resources
when it is not set&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;they may refuse to attach certain port types to the network
(e.g. some external attachment ports may not themselves be VLAN
transparent and therefore should not be attached to transparent
networks)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Plugins may also only implement one sort of network, either transparent
or not, and decline to create a network when a network is requested
that cannot be implemented by the controller.&lt;/p&gt;
&lt;p&gt;In the case that the flag is absent an aware plugin is under no
obligation to deliver a VLAN transparent network (and an unaware
plugin will, naturally, ignore its absence); the returned network may
or may not be VLAN transparent.&lt;/p&gt;
&lt;p&gt;Note that the flag cannot be changed by a net-update.  VLAN transparency
must be declared at creation and cannot be changed after this point,
as this would potentially affect the placing of the network and even the
choice of endpoints that VMs plug to.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="response"&gt;
&lt;h3&gt;Response&lt;/h3&gt;
&lt;p&gt;After network creation, a network may have a property
‘vlan-transparent’.&lt;/p&gt;
&lt;p&gt;In the case that this property does not exist, the plugin
is a legacy plugin and no determination is possible about whether the
network is capable of passing VLAN tagged packets.&lt;/p&gt;
&lt;p&gt;In the case that the property exists and the flag is set to true, then
the plugin is a VLAN aware plugin and (regardless of the request)
has created a network capable of passing VLAN tagged packets.&lt;/p&gt;
&lt;p&gt;In the case that the property exists and the flag is set to false,
then the plugin is a VLAN aware plugin, the request did not pass the
‘vlan-transparent’ flag, and for its own reasons the plugin
elected to create a network without VLAN transparency (typically
because it’s being efficient or it’s simply not capable of doing so).&lt;/p&gt;
&lt;p&gt;Per the description in ‘request’ above, it is possible that the correct
response is an error indicating inability to act upon the request.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="firewalling"&gt;
&lt;h3&gt;Firewalling&lt;/h3&gt;
&lt;p&gt;VLAN tagging will be treated as an opaque encapsulation.&lt;/p&gt;
&lt;p&gt;VLAN tagged packets will &lt;em&gt;not&lt;/em&gt; be firewalled by security groups or other
port based security such as antispoofing, as the packet is not an IP
packet.  (For those drivers capable of passing VLAN tagged packets, this
is - at least sometimes - a change of behaviour.)  This is a deliberate
choice: security groups generally filter packets they understand and pass
packets they don’t, so it’s consistent (IP-in-MPLS would behave like this)
and it’s very likely IP-in-VLAN packets will have different addresses to
any untagged addresses on the same interface, and to each other, and so
Openstack port security will not serve any useful purpose.&lt;/p&gt;
&lt;p&gt;This requires validation within the IPTables firewall driver to ensure that
this is the behaviour seen at the moment.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;There exists a complementary port-based VLAN spec that permits supplying a
set of networks to a nominated port as a VLAN trunk.  It addresses other
use cases and is not a direct alternative.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;‘vlan-transparent’ property added to networks, a tri-state boolean.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;On networks:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;vlan-transparent&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;tristate&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;write on create, all
readonly after, all&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;absent&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;boolean
or absent&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;In current implementations that do pass VLANs, tagged packets’
contents are firewalled.  This is not explicitly documented, but is
one behaviour a user might reasonably expect.&lt;/p&gt;
&lt;p&gt;This change proposes treating a VLAN tag as an opaque encapsulation,
and thus VLAN tagged packets would &lt;em&gt;not&lt;/em&gt; be firewalled by their
content.  Also, security groups only offer IP-based firewalling, so
it would not be possible to block VLAN tagged packets.  That said,
guest OSes can be expected to ignore tagged packets when not
configured for receipt of VLANs, so there should be no impact.&lt;/p&gt;
&lt;p&gt;This is in keeping with the behaviour for other non-IP packet types.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;The python-neutronclient should be adjusted to take account of the new
option for net-create and the new property in net-show.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;May make some plugins more efficient at using network resources.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;ijw-ubuntu&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement new net-create parameter&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement new network property, including database migration script&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change a sampling of plugins, including the ML2 plugin, to implement
use of the properties&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement a new attr on ML2 drivers indicating whether a driver, when in
use and potentially responsible for a segment of a network, is capable of
passing VLAN packets on that network.  The driver may implement settings of
true or false, or the property may be absent in legacy drivers.  In the case
that any driver does not have the attribute or has the attribute set to
false, ML2 will decline to create VLAN transparent networks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Of the core drivers, the VLAN and OVS drivers will be marked as not
supporting VLAN transparent networks and the LB, VXLAN and GRE drivers
will be marked as supporting VLAN transparent networks.  Other drivers
will have legacy behaviour.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other plugins will have legacy behaviour until updated and no change is
required of them.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is &lt;em&gt;not&lt;/em&gt; changing any driver implementation, merely reporting the
known behaviour of existing drivers.  Thus agents are unaffected.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Tempest should confirm that (for a known good networking setup) VLAN
transparent networks can be requested from ML2 and that they work.
Such testing should ideally be host to host, to test both the soft switch
and the hardware configuration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;API tests should confirm that the property behaves as described
on net-create, net-update and net-show.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional tests should confirm that ML2 approves and denies creations correctly.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Requires documentation of the new flag.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Requires documentation of plugin and MechanismDriver behaviour and
the requirements for supporting VLAN transparent networks for plugins.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/juno-nfv-bof"&gt;https://etherpad.openstack.org/p/juno-nfv-bof&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/92541/"&gt;https://review.openstack.org/#/c/92541/&lt;/a&gt; (composite port support, which
is independent of the status of an individual network)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
</description><pubDate>Fri, 21 Nov 2014 00:00:00 </pubDate></item><item><title>Brocade Vyatta VPN service and device driver for Neutron</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/brocade-vyatta-vpnaas-plugin.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/brocade-vyatta-vpnaas-plugin"&gt;https://blueprints.launchpad.net/neutron/+spec/brocade-vyatta-vpnaas-plugin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Introduce the Brocade Vyatta VPN service and device driver to provide VPNaaS
solution using Vyatta vRouter VM running as a Neutron router.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Brocade Vyatta vRouter is a multi-service product that provides various L3 and
L4 services like Routing, NAT, Firewall, VPN, etc. While basic neutron router L3
functions are available using the Brocade Vyatta L3 plugin [1] vRouter’s IPSec
site-to-site VPN functionality is currently not configurable through existing
Neutron VPN APIs.&lt;/p&gt;
&lt;p&gt;When available Cloud Service providers would be able to create site-to-site
IPSec VPN to connect tenant networks to remote DC networks using Vyatta vRouter.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This blueprint proposes a new vendor service and device drivers for the
Neutron VPN plugin and agent.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+----------------------+&lt;/span&gt;                  &lt;span class="o"&gt;+----------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;Neutron&lt;/span&gt; &lt;span class="n"&gt;L3&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+------------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+------------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="n"&gt;VPN&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;VPN&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Service&lt;/span&gt; &lt;span class="n"&gt;Plugin&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+------------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+------------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;Vyatta&lt;/span&gt; &lt;span class="n"&gt;VPN&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;Vyatta&lt;/span&gt; &lt;span class="n"&gt;VPN&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;RPC&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Device&lt;/span&gt; &lt;span class="n"&gt;Driver&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Service&lt;/span&gt; &lt;span class="n"&gt;Driver&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--------------&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-+------------------+-+&lt;/span&gt;                  &lt;span class="o"&gt;+-+--------+---------+-+&lt;/span&gt;
                                                     &lt;span class="o"&gt;|&lt;/span&gt;
                                                     &lt;span class="o"&gt;|&lt;/span&gt;
                                                     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;REST&lt;/span&gt; &lt;span class="n"&gt;API&lt;/span&gt;
                                                     &lt;span class="o"&gt;|&lt;/span&gt;
                                            &lt;span class="o"&gt;+--------&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;---------+&lt;/span&gt;
                                            &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
                                            &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
                                            &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Vyatta&lt;/span&gt; &lt;span class="n"&gt;vRouter&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
                                            &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
                                            &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
                                            &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
                                            &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
                                            &lt;span class="o"&gt;+------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Vyatta VPN service driver will inherit from the reference ipsec service driver
except it will use a unique topic for RPCs to and from the Vyatta VPN device
driver. This is done to be inline with existing service-type framework already
partially in place and the expectation that if neutron flavor framework [4]
materializes the functionality proposed in this BP will work as-is.&lt;/p&gt;
&lt;p&gt;Vyatta VPN device driver will perform the following functions:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Handles the RPC message from vpn service-plugin that indicates a CRUD
operation for site-to-site vpn connection&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Gets the list of VPN services from the service-plugin using a RPC call&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prepares the list of new, deleted and updated vpn connection based on the
local service-cache entries&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Processes the above lists into effect using vRouter’s REST API interface&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updates the local service-cache to reflect the new changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reports the status of the vpn connections back to the vpn service-plugin&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All these functions are similar to the existing reference vpn device driver
implementation.&lt;/p&gt;
&lt;p&gt;Additionally during L3 Agent startup the device driver will read vRouter VPN
configuration using its REST API to rebuild the local service-cache. Once
rebuilt the steps 2 through 6 are repeated. This helps to bring the vRouter
VPN configuration to be in sync with the changes (if any) in the plugin DB
while the L3 agent was down.&lt;/p&gt;
&lt;p&gt;Note, we are aware of the current L3 agent refactoring proposed for Kilo [3].
Given the device driver interface is planned to be kept as-is the changes
proposed in this blueprint will integrate with minimal impact vis-a-vis the
refactoring.&lt;/p&gt;
&lt;p&gt;This effort is part of a wider set of blueprints to offer Neutron L3 and L4
services using the Vyatta vRouter VM:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[1] introduces neutron router functionality using the Vyatta vRouter&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[2] introduces firewall service using the Vyatta vRouter.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;The device driver will use a common RESTapi client library that uses basic-auth
authentication to connect to Vyatta vRouter.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;When tenants creates VPN using the Neutron API it will be created on the
carrier-grade Vyatta vRouter.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;Expected to work with IPv6&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Operators should first configure the Brocade Vyatta L3 plugin as described in
[1]. Then they can configure the new vpn service and device drivers to offer
Vyatta VPN using Neutron APIs as follows:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Edit /etc/neutron/neutron.conf and specify Vyatta VPN service driver as the default service provider for VPN.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;service_providers&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;service_provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;VPN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;brocade&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vpn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;service_drivers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vyatta_ipsec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BrocadeVyattaIPsecVPNDriver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Edit /etc/neutron/vpn_agent.ini and specify Vyatta VPN device driver.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vpnagent&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;vpn_device_driver&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;neutron&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vpn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;device_drivers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vyatta_ipsec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;VyattaIPSecDriver&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;Validating Neutron VPN APIs with multiple vendor, including this one from
Brocade, will help to move out of current experimental state for these APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;srics-r&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add new vyatta service driver for VPN service plugin
(currently planned for neutron/services/vpn/service_drivers/vyatta_ipsec.py)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new vyatta device driver for VPN agent
(currently planned for neutron/services/vpn/device_drivers/vyatta_ipsec.py)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add unit tests required to test the new code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add tempest tests for new scenarios&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Brocade Vyatta L3 Plugin [1]&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;3rd party testing will be provided (Brocade Vyatta CI)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Brocade Vyatta CI will report on all changes affecting this plugin&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing is done using devstack and Vyatta vRouter&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;No new API tests are planned as no APIs are changed as part of this blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Brocade specific documentation will be updated on the availability of this
functionality in Neutron and the vpn_device_driver configuration required to
enable it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[1] &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/l3-plugin-brocade-vyatta-vrouter"&gt;https://blueprints.launchpad.net/neutron/+spec/l3-plugin-brocade-vyatta-vrouter&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[2] &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/firewall-plugin-for-brocade-vyatta-vrouter"&gt;https://blueprints.launchpad.net/neutron/+spec/firewall-plugin-for-brocade-vyatta-vrouter&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[3] &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/restructure-l3-agent"&gt;https://blueprints.launchpad.net/neutron/+spec/restructure-l3-agent&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[4] &lt;a class="reference external" href="https://review.openstack.org/#/c/102723"&gt;https://review.openstack.org/#/c/102723&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 20 Nov 2014 00:00:00 </pubDate></item><item><title>Support for VLAN networks in Distributed Virtual Router (DVR)</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/neutron-ovs-dvr-vlan.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-ovs-dvr-vlan"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-ovs-dvr-vlan&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With Juno deployment, users of openstack neutron can deploy distributed virtual
routers as referred in [1].&lt;/p&gt;
&lt;p&gt;DVRs enable routing between tenant VMs without the need to deploy a
centralized node to host tenant routers. Tenants can create distributed
routers and such routers are made available on-demand basis on the compute
servers that have tenant VMs on subnets hosted by the router.&lt;/p&gt;
&lt;p&gt;However, in Juno release of neutron, distributed router interfaces that are
managed can belong only to VXLAN (or) GRE network types.&lt;/p&gt;
&lt;p&gt;The capability to host VLAN network types as distributed router interfaces was
not available.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;As explained in the introduction section above, Juno release of openstack
makes available distributed virtual routers.  However, the implementation
available is functional only for network_types for VXLAN and GRE.&lt;/p&gt;
&lt;p&gt;This blueprint will address the following gaps:&lt;/p&gt;
&lt;p&gt;1. Enables VLAN Networks to be hosted as distributed router interfaces
More specifically, if two networks are attached as interfaces of a dvr,
of which both the networks are VLAN type, then VMs on such network can
route traffic between each other transparent to the tenant, via
this blueprint.&lt;/p&gt;
&lt;p&gt;2. Enables a distributed router to route packets between a VLAN network,
VXLAN network and GRE network.
More specifically, if two networks are attached as interfaces of a dvr,
of which one is a VLAN network and another is a VXLAN network, then VMs
on such network can route traffic between each other transparent to the
tenant, via this blueprint.
Similarly, this blueprint also enables routed communication between
one interface of the dvr being on VLAN network and another interface
being on GRE network.
Also, this blueprint also enables routed communication between one
interface of a dvr being on a VXLAN network and another interface
being on a GRE network.&lt;/p&gt;
&lt;p&gt;We are intending to clarify here that this blueprint would enable only routed
traffic to pass through disparate network types (only VLAN, VXLAN, GRE).
This blueprint does not propose a gateway to switch traffic across disparate
networks.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;We will be making changes to the following components of the Openstack
Neutron as part of implementation of this blueprint:&lt;/p&gt;
&lt;p&gt;a. The DVR RPCs serviced by the ML2 Plugin will be enhanced to provide
physical network information that will be used by the OVS Neutron
Agent to plumb VLAN network-type ports as DVR interfaces.&lt;/p&gt;
&lt;p&gt;b. The OVS DVR Neutron Agent will be enhanced to embrace VLAN network-type
thereby allowing tenant VMs that are on VLAN networks to communicate via
distributed router.   Also it will be enhanced to enable tenant VMs (one
on VLAN and other on VXLAN/GRE network) to communicate via
distributed router.
By enhancement, we want to refer that OVS Rules will be added to
integration-bridge and physical-bridges by the OVS DVR Neutron Agent
in order to enable routing between VMs on different VLAN networks and
also to enable routing between VMs that each reside on a VLAN network
and a VXLAN/GRE network.&lt;/p&gt;
&lt;p&gt;So, the blueprint will enable DVR openvswitch implementation to embrace
VLAN network-types.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;This change will not have impact on IPv6 in Neutron.&lt;/p&gt;
&lt;p&gt;The Distributed Virtual Router (dvr) in [1] does not support IPv6
networks.  And, so the DVR feature must first be enhanced to support
IPv6 as a separate blueprint.  Until then IPv6 tenant networks
will not able to take advantage of the DVR feature in neutron.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;The Neutron community embraced the DVR feature in the intent that
it resolves parity issues with nova-network.   This blueprint will
further close gaps to bring-in more parity.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;The author of this blueprint will be posting code for reviews
by the community.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="mailto:vivekanandan.narasimhan%40hp.com"&gt;vivekanandan&lt;span&gt;.&lt;/span&gt;narasimhan&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="mailto:blak111%40gmail.com"&gt;blak111&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt; (kevin benton)
&lt;a class="reference external" href="mailto:swaminathan.vasudevan%40hp.com"&gt;swaminathan&lt;span&gt;.&lt;/span&gt;vasudevan&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt; (review)
&lt;a class="reference external" href="mailto:rajeev.grover%40hp.com"&gt;rajeev&lt;span&gt;.&lt;/span&gt;grover&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt; (review)
&lt;a class="reference external" href="mailto:michael.smith6%40hp.com"&gt;michael&lt;span&gt;.&lt;/span&gt;smith6&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt; (review)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The following are the work items involved for execution of this
blueprint:&lt;/p&gt;
&lt;p&gt;1. Primary code-piece development in Neutron to enhance existing DVR logic
to embrace VLAN networks (in addition to retaining the functionality to host
VXLAN/GRE networks).&lt;/p&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;Unit test cases development to ensure test coverage for this feature.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;3. There will be functional test cases that will be added in initial commits
to test the feature.&lt;/p&gt;
&lt;p&gt;4. In the longer term (in next release), the existing DVR CI would be enhanced to
embrace VLAN-type networks as DVR interfaces.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Depends on the Distributed Virtual Router blueprint as in [1].&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;As mentioned in Work Items, initially functional tests will be made
available to test this feature.  Later the existing DVR CI (available at gate)
will be enhanced to embrace testing VLAN networks with DVR.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional tests cases would be provided to test this feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;There will be documentation impact as we need to include in the openstack
neutron manual, that DVR is capable of supporting VLAN network-type.
The auther and the extended existing DVR team will work with
neutron documentation in including this feature.&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Openstack Networking Administration Guide will be updated to reflect
the capability brought in by this blueprint into DVR.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] DVR blueprint: &lt;a class="reference external" href="http://specs.openstack.org/openstack/neutron-specs/specs/juno/neutron-ovs-dvr.html"&gt;http://specs.openstack.org/openstack/neutron-specs/specs/juno/neutron-ovs-dvr.html&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 29 Oct 2014 00:00:00 </pubDate></item><item><title>Restructure L3 Agent</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/restructure-l3-agent.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/restructure-l3-agent"&gt;https://blueprints.launchpad.net/neutron/+spec/restructure-l3-agent&lt;/a&gt;&lt;/p&gt;
&lt;dl class="field-list simple"&gt;
&lt;dt class="field-odd"&gt;Author&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-odd"&gt;&lt;p&gt;Carl Baldwin &amp;lt;&lt;a class="reference external" href="mailto:carl.baldwin%40hp.com"&gt;carl&lt;span&gt;.&lt;/span&gt;baldwin&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The L3 agent is implemented mostly in a single python file.  At current count,
this file is just over 2,000 lines of code &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.  Most of the functionality is
provided by the L3NATAgent class which comprises about 75% of the file.  This
class handles everything from handling RPC messages down to sending gratuitous
arp for newly added addresses on the interfaces inside the routers’ namespaces.
This structure makes the agent very difficult to extend and modify.  This is a
bit of technical debt.  Paying it down will help enable the development of new
functionality.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/c9bea66dfe/neutron/agent/l3_agent.py#L2047"&gt;https://github.com/openstack/neutron/blob/c9bea66dfe/neutron/agent/l3_agent.py#L2047&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;As mentioned in the introductory paragraph, the L3 agent has gotten out of
hand.  The structure of this code has made it difficult to extend and develop
new features.  Following is a list of responsibilities taken care of in the
l3_agent.py file and mostly in the L3NATAgent class within that file.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Defines the L3PluginApi&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manages link local addresses for the DVR fip namespace&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Defines the RouterInfo, basically a big struct of data about a router&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handles router update messages from RPC in a queue&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handles periodic synchronization of all routers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L3NATAgent&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Manages namespace lifecycle&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handles router addition removal&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Runs metadata proxy in each router&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Very large method called process_router&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;snat_rules, dnat_rules&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;floating_ip_address&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;external gateway&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;internal network interfaces&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ipv6 support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cleanup of stale interfaces&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;static routes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HA router keepalive&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DVR routers&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;rtr_2_fip&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;dvr floating ips&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;snat namespace handling&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;arp entries&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;routes_updated&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;_process_routers_loop&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;_sync_routers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;gratuitous arp&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L3NATAgentWithStateReport&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Code for DVR and HA routers is mingled throughout.  There is a lot of “if
router[‘distributed’]” this and “if ri.is_ha” that.&lt;/p&gt;
&lt;p&gt;There is no clear strategy for resource life-cycle management of resources like
namespaces and devices.  Most of it has evolved over time as problems with the
initial implementation have been found.  Such problems are usually around them
not being deleted when they should be gone.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="overview"&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
&lt;p&gt;This will not be a rewrite of the L3 agent from scratch.  Starting this project
as a Herculean effort designed to land as a single patch is a sure recipe for
failure.  Much of this work will be pure refactoring but not all of it.  Work
will be posted for review early and often.  Dependencies between patches will
be avoided when possible.  Each patch will stand on its own as a reasonably
reviewable improvement to the existing code base.&lt;/p&gt;
&lt;p&gt;Proper separation of concerns is a goal however, this will be done in steps.
We’ll start with the high level separation of the router abstraction from the
L3 agent.&lt;/p&gt;
&lt;section id="l3-agent"&gt;
&lt;h4&gt;L3 Agent&lt;/h4&gt;
&lt;p&gt;The L3 agent will be responsible for listening for updates from RPC, queuing
the updates for processing by a worker.  It will continue to oversee the set of
routers which are managed by the agent.  If namespaces are enabled, this could
be a large set of routers.  If namespaces are not enabled, this will be a single
router.  (_process_routers, _sync_routers, routes_updated,
_router_added/removed)&lt;/p&gt;
&lt;p&gt;The agent will still manage external networks available to routers on the
agent.&lt;/p&gt;
&lt;p&gt;The L3PluginApi class will remain as it is in l3_agent.py.&lt;/p&gt;
&lt;p&gt;The agent will retain the L3NATAgentWithStateReport capability.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="router"&gt;
&lt;h4&gt;Router&lt;/h4&gt;
&lt;p&gt;A new router class will be introduced.  A lot of functionality currently
handled by the L3 agent – especially the functionality in the process_routers
method – will be encapsulated by this new class.  The current RouterInfo class
will move under this abstraction.  This class will obsolete and replace the
RouterInfo class.&lt;/p&gt;
&lt;p&gt;The router class will be more than just a struct with data about the router.  It
will be a full-fledged class that is capable of handling the implementation of
the router.  It needs a clear and uncomplicated python API defined.&lt;/p&gt;
&lt;p&gt;As of the Juno release, there are three kinds of routers available.  These are
distributed, highly available, and legacy routers.  A new router class
hierarchy will be added to encapsulate the details of each available type of
router.  The appropriate class will be loaded when the router instance is first
created.&lt;/p&gt;
&lt;p&gt;Kilo or beyond will see the addition of a fourth type of router which combines
DVR and HA routers.  Adding this fourth type is out of the scope of this
blueprint.  However, adding this new type of router should be relatively easy
after this blueprint has been completed by creating a new class type which
combines the functions of the separate base classes.  This new classes should be
written in a way which efficiently makes use of the existing code in the two
base classes.  Any additional complexity in this module should only exist to work out
any coordination which needs to happen between the two classes.&lt;/p&gt;
&lt;p&gt;The above uses inheritence to encapsulate the details of the various kinds of
routers with an abstract base router serving as the base class and the others
implemented as sub-classes.  The HA DVR type of router would then use multiple
inheritence.  Following is a dot representation of what I imagine the hierarchy
will be.  Notice that LegacyRouter is not a base class.  This reflects the fact
that “DistributedRouter is a LegacyRouter” is not a true statement.  Also,
there are two DVR classes.  This reflects the fact that non-network nodes have
the distributed part of a DVR and network nodes have the central part which
builds from the distributed part:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;digraph&lt;/span&gt; &lt;span class="n"&gt;inheritence&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"LegacyRouter"&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Router"&lt;/span&gt;
  &lt;span class="s2"&gt;"DistributedRouter"&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Router"&lt;/span&gt;
  &lt;span class="s2"&gt;"DistributedRouterCentral"&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"DistributedRouter"&lt;/span&gt;
  &lt;span class="s2"&gt;"HARouter"&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Router"&lt;/span&gt;
  &lt;span class="s2"&gt;"HADistributedRouter"&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"HARouter"&lt;/span&gt;
  &lt;span class="s2"&gt;"HADistributedRouter"&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"DistributedRouterCentral"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Given that HA and DVR are properties of individual routers and not properties
of the deployment, we will need to pay attention to the migration path from one
to another.  The code should fully expect that a router can change from one
type to another and have the capability to handle it by changing the class used
for a router.  I expect that the router should be functional with its new type
and that  any namespaces, devices, or other resources that are no longer
necessary after the router changes type will be cleaned up.  The clean up will
be handled by the resource lifecycle pattern described in the &lt;a class="reference internal" href="#resource-lifecycle"&gt;Resource
Lifecycle&lt;/a&gt; section.&lt;/p&gt;
&lt;p&gt;The very long _process_router method needs to be refactored with this.  The
following responsibilities are handled here.  Eventually, these will be
abstracted behind other interfaces (like an iptables abstraction) but that work
may not be completely done as part of this effort.  At a high level, the
refactoring of this method will separate concerns like plugging interfaces to
networks from routing responsibilies.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;snat_rules, dnat_rules&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;floating_ip_address&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;external_gateway_added&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;internal network added&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;static routes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="services"&gt;
&lt;h4&gt;Services&lt;/h4&gt;
&lt;p&gt;There are a few services implemented in the L3 agent in various ways.  This
blueprint will add a simple service driver model to support decoupling these
services from the L3 agent class and its inheritence hierarchy.  As stated
before, inheritence will not be used to integrate these services.  Each of the
services will be moved to a new service specific module&lt;/p&gt;
&lt;p&gt;Essentially, the agent will be a basic container which loads services as
classes.  The routing service orchestrates the workflow for services by
dispatching router events to each of the known services sequentially.  For this
blueprint, the dispatching will likely be implemented as a simple method call
to a common service interface.  This can be expanded to support a more
pluggable model as a follow-on effort.&lt;/p&gt;
&lt;p&gt;The services will have a reference to the router in order to access L3 function
such as adding/removing NAT rules and opening ports.&lt;/p&gt;
&lt;p&gt;I don’t intend to make any significant changes to the device driver models that
are implemented in the FW and VPN services in the scope of this blueprint.  I
don’t expect this effort to have any effect on the configuration of services.
Backward compatibility will be actively preserved.  This may involve leaving
stubs in place for the VPNAgent and others to load a VPN enabled L3 agent.&lt;/p&gt;
&lt;p&gt;Existing integration tests will be modified to work with the new structure.&lt;/p&gt;
&lt;p&gt;The intent here will not be to make a model that is everything to everyone.
That is out of the scope of this blueprint.  The intent is to iteratively
develop an interface that will work for the following services which are
already integrated with the L3 agent.  The goal is to reduce coupling and pave
the way for a more sophisticated model which may be needed in the future.  They
will be tackled in the order listed and the interface will evolve to support
them all.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Metadata Proxy&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The easiest one.  Low-hanging fruit.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;FWaaS&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Want to remove it as a super-class of L3NATAgent&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;VPNaaS&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Want to remove it as a sub-class of L3NATAgent&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;The first step is to create a service abstract class, and then sub-classes
for the various services to use these as observers to the L3 agent.  The base
class would have no-op methods for each action that the L3 agent could notify
about, and the child classes would implement the ones they’re interested in.
Each service will register as an observer.&lt;/p&gt;
&lt;p&gt;Currently, the L3 agent (and VPN agent) load the device drivers for services.
What can be done in this first step, is, instead of doing the load, a service
object can be created. This object would do the loading and register with the
L3 agent for notifications.&lt;/p&gt;
&lt;p&gt;The child services’ notification handlers will be populated by moving the code
in the various agent classes into the new service child classes, and adapt as
needed.&lt;/p&gt;
&lt;p&gt;Anything more complicated than this should be considered out of the scope of
this blueprint.&lt;/p&gt;
&lt;p&gt;Some guidelines for this work:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;We don’t need the service abstract class to be perfectly and completely
defined in advance.  I intend to do this iteratively tackling the services
in the order listed above.  This means that we don’t review the changes to
decouple the metadata proxy with the needs of the VPN agent in mind.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This initial decomposition should be done without changing any
configuration or other deployment details.  This might mean that we leave,
for example, a tiny stub of a VPNAgent class in place.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Initially, the services will get an L3 agent passed in on create, but in the
as the blueprint progresses, a router instance can be passed to the service.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="dvr-router-class"&gt;
&lt;h4&gt;DVR Router Class&lt;/h4&gt;
&lt;p&gt;Everything related to the floating IP namespace that was added for DVR should
be encapsulated in a driver for plugging a router in to an external network and
handle floating ip setup.  This includes the LinkLocalAllocator, dvr specific
floating ip processing, fip namespace management, connection of router to fip
(rtr_2_fip, fip_2_rtr), _create_dvr_gateway, and the management of proxy arp
entries.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ha-router-class"&gt;
&lt;h4&gt;HA Router Class&lt;/h4&gt;
&lt;p&gt;This encapsulation will hide the details related to starting keepalived and
creating and using interfaces needed for the HA network on which it
communicates.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="resource-lifecycle"&gt;
&lt;h4&gt;Resource Lifecycle&lt;/h4&gt;
&lt;p&gt;The major problem here is that resources are often left lying around beyond
their useful lifecycle.  Assumptions were made about the reliable availability
of the agent, guaranteed ordering and delivery of RPC messages, and other
unrealistic guarantees.  The new design will account for problems in these
areas.  No assumptions will be made.  This will result in a more robust
implementation.&lt;/p&gt;
&lt;p&gt;The problem that we’ve had with this is that the agent fails to cleanup
resources when they should no longer exist.  To address this, I’m thinking of
something that supports the following pattern using namespaces as an example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;full_sync&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;namespace_manager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prepare_to_clean_up_stale&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;nsm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;all_active_routers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;nsm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;link_router_to_ns_somehow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The __enter__ and __exit__ methods should work together to discover stale
namespaces and then clean them up.  I’m thinking maybe a namespace object
should hold a weak reference to the router that occupies it.  When the weak ref
goes stale then the namespace can be removed.  This pattern is not too
different from what exists in the code now since some earlier refactoring that
I did.  However, this effort will formalize the pattern and abstract it from
the rest of the code.  Code has been started to illustrate this pattern &lt;a class="footnote-reference brackets" href="#id4" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/130052/"&gt;https://review.openstack.org/#/c/130052/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;p&gt;The pattern can be applied to other resources such as interfaces inside of a
namespace.  We have had problems ensuring that those get removed when they are
no longer useful as well.  For devices and other resources in a router, the
active resources would all be marked each time a router is processed.  Stale
resources are then identified and removed.&lt;/p&gt;
&lt;p&gt;There has been a problem with namespaces which are persistently difficult to
delete due to a problem in the version of iproute in use on the system &lt;a class="footnote-reference brackets" href="#id7" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and
&lt;a class="footnote-reference brackets" href="#id8" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.  There really is nothing that can be done to remove these except to
reboot the machine.  However, the new implementation of resource lifecycle
management will hold a set of namespaces that it has tried to delete.  If the
deletion fails, it will skip this deletion in future clean up runs.  Ideally,
the operator will either keep namespace deletion disabled or upgrade the
iproute package on the system to avoid these problems.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id7" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/ubuntu/+source/iproute/+bug/1238981"&gt;https://bugs.launchpad.net/ubuntu/+source/iproute/+bug/1238981&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugzilla.redhat.com/show_bug.cgi?id=1062685"&gt;https://bugzilla.redhat.com/show_bug.cgi?id=1062685&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;section id="configuration-handling"&gt;
&lt;h4&gt;Configuration Handling&lt;/h4&gt;
&lt;p&gt;The handling of the config options will be cleaned up a bit; there’s so much
‘if that’ and ‘if this’ with config options too. Behavior needs to be properly
encapsulated so that we don’t need to branch so much so often.  A few examples
examples are linked in the references &lt;a class="footnote-reference brackets" href="#id13" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id14" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id15" id="id11" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; &lt;a class="footnote-reference brackets" href="#id16" id="id12" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;8&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id13" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/c9bea66dfe/neutron/agent/l3_agent.py#L584"&gt;https://github.com/openstack/neutron/blob/c9bea66dfe/neutron/agent/l3_agent.py#L584&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id14" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id10"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/c9bea66dfe/neutron/agent/l3_agent.py#L743"&gt;https://github.com/openstack/neutron/blob/c9bea66dfe/neutron/agent/l3_agent.py#L743&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id15" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id11"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/c9bea66dfe/neutron/agent/l3_agent.py#L1349"&gt;https://github.com/openstack/neutron/blob/c9bea66dfe/neutron/agent/l3_agent.py#L1349&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id16" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id12"&gt;8&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron/blob/c9bea66dfe/neutron/agent/l3_agent.py#L1460"&gt;https://github.com/openstack/neutron/blob/c9bea66dfe/neutron/agent/l3_agent.py#L1460&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;No impact is expected.  We need to be careful when reviewing code that these
changes do not introduce vulnerabilities in the agent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;We will take care to preserve all existing IPv6 functionality in Neutron.  No
changes or additions to the current IPv6 functionality are planned.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Much of code in the l3_agent.py file will be moved out to other files.  This
refactoring will introduce better software engineering patterns to allow the
functionality to be extended, modified, and maintained more easily.&lt;/p&gt;
&lt;p&gt;Developers who have become accustomed to the current implementation will
likely not recognize the end result.  However, they will be able to easily get
reaquainted with the new code.&lt;/p&gt;
&lt;p&gt;To avoid problems with rebasing and potential regressions while the
heavy-lifting is being done, non-critical changes to the L3 agent should be
avoided while this work is in progress.  Mail will be sent to the openstack-dev
ML to begin a freeze on non-critical changes and another one to end it.  The
freeze will only be needed during the initial more disruptive restructuring.
As certain part stabilize, the freeze will be lifted.  For example, once the
VPN and FW services have been decoupled from the agent code – which will be
the first step – development on those services can continue.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;This change is part of the approved Neutron priorities for Kilo.&lt;/p&gt;
&lt;p&gt;It supports at least the following efforts which may also be planned for Kilo.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Pluggable external networks blueprint (dynamic routing integration indirectly)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enabling HA routers and DVR to work together.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Better integration of L3 services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Spinning out advanced services&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The alternative is to leave it like it is and to perform small bits of
refactoring only when it is necessary for a particular new feature.  This is
not ideal since there are already a number of things that this refactoring
needs to support.  It will slow down the development of that work if this is
delayed.&lt;/p&gt;
&lt;p&gt;Writing a new agent and eventually deprecating the current one is another
alternative?  I’ve personally never had a very good experience with this
approach.  It seems to trade one set of known problems for another set of
unknown problems.  Regressions are all too common.  I prefer to restructure in
small reviewable pieces.  This does not guarantee no regressions but it can
uncover them earlier in the process and they are easier to pinpoint and fix.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~carl-baldwin"&gt;carl-baldwin&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~amuller"&gt;amuller&lt;/a&gt;
&lt;a class="reference external" href="https://launchpad.net/~jschwarz"&gt;jschwarz&lt;/a&gt;
&lt;a class="reference external" href="https://launchpad.net/~pcm"&gt;pcm&lt;/a&gt;
&lt;a class="reference external" href="https://launchpad.net/~yamahata"&gt;yamahata&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;I expect that some of the initial work items will need to be tackled in
sequential order because of the high degree of coupling in the code.  However,
as things are decomposed and the coupling is reduced, other work items can be
tackled in parallel.&lt;/p&gt;
&lt;p&gt;For example, since the service agents are coupled with the L3 agent inheritence
hierarchy, they will need to be moved out before a proper router abstraction is
feasible.&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Functional Testing for the Agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Service Drivers&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Start simple.  This won’t be everything to everyone yet.  It is not meant
to full-blown pluggable service drivers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Metadata Proxy&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FWaaS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VPNaaS&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decomposition and modularization of DVR, HA, and legacy routers&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Create a proper abstraction of a router to replace RouterInfo&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Can serve as an abstraction for other router implementations.  Again,
we’ll start simple to introduce the abstraction.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create the inheritence hierarchy.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This may be done in a few steps.  Initially, the inheritence hierarchy
may be thin with most of the implementation still in the base class.
Future steps will move responsibilities to the sub-classes and evolve
the interface.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;In addition to the functional tests discussed below, effort will be made to use
existing unit tests as necessary to be sure that existing coverage is retained
and avoid regressions they were created to prevent.  The end result may look
like all of the old unit tests have been removed and new, better ones have been
written in their place.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;All&lt;/em&gt; new and restructured code will be covered with proper unit test coverage.
It will be significantly easier to unit test with the new structure of the
code.  If it isn’t then we’re doing it wrong.&lt;/p&gt;
&lt;p&gt;I don’t plan to make an effort to add missing &lt;em&gt;unit&lt;/em&gt; test coverage before the
code is restructured.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;No new tempest tests are planned.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Functional tests will be added from the L3 agent prior to any significant
restructuring of the agent code.  Assaf &lt;a class="footnote-reference brackets" href="#id20" id="id17" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;9&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; will take the lead of this testing
effort with help from John Schwarz &lt;a class="footnote-reference brackets" href="#id21" id="id18" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;10&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and all of the other assignees listed
in this blueprint.  This includes the addition of functional tests for the new
DVR and HA &lt;a class="footnote-reference brackets" href="#id22" id="id19" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;11&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; features.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id20" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id17"&gt;9&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~amuller"&gt;https://launchpad.net/~amuller&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id21" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id18"&gt;10&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~jschwarz"&gt;https://launchpad.net/~jschwarz&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id22" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id19"&gt;11&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/117994/"&gt;https://review.openstack.org/#/c/117994/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;No new API tests are planned.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;New API interfaces in the code will be documented with doc strings&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/kilo-neutron-agents-technical-debt"&gt;https://etherpad.openstack.org/p/kilo-neutron-agents-technical-debt&lt;/a&gt;
&lt;a class="reference external" href="https://review.openstack.org/#/c/105078/"&gt;https://review.openstack.org/#/c/105078/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 23 Oct 2014 00:00:00 </pubDate></item><item><title>Neutron OVS DVR - Distributed Virtual Router</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/neutron-ovs-dvr.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-ovs-dvr"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-ovs-dvr&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron Distributed Virtual Router implements the L3 Routers across the
Compute Nodes, so that tenants intra VM communication will occur without
hiting the Network Node. (East-West Routing)&lt;/p&gt;
&lt;p&gt;Also Neutron Distributed Virtual Router implements the Floating IP namespace
on every Compute Node where the VMs are located. In this case the VMs with
FloatingIPs can forward the traffic to the External Network without reaching
the Network Node. (North-South Routing)&lt;/p&gt;
&lt;p&gt;Neutron Distributed Virtual Router provides the legacy SNAT behavior for
the default SNAT for all private VMs. SNAT service is not distributed, it
is centralized and the service node will host the service.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Today Neutron L3 Routers are deployed in specific Nodes (Network Nodes) where
all the Compute traffic will flow through.&lt;/p&gt;
&lt;p&gt;Problem 1: Intra VM traffic flows through the Network Node&lt;/p&gt;
&lt;p&gt;In this case even VMs traffic that belong to the same tenant on a different
subnet has to hit the Network Node to get routed between the subnets.
This would affect Performance.&lt;/p&gt;
&lt;p&gt;Problem 2: VMs with FloatingIP also receive and send packets through the
Network Node Routers&lt;/p&gt;
&lt;p&gt;Today FloatingIP (DNAT) translation done at the Network Node and also the
external network gateway port is available only at the Network Node. So any
traffic that is intended for the External Network from the VM will have to
go through the Network Node.&lt;/p&gt;
&lt;p&gt;In this case the Network Node becomes a single point of failure and also the
traffic load will be heavy in the Network Node. This would affect the
performance and scalability.&lt;/p&gt;
&lt;p&gt;This would also help the Neutron networks to be on par with the Nova parity.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposal is to distribute the L3 Routers across the Compute Nodes when
required by the VMs.&lt;/p&gt;
&lt;p&gt;In this case there will be Enhanced L3 Agents running on each and every
compute node ( This is not a new agent, this is an updated version of the
existing L3 Agent). Based on the configuration in the L3 Agent.ini file,
the enhanced L3 Agent will behave in legacy(centralized router) mode or
as a distributed router mode.&lt;/p&gt;
&lt;p&gt;Also the FloatingIP will have a new namespace created on the specific compute
Node where the VM is located
Each Compute Node will have one new namespace for FIP, per external network
that will be shared among the tenants.
An External Gateway port will be created on the
Compute Node for the External Traffic to Flow through.&lt;/p&gt;
&lt;p&gt;Default SNAT functionality will still be centralized and will be running on a
Service Node.&lt;/p&gt;
&lt;p&gt;The Metadata agent will be distributed as well and will be hosted on all compute
nodes and the Metadata Proxy will be hosted on all the Distributed Routers.&lt;/p&gt;
&lt;p&gt;The existing DHCP server will still run on the Service Node. There are future
plans to distributed the DHCP. ( This will be addressed in a different blueprint)&lt;/p&gt;
&lt;p&gt;This implementation is specific to ML2 with OVS driver.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative is to use a Kernel Module. But we did not pursue this since
there was a dependency for the Kernel Module to be part of the upstream
linux distribution before we push this patch.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;There are couple of minor data model changes that will be
addressed by this blueprint.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Router object Data Model.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+----------------+--------------+------+-----+---------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;Field&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;Type&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Default&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------+--------------+------+-----+---------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tenant_id&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Yes&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NO&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;PRI&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;admin_state_up&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;gw_port_id&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;MUL&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;enable_snat&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NO&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;distributed&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------+--------------+------+-----+---------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Add “distributed” flag to the router object data model. This
will enable the agent to take necessary action based on the
router model.&lt;/p&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;SNAT Agent to host mapping data model.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A new table for the service node enhanced L3 agent to
track the SNAT service on each node.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+------------------+--------------+------+-----+---------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Default&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------------------+--------------+------+-----+---------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NO&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;PRI&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;router_id&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;MUL&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;host_id&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;l3_agent_id&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;YES&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;MUL&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------------------+--------------+------+-----+---------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ol class="arabic simple" start="3"&gt;
&lt;li&gt;&lt;p&gt;ML2 DVR interface binding data model.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;dl&gt;
&lt;dt&gt;::&lt;/dt&gt;&lt;dd&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Field&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Null&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Key&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Default&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;port_id
host
router_id
vif_type
vif_details
vnic_type
profile
cap_port_filter
driver
segment
status&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string(36)
string(255)
string(36)
string(64)
string(4095)
string(64)
string(36)
boolean
string(64)
string(36)
string(16)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;NO
NO
YES
YES
YES
YES
YES
YES
YES
YES
YES&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;PRI
PRI&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;A new table that is used to hold port bindings for DVR router
interfaces only.
This is similar to the portbindings table, but this table will hold
bindings only for dvr router interfaces.&lt;/p&gt;
&lt;p&gt;The original portbindings table will also hold one-binding row
for a dvr router interface, but that won’t hold binding information.
That binding row is held there, only to ensure transparency of dvr presence
to the tenants themselves.&lt;/p&gt;
&lt;p&gt;Some of the significant fields in the above are:
port_id - This refers to the port id of the DVR Router interface for which
this binding is applied to. The port-id will refer to id field
of the port table.
host - This holds the host on which the DVR interface is bound.
router_id - This field indicates for which router interface, this
binding belongs.
status - This field represents the status of the dvr interface port on the
host, which is represented by this binding.&lt;/p&gt;
&lt;p&gt;The status field value of the single-binding row for dvr router
interface in the original portbindings table will now be an ORed result
of the above status field of all such bindings available in the above
table for dvr router interfaces.&lt;/p&gt;
&lt;ol class="arabic simple" start="4"&gt;
&lt;li&gt;&lt;p&gt;ML2 DVR Unique MAC Address Table:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;dl&gt;
&lt;dt&gt;::&lt;/dt&gt;&lt;dd&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Field&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Null&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Key&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Default&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;host
mac_address&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string(255)
string(32)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;NO
NO&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;PRI&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;NULL&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;A new table that is used to hold Unique DVR Base mac assigned to OVS L2
agent that is running in DVR Mode.&lt;/p&gt;
&lt;p&gt;For any given host where an OVS L2 Agent is running, only one MAC Address
from the DVR Base Mac pool is allocated to that OVS L2 Agent. This
allocation rpc cycle, completes during init() of the OVS L2 Agent.&lt;/p&gt;
&lt;p&gt;In order to make OVS L2 Agent run in DVR Mode, enable_distributed_routing
flag must be set to True in the [agent] section of ml2 ini file (ml2_conf.ini).&lt;/p&gt;
&lt;p&gt;Similarly, the DVR Base Mac Address which represents start of the pool, need
to be defined in neutron.conf&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;router-create    Create a router for a given tenant.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;another_router&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;distributed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;true&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Admin can only set this attribute. The tenants need not be aware about
this attribute in the router table. So it is not visible to the tenant.&lt;/p&gt;
&lt;p&gt;Request&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;routers&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"router"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"another_router"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s2"&gt;"admin_state_up"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s2"&gt;"distributed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"router"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
&lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s2"&gt;"external_gateway_info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"another_router"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s2"&gt;"admin_state_up"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s2"&gt;"distributed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"6b96ff0cb17a4b859e1e575d221683d3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"8604a0de-7f6b-409a-a47c-a1cc7bc77b2e"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;router-show    Show information of a given router.&lt;/p&gt;
&lt;p&gt;Request&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;routers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;a9254bdb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2613&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;a13&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ac4c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;adc581fba50d&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Response&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"routers"&lt;/span&gt;&lt;span class="p"&gt;:[{&lt;/span&gt;
&lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s2"&gt;"external_gateway_info"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
&lt;span class="s2"&gt;"network_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"router1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s2"&gt;"admin_state_up"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s2"&gt;"distributed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s2"&gt;"tenant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"33a40233088643acb66ff6eb0ebea679"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"a9254bdb-2613-4a13-ac4c-adc581fba50d"&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;router-update    Create a router for a given tenant.&lt;/p&gt;
&lt;p&gt;Admin can only update a centralized router to a distributed router.&lt;/p&gt;
&lt;p&gt;Note: Admin can only update a centralized router to a distributed
router and not the other way around. For the first release we are
targeting only from centralized to distributed.&lt;/p&gt;
&lt;p&gt;Admin only context:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;router1&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;distributed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Admin only CLI commands:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;l3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hosting&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;snat&lt;/span&gt;   &lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="n"&gt;L3&lt;/span&gt; &lt;span class="n"&gt;agents&lt;/span&gt; &lt;span class="n"&gt;hosting&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;snat&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This command will list the agent with the router-id and SNAT IP.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;l3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;snat&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;            &lt;span class="n"&gt;Associate&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;snat&lt;/span&gt; &lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;L3&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This command will allow an admin to associate a SNAT namespace to an agent.
This command will take the router ID as an argument.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;l3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;snat&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;remove&lt;/span&gt;         &lt;span class="n"&gt;Remove&lt;/span&gt; &lt;span class="n"&gt;snat&lt;/span&gt; &lt;span class="n"&gt;association&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;an&lt;/span&gt; &lt;span class="n"&gt;L3&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This command will allow an admin to remove or disassociate a SNAT service from
the agent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Need to make sure the existing FWaaS and the Security Group Rules
are not affected by the DVR.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Yes this change will have some impact on the python-neutronclient&lt;/p&gt;
&lt;p&gt;The Admin level API proposed above will have to be implemented in
the CLI.&lt;/p&gt;
&lt;p&gt;Also there is an impact with Horizon to address the admin level API
mentioned above.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Improves Performance.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Inter VM traffic between the tenant’s subnet need not reach the
router in the Network node to get routed and will be routed locally
from the Compute Node. This would increase the performance substantially.&lt;/p&gt;
&lt;p&gt;Also the Floating IP traffic for a VM from a Compute Node will directly hit
the external network from the compute node, instead of going through the
router on the network node.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Global Configuration to enable Distributed Virtual Router.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;#neutron.conf&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# To enable distributed routing this flag need to be enabled.&lt;/span&gt;
&lt;span class="c1"&gt;# It can be either True or False.&lt;/span&gt;
&lt;span class="c1"&gt;# If False it will work in a legacy mode.&lt;/span&gt;
&lt;span class="c1"&gt;# If True it will work in a DVR mode.&lt;/span&gt;

&lt;span class="c1"&gt;#router_distributed = True&lt;/span&gt;


&lt;span class="c1"&gt;# ovs_neutron_plugin.ini&lt;/span&gt;

&lt;span class="c1"&gt;# This flag need to be enabled for the L2 Agent to address&lt;/span&gt;
&lt;span class="c1"&gt;# DVR rules&lt;/span&gt;

&lt;span class="c1"&gt;#enable_distributed_routing = True&lt;/span&gt;


&lt;span class="c1"&gt;# l3_agent.ini&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# This flag is required by the L3 Agent as well to run the L3&lt;/span&gt;
&lt;span class="c1"&gt;# agent in a Distributed Mode.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#distributed_agent = True&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will be disabled by default.&lt;/p&gt;
&lt;p&gt;NOTE: This is for backward compatibility. For migration the admin
might have to run the db-migration script and also re-start the
agents with the right configuration to take effect.&lt;/p&gt;
&lt;p&gt;If Cloud admin wanted to enable the feature this can be configured.&lt;/p&gt;
&lt;p&gt;It currently uses the existing OVS binary in Linux Distribution. So
there should not be any new binaries.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Multinode Devstack setup may be required to develop and test.&lt;/p&gt;
&lt;p&gt;Services Impact - Some of the services such as the VPN and FW should be
refactored to accomodate the distributed virtual routers. The respective
services team will be working with the DVR team to refactor the services.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;swaminathan-vasudevan&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;rajeev-grover&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;mbirru&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;michael-smith6&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;vivekanandan-narasimhan&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;L3 Plugin Extension for DVR&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ML2 Plugin/OVS Agent for DVR&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L3 Enhanced Agent for DVR&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L3 Agent Scheduler for DVR&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L3 Driver/iplib for DVR&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;OVS (2.01 and above), L2-Pop.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Yes. Since we are implementing the Distributed Nature of
routers, there need to be multinode setup for testing this
feature so that the rules and actual namespace creation for
the routers can be validated.&lt;/p&gt;
&lt;p&gt;Single node infrastructure to test the feature may still be
possible, but we need to validate.&lt;/p&gt;
&lt;p&gt;Continuous integration testing to test the dvr at the gate
will be considered.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Yes. There will be documentation impact and so documentation
has to be modified to address the new deployment scenario.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/Distributed-Virtual-Router"&gt;https://etherpad.openstack.org/p/Distributed-Virtual-Router&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Meetings/Distributed-Virtual-Router"&gt;https://wiki.openstack.org/wiki/Meetings/Distributed-Virtual-Router&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ovs-distributed-router"&gt;https://blueprints.launchpad.net/neutron/+spec/ovs-distributed-router&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 22 Oct 2014 00:00:00 </pubDate></item><item><title>FWaaS Implementation for Cisco Virtual Router</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/fwaas-cisco.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/fwaas-cisco"&gt;https://blueprints.launchpad.net/neutron/+spec/fwaas-cisco&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Adds support for vendor FWaaS implementation based on the Cisco Virtual
Router.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The Cisco Virtual Router implementation (CSR1kv) also supports the Firewall
Service in addition to Routing. The CSR1kv backend allows a Firewall to be
applied on any of it’s interfaces for a specific direction of traffic. This
blueprint targets neutron support for this use case.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Support of the Plugin and Agent/Driver for the CSR1kv Firewall is being
proposed in this blueprint. There are no changes to any of the Resources from
the Reference implementation. The OpenStack resources are translated to the
backend implementation and the mapping to the backend resources is maintained.&lt;/p&gt;
&lt;p&gt;Supporting the CSR1kv requires:
* Additional vendor attributes to specify firewall insertion points (neutron
port_id corresponding to router interface and associated direction). Although
this is being proposed as vendor extensions, the new framework being proposed
to replace extensions will be adopted or this will evolve to that based on the
timeline of its availability. The “extraroute” approach will be taken to add
the needed attributes of port and direction without any changes to the neutron
client.
* Introduce new table to track insertion points of a firewall resource in the
vendor plugin.
* Interaction with the CSR1kv Routing Service Plugin[1] which is limited to
querying for the hosting VM and some validation for the attached interface.
* Add validators for the attribute extensions to conform to vendor
implementation constraints.
* Agent support for Firewall built on Cisco Config Agent[2] as a service agent
to handle messaging with the plugin along with the messaging interfaces
(firewall dict, plugin API and agent API) mostly along the lines of the
reference implementation.
* Agent to backend communication using existing vendor REST communication
library.&lt;/p&gt;
&lt;p&gt;Implementation is being targeted as a Service Plugin and will be refactored to
align with the Flavor Framework once there is clarity on that effort. Also as
a Vendor Service Plugin, the effort will be refactored or realigned as the
Services split discussions are finalized. Also, if the Service Insertion BP[3]
or similar proposals are resubmitted in Kilo, this effort will be aligned with
the community direction.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;There are no changes planned to existing Firewall resources (FirewallRule,
FirewallPolicy and Firewalls). The insertion point attributes are tracked
by introducing a new table CiscoFirewallAssociation:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;firewall_id  - uuid of logical firewall resource&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;port_id      - uuid of neutron port corresponding to router interface&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;direction    - direction of traffic on the portid to apply firewall on&lt;/dt&gt;&lt;dd&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;can be:&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;ingress&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;egress&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;bidirectional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;No new REST API is introduced.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None to existing. New topic for messaging between the plugin and agent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;Expected to work with IPv6.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Deployer will have to enable the CSR1kv Routing Service Plugin, the Cisco
Config Agent in addition the CSR1kv Firewall Service Plugin being proposed
here. There is no impact to the community implementation when this is not
enabled. The Agent/backend driver is derived from the Service Plugin and
eventually from the flavor and this is messaged with the Config Agent avoiding
the need for a separate .ini file.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;The spec was reviewed and approved in the Juno Cycle. This is proposed as a
Vendor Service Plugin and will be refactored to align with any Community
efforts in this area.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The ideal approach is to base it on the flavor framework and service insertion
BP’s. But given that these are TBD, this is being proposed as a Service Plugin
which will be refactored to align with the community model when available.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;The below figure is a representation of the CSR1kv components and
interactions. The CSR1kv Routing Service Plugin [1] and the Cisco Config
Agent[2] have been upstreamed in Juno. The work being targeted here are the
two items suffixed with a ‘*’ and their interfaces to the existing components.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt;
&lt;span class="o"&gt;+---+---------------------+--------+&lt;/span&gt;             &lt;span class="o"&gt;+-----------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+---------------------+&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Cisco&lt;/span&gt; &lt;span class="n"&gt;Cfg&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;CSR1kv&lt;/span&gt; &lt;span class="n"&gt;Routing&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Agent&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Service&lt;/span&gt; &lt;span class="n"&gt;Plugin&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+---------------------+&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;+------+----+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;^&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;CSR1kv&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;FW&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;+------------------------&amp;gt;|&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="o"&gt;*|&amp;lt;-----+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="n"&gt;v&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;+------+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+------------------&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;--+&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;                           &lt;span class="n"&gt;v&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;CSR1kv&lt;/span&gt; &lt;span class="n"&gt;Firewall&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;                      &lt;span class="o"&gt;+-----------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Service&lt;/span&gt; &lt;span class="n"&gt;Plugin&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;REST&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;lib&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;                      &lt;span class="o"&gt;+-----------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+---------------------+&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;                            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;                            &lt;span class="n"&gt;v&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;                         &lt;span class="o"&gt;+----------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;CSR1kv&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;VM&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------------------------------+&lt;/span&gt;                         &lt;span class="o"&gt;+----------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee: skandasw
Other contributors: yanping&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Service Plugin with vendor extension attributes for the Firewall Resource.
API &amp;amp; DB changes for the vendor specific extensions.
Cisco CSR1kv FWaaS service agent addition to the Cisco config Agent[2].
REST client lib Refactor to work with Cisco FWaaS and VPN implementations.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None. All CSR specific components needed are already upstreamed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests are being added to address the changes.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Tests will be added for Vendor implementations along with CI support.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Tests will be added to validate the CSR FWaaS implementation in association
with the CSR Routing implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Tests will be added for the Vendor extensions being proposed.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Will require new documentation in Cisco sections.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Although API extensions are being proposed, these are vendor extensions and
will be documented accordingly. There are no other consumers of the API
changes.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1]https://blueprints.launchpad.net/neutron/+spec/cisco-routing-service-vm
[2]https://blueprints.launchpad.net/neutron/+spec/cisco-config-agent
[3]https://blueprints.launchpad.net/neutron/+spec/service-base-class-and-insertion&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 21 Oct 2014 00:00:00 </pubDate></item><item><title>OFAgent: Flow-based tunneling</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/ofagent-flow-based-tunneling.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ofagent-flow-based-tunneling"&gt;https://blueprints.launchpad.net/neutron/+spec/ofagent-flow-based-tunneling&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;make ofagent use flow-based tunneling rather than
the current port-based tunneling.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;ofagent creates tunnel ports for each peer nodes.
It’s unscalable and complex.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;use flow-based tunneling, using tun_ipv4_src/tun_ipv4_dst NXMs.
(in addition to tun_id OXM, which is currently used by ofagent)&lt;/p&gt;
&lt;p&gt;Note: while the use of NXMs contradicts to the one of goals of
ofagent, i.e. being portable to other switch implementations,
it isn’t a problem right now because:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;the tunneling support is OVS-dependent anyway&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;i’ve heard that the future versions of OpenFlow aims to the same direction.
there seems to be no publically available reference for this, though.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;code would get simpler and easier to maintain.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;yamamoto&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;kakuma&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;tweak L2populationRpcCallBackTunnelMixin api so that it can handle
the “a single tunnel port for many networks” situation more naturally&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tweak how ofagent sets up tunnel ports&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tweak ofagent flows accordingly&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;ideally multi-node testing is necessary.
however i don’t plan to cover it by this blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;no api change thus no additional tests.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;should document new requirement (ryu&amp;gt;=3.15) for relevant NXMs support&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;the current implementation of this blueprint:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/130676/"&gt;https://review.openstack.org/#/c/130676/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/130677/"&gt;https://review.openstack.org/#/c/130677/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;as far as i know, NXMs are only documentated in Open vSwitch
source code:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openvswitch/ovs/blob/e9bbe84b6b51eb9671451504b79c7b79b7250c3b/lib/meta-flow.h#L335"&gt;https://github.com/openvswitch/ovs/blob/e9bbe84b6b51eb9671451504b79c7b79b7250c3b/lib/meta-flow.h#L335&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openvswitch/ovs/blob/e9bbe84b6b51eb9671451504b79c7b79b7250c3b/lib/meta-flow.h#L353"&gt;https://github.com/openvswitch/ovs/blob/e9bbe84b6b51eb9671451504b79c7b79b7250c3b/lib/meta-flow.h#L353&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 15 Oct 2014 00:00:00 </pubDate></item><item><title>Report HA Router Master</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/report-ha-router-master.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/report-ha-router-master"&gt;https://blueprints.launchpad.net/neutron/+spec/report-ha-router-master&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Highly available routers is a new functionality that was merged in the
l3-high-availability blueprint. HA routers are scheduled on multiple L3 agents
however the cloud operator has no way of knowing where the active instance
is.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;A cloud operator can know which L3 agents are providing a router, but not
where the active instance is. Legacy routers may be manually moved from
one agent to another. With HA routers, the equivalent is moving the active
instance, but that is not currently possible.
The first step is to know where the active instance, which will be addressed
in this blueprint, however setting the location of the active instance is
out of scope and will be addressed in the future.&lt;/p&gt;
&lt;p&gt;The operator might want to perform node maintenance which is assisted by
manually moving routers from the node. Likewise the operator might want
to see the state of routers after a failover (Did the active instance
actually failover?).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;l3-agent-list-hosting-router &amp;lt;router_id&amp;gt;&lt;/p&gt;
&lt;p&gt;Currently shows all L3 agents hosting the router. It will now also show the HA
state (Active, standby or fault) of said router on every agent.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+-----------+------+----------------+-------+----------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;admin_state_up&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;alive&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ha_state&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------+------+----------------+-------+----------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;534&lt;/span&gt;&lt;span class="n"&gt;c4b37&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;net1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;da2730c6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;net2&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;standby&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="n"&gt;abcd991&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;net3&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;xxx&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;fault&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------+------+----------------+-------+----------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Keepalived doesn’t support a way to query the current VRRP state.
The only way to know then is to use notifier scripts.
These scripts are executed when a state transition occurs,
and receive the new state (Master, backup, fault).&lt;/p&gt;
&lt;p&gt;Every time we reconfigure keepalived (When the router is created or updated)
we tell it to execute a Python script
(That is maintained as part of the repository).&lt;/p&gt;
&lt;p&gt;The script will:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Write the new state to a file in $state_path/ha_confs/router_id/state&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Notify the agent that a transition has occurred via a Unix domain socket.
The reason that step 1 will happen in the script and not in the agent after
it receives the notification is that we want to write down the state
transition whenever it happens so that it isn’t lost if the agent is down.
keepalived does not expose a way to query for the current state, so that
if a state transition occurred but we failed to write it down, that
information is forever lost.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The L3 agent will start and stop the metadata proxy when it receives a
notification. This is to save on memory usage by enabling the proxy
only on the active instance. This can be important at scale as every
proxy takes 20+ MBs.&lt;/p&gt;
&lt;p&gt;The L3 agent will batch these state change notifications over a period of T
seconds. When T seconds have passed and no new notifications have arrived it
will send a RPC message to the server with a map of router ID to VRRP state
on that specific agent. How it works is that once an event is received
by the agent, it batches all future events over a period of T seconds. When
the timer goes off, it sends all of the state changes in a single message
to the controller. Additionally, every time the agent starts it gets a list
of routers scheduled on the agent. The agent will now loop through said
routers, collect their HA states from disk and update the server.
This is to catch any state changes that occurred if and when an agent was down.
If a router changes states multiple times during the batching period, the
agent will only send the most up to date state.&lt;/p&gt;
&lt;p&gt;The RPC message send will be retried in case the management
network is temporarily down, or the agent is disconnected from it.&lt;/p&gt;
&lt;p&gt;The server will then persist this information following the RPC message:
The tables are already set up for this. Each router has an entry in the HA
bindings table per agent it is scheduled to, and the record contains the
VRRP state on that specific agent. The controller will also persist
the last time a state change was received, so that in a split brain situation
the admin would be able to understand which is the ‘real’ master by observing
the time stamps.&lt;/p&gt;
&lt;p&gt;Optionally*, the server will look for dead agents (That have not sent
heartbeats in a while) and will mark their HA routers as down. This will
aid the main use case of a hypervisor dying (Of course not being able
to report of any state changes), and another hypervisor hosting all of the
routers. In this case the API will return ‘active’ for all routers on both
machines until the server notices that the first agent died and marks
its routers as down.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This is an optional enhancement that could be added after the enhancement
lands if we find it correct.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;The HA state of every router to agent binding is persisted in the
L3HARouterAgentPortBinding table. It is currently unused. A DB migration
will be necessary in order to add time stamps as well as the ‘fault’
state, as currently only the ‘active’ and ‘standby’ can be persisted.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;l3-agent-list-hosting-router will now return an extra column that can be
‘active’, ‘standby’ or ‘fault’ for HA routers, or None for other types of
routers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;keepalived runs as root, as does the transition script that it invokes.
The transition script talks to the agent via a Unix domain socket.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;python-neutronclient will support the new ha_state column. It will show
‘active’, ‘standby’ or ‘fault’ when a proper response is received. ‘-’ will be
displayed if None is received by an old server or for non-HA routers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Assuming two L3 agents and 1,000 routers hosted on each, a failover from node
1 to node 2 should induce only a single RPC call from node 2 to the server,
and a single DB transaction.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Instead of neutron-keepalived-state-change notifying the agent via a Unix
domain socket, the agent could poll for the state of all HA routers every
T seconds. It would then diff the new states against a cached copy
and notify the server of any changes. One could argue that this is simpler
to implement and maintain, but is less performant.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Assaf Muller &amp;lt;amuller&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Current keepalived notifier bash scripts are generated in-line. These will
now be a Python script maintained as part of the repository. The script
will be available as neutron-keepalived-state-change and will be invoked
by keepalived.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;At first the script will replicate the existing behavior of the bash
scripts: Write the new state to disk and start up or shut down the metadata
proxy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The script must also notify the agent of the state change via a Unix domain
socket. Starting and stopping the metadata proxy will be moved ot the agent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The RPC message that updates HA routers states will be implemented (It
currently actually already exists but cannot be used without changing
its format).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The agent will batch up state change notifications in to a single RPC
message. The Nova notifier mechanism batches notifications and the code
will be reused.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The API must expose the new ha_state column.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The L3 agent must report HA states after it starts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the fault state and state change timestamp via a DB migration patch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Optional: The controller will look for dead agents and move their HA routers
to the fault state.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;L3 HA cannot be tested in Tempest without multi-node support. L3 HA is the
first candidate to be tested when in-tree integration tests are introduced
via the integration-tests blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;The L3 agent already has functional testing in place. Two new tests will
be added:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;When a state change occurs, that the notification arrives at the agent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When multiple state changes occur, that the RPC call is sent to the server
with the expected parameters.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;The RPC and DB methods will be tested with unit tests.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The changes to the API and CLI require documentation.&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;The CLI client documentation must be updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;The Neutron API change must be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Topic branch:
&lt;a class="reference external" href="https://review.openstack.org/#/q/branch:master+topic:bug/1365453,n,z"&gt;https://review.openstack.org/#/q/branch:master+topic:bug/1365453,n,z&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/l3-high-availability"&gt;https://blueprints.launchpad.net/neutron/+spec/l3-high-availability&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1365453"&gt;https://bugs.launchpad.net/neutron/+bug/1365453&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 15 Oct 2014 00:00:00 </pubDate></item><item><title>Allow to specify floating IP address</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/allow-specific-floating-ip-address.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/allow-specific-floating-ip-address"&gt;https://blueprints.launchpad.net/neutron/+spec/allow-specific-floating-ip-address&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;IP Address of floating ip is automatically allocated from IP pool.&lt;/p&gt;
&lt;p&gt;In some cases, user want to specify a IP Address of floating ip.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Adding the floating ip address as an attribute to the API for creating floating ip. An attribute name is floating_ip_address.&lt;/p&gt;
&lt;p&gt;Attributes of API are limited by “policy.json”. By default, Non-admin user cannot use floating_ip_address. Admin can use it. (“rule:admin_only”)&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;floating_ip_address will be allowed to POST /v2.0/floatingips&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is not updatable. i.e. cannot use for PUT /v2.0/floatingips&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The attribute map will be changed as the following.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="s1"&gt;'floatingips'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="s1"&gt;'floating_ip_address'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:ip_address_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                                &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="s1"&gt;'enforce_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;An administrator of OpenStack should consider whether this feature is exposed to tenant user.&lt;/p&gt;
&lt;p&gt;If users have a permission to use this feature, Users can control public ip addresses.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;fujioka-yuuichi-d&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Add attribute to API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create test case on tempest&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;The following tests will be added.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;API Testing&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Allowed users can use the new parameter&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scenario Testing&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A created floating ip address is reachable&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;The following tests will be added.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Allowed users can use the new parameter&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;The following tests will be added.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;All patterns that parameter is passed/not passed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;New attributes will be added to API documentation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/70286/"&gt;https://review.openstack.org/#/c/70286/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 07 Oct 2014 00:00:00 </pubDate></item><item><title>Allow compute port mac_address to be updated</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/mac_addr_update.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/allow-mac-to-be-updated"&gt;https://blueprints.launchpad.net/neutron/+spec/allow-mac-to-be-updated&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ironic servers can experience a nic failure which requires nic replacement.
The replacement nic can have a new mac address.  There is currently no way to
handle this situation without the potential of losing the IP address.&lt;/p&gt;
&lt;p&gt;See also bug [2].&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Because the ‘mac_address’ attribute of port is not updatable, replacing a nic
on an ironic server today requires deleting the associated neutron port and
creating a new one with the correct mac address.  This can result in the server
losing its IP address to another port being created at the same time.&lt;/p&gt;
&lt;p&gt;This spec does not seek to retain the same IPv6 SLAAC address when mac address
changes.  Such addresses are expected to change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Change server code to allow the mac_address attribute of the port resource to
be updated.  Specifically, enable this feature for the ml2 plugin.  Any
work to be done to other plugins will be addressed in other specs.&lt;/p&gt;
&lt;p&gt;In the base plugin, restrict mac_address update to compute ports only
(non-compute ports require more changes and are not covered by the use cases
handled here).  The use cases don’t require an active port, so in the ml2
plugin, we require that the port not be ‘plugged’: vif_type must be
BINDING_FAILED or UNBOUND.  Note that for ironic servers, vif_type is always
BINDING_FAILED, so mac_address can always be changed for those ports.  This may
at some point be viewed as a bug however, so any fix to that bug will need to
account for this feature.  For ‘normal’ VMs, the life cycle of binding:vif_type
depends on the backend.  The l2pop mech driver is updated to change the fdb
table entries appropriately.&lt;/p&gt;
&lt;p&gt;In the OVS L2 agent, send a gratuitous arp when a mac_address change is
detected.&lt;/p&gt;
&lt;p&gt;The allowed_address_pairs extension allows for the mac_address of any pair to
default to port.mac_address.  This implies that there are cases where updating
the port’s mac_address should also update the allowed_address_pair mac_address.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;Modify the ‘allow_put’ property of the ‘mac_address’ attribute in the ‘ports’
entry of the RESOURCE_ATTRIBUTE_MAP from False to True.  The policy.json file
is modified to add rules for “update_port:mac_address” - the same rules are
used as for “create_port:mac_address” except network owner is not allowed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;To be conservative for now, this feature will be restricted by default to the
following.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;admin role&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;advsvc role&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The user can adjust policy.json as always, if desired.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;Introduces a new case where notifications are issued, but does not add a new
notification or modify or remove any existing notification.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The performance impact when mac_address is changed during a port update are
characterized in the following list.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The impact should be the same as that of changing the ip address.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For dvr environments, adds the overhead of VM arp table updates for all
routers on the network.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;No IPv6-specific issues are expected.  When a mac address changes, the SLAAC
address, if any, will change also, but since such addresses are dynamic, that
should be fine.  Domain name servers will need to start vending the new
address, and the current code should handle the AAAA record update to OpenStack
DHCP servers.  If the subnet’s DHCP is not enabled, the propagation of the new
address to external DNS servers is out of scope.  The link local address also
changes, but that is also fine.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;Deployers can now replace nics in ironic servers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;Non-ml2 plugin developers need to decide whether mac_address updates can be
allowed or are desirable in their environment.  The normal development process
should take place to deal with the fact that the neutron api and the base
plugin now allow mac address update.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;Integrates well with ironic: in addition to nic replacement, some nics have
changeable mac addresses, so the ability to change the mac_address of a port
seems useful.&lt;/p&gt;
&lt;p&gt;There hasn’t been much discussion yet, aside from review comments against the
implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;1. If fixed_ips were a separate resource (similar to floating_ips, and vaguely
referred to in [4]), then the tenant could retain ownership of ip address while
the port was deleted and re-created with the new mac address.  This would
require a large change to the data model, which may not be justified by the
requirements of this spec.  This also puts the burden of relating ip address
and mac address on the client, along with the various failure scenarios that
would have to be handled without the benefit of transactions.  Seems like a
bigger win to do the proposed relatively small change in the server and remove
some complexity from clients.&lt;/p&gt;
&lt;p&gt;2. Another thought was to use DHCP client id instead of mac address in the dhcp
protocol.  Then the mac address becomes irrelevant to the ip address lookup,
and replacing the card would have no affect on the IP address assigned.
However, based on a quick discussion with the Ironic team [3], there is a hard
need to have the port mac_address match the hardware’s mac address.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;ChuckC  (Chuck Carlino)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Work items related to neutron core.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Review [1]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Baremetal scenario testing to cover nic replacement&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;allowed_address_pairs support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API tests&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Vendor plugin work items are out of scope.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Add tempest test cases to cover mad address update.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;VM mac address update verifying connectivity&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;baremetal nic replacement&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Add tests updating a port’s mac_address and validate that the following
are appropriately updated/notified.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;DHCP agents&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;security group rules&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;allowed_address_pairs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Since this feature involves an api change, we plan to add tests to validate the
update of port’s mac_address.  If, at the time of implementation, neutron API
tests include negative test cases and tests of policy.json, then those will be
added for this feature as well.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Need to document that it is now permitted to update the mac_address of
an unbound or failed VM port.&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;The following documents and sections may need updating.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Cloud Administrator Guide&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Core Networking API features&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron/APIv2-specification (Port table)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://review.openstack.org/112129"&gt;https://review.openstack.org/112129&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[2] &lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1341268"&gt;https://bugs.launchpad.net/neutron/+bug/1341268&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[3] &lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2014-November/050329.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2014-November/050329.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[4] &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-ipam"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-ipam&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 07 Oct 2014 00:00:00 </pubDate></item><item><title>Support for Extensions in ML2</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/neutron-ml2-mechanismdriver-extensions.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/extensions-in-ml2"&gt;https://blueprints.launchpad.net/neutron/+spec/extensions-in-ml2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint defines a pluggable framework for extending core resource
attributes in ML2.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;In the current ML2 plugin implementation, only the extensions defined in the
Ml2Plugin class itself are available, and there is no way for core resources to
be extended with attributes needed by specific mechanism drivers. When such
extensions are needed, whether for new general purpose features that might be
incorporated in future core API versions, or to better support specific
networking technologies, the only current option is to implement a new
monolithic plugin.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This proposal adds support to ML2 for extension drivers, which manage extended
attributes on the neutron core resources implemented by the ML2 plugin:
network, subnet and port.&lt;/p&gt;
&lt;p&gt;The extension drivers are completely orthogonal to mechanism drivers. An
operator configures some set of extension drivers and configures some other set
of mechanism drivers. The set of extension drivers configured determines what
extended attributes are present on the core resources. These extension drivers
manage setting, defaulting, updating and returning persistent values for these
extended attributes. The values of these extended attributes are then available
to all the configured mechanism drivers and they do not vary depending on which
mechanism driver is using the extended attributes.
If a mechanism driver understands an extension, it can enforce its semantics.
If not, it just ignores those extended attributes.&lt;/p&gt;
&lt;p&gt;Each mechanism driver that requires a vendor-specific extension would have its
own extension driver. There may also be “community” extension drivers, where
several different mechanism drivers might be able to enforce the extension’s
semantics.&lt;/p&gt;
&lt;p&gt;What follows describe changes in ML2 to define extension drivers and provide
support for extensions in ML2 mechanism drivers:&lt;/p&gt;
&lt;p&gt;1. Introduce ExtensionDriver API and ExtensionManager (similar to
MechanismDriver and MechanismManager).&lt;/p&gt;
&lt;p&gt;2. Define new configuration parameter which contains list of extension drivers
to load (i.e. extension_drivers).&lt;/p&gt;
&lt;p&gt;3. ExtensionDriver - Abstract class that defines the following interfaces for
ML2 extension drivers:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;initialize: Abstract method - Perform extension driver initialization&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;extension_alias: Abstract property - Return supported extension aliases&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;process_create_network: Process extended attribute for create network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;process_create_subnet: Process extended attribute for create subnet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;process_create_port: Process extended attribute for create port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;process_update_network: Process extended attribute for update network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;process_update_subnet: Process extended attribute for update subnet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;process_update_port: Process extended attribute for update port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;extend_network_dict: Add extended attributes to network dictionary&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;extend_subnet_dict: Add extended attributes to subnet dictionary&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;extend_port_dict: Add extended attributes to port dictionary&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;4. ExtensionManager - Manages loading and initializing extension drivers
similarly to the existing TypeManager and MechanismManager classes.
Provides methods that dispatch to the ordered list of registered extension
drivers for each of the process_create_&amp;lt;resource&amp;gt;, process_update_&amp;lt;resource&amp;gt;,
and extend_&amp;lt;resource&amp;gt;_dict abstract operations defined on ExtensionDriver.&lt;/p&gt;
&lt;p&gt;5. Ml2Plugin will initialize the ExtensionManager at startup, which will load
and initialize the configured ExtensionDrivers.&lt;/p&gt;
&lt;p&gt;6. Change Ml2Plugin’s supported_extension_aliases abstract property to include
the extension_alias property of each registered ExtensionDriver.&lt;/p&gt;
&lt;p&gt;7. In resource’s create and update (i.e. network, port, subnet in Ml2Plugin)
before calling the pre/post_commit, process_create/update in extension
driver should be called to validate and persist any extended resource’s
attributes defined by driver. Extended attribute must also be returned.&lt;/p&gt;
&lt;p&gt;8. In each case where dictionaries are built by Ml2Plugin for network, subnet,
and port resources, the ExtensionManager’s extend_&amp;lt;resource&amp;gt;_dict function will
be called so that the registered ExtensionDrivers can add their extended
attributes.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Link below contains discussion on this subject in icehouse summit:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/icehouse-neutron-vendor-extension"&gt;https://etherpad.openstack.org/p/icehouse-neutron-vendor-extension&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Also, alternative of implementing extensions directly in mechanism drivers was
considered, but was rejected for various reasons, including no way to return
extended attributes from get operations&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;ExtensionDriver implementations will add tables to store their extended
attributes, but no ExtensionDrivers are included in the BP.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Core resource extensions will now be possible with ML2, similar to what has
previously been possible with monolithic plugins.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;If a mechanism driver needs to add extended attribute to a resource, it needs
to create an extension driver (based on ExtensionDriver API) and add the name
to the setup.cfg and ml2_conf.ini.
The name of extension and path to the extension should be added in the
extension driver.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Nader Lahouti (nlahouti)&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;ExtensionManager - new implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ExtensionDriver - new implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new method in Ml2Plugin class for adding supported extensions in
mechanism driver to supported extension in the class.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Invoke extension driver’s method (e.g. process_create resource) in
create/update/delete_&amp;lt;resource’s name&amp;gt; to add/update/delete attribute in
persistent table.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The regular test for plugin still applies here. But new unit tests will be
added with a test ExtensionDriver that verifies that extended attributes are
properly processed in create and update operations, returned from create,
update, and get operations, and available from within MechanismDriver methods.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The ExtensionDriver API will include docstrings describing the new API, so
generated documentation will cover it. Will need to update deployment docs for
the new config variable. Will mainly be covered by vendor docs whose mechanism
drivers require extension drivers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 14 Aug 2014 00:00:00 </pubDate></item><item><title>Configuration Agent for Cisco Service VMs</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/cisco-config-agent.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/cisco-config-agent"&gt;https://blueprints.launchpad.net/neutron/+spec/cisco-config-agent&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint covers the Cisco configuration agent that is responsible for
configuring Cisco service VMs to implement network services. This agent is
meant to be generic and intended to support multiple services. But initially it
will cover only routing and NAT services in CSR1kv Service VM. The design of
this agent is inspired by the current L3 agent which configures neutron routers
in Linux namespaces.&lt;/p&gt;
&lt;p&gt;This blueprint depends on the blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/cisco-routing-service-vm"&gt;https://blueprints.launchpad.net/neutron/+spec/cisco-routing-service-vm&lt;/a&gt;
which implements the plugin side.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;There are use cases for Neutron services implemented using Service VMs.
CSR1kv is one such service VM that can implement a variety of network
services like routing, NAT, firewalls, VPNs, etc.&lt;/p&gt;
&lt;p&gt;The configuration agent proposed here will connect to and configure a CSR1kv VM
for implementing Neutron routers. Neutron routers are configured inside the
CSR1kv VM as VRFs. The agent will also configure NAT and floatingIP
functionality for external gateways.&lt;/p&gt;
&lt;p&gt;Use Cases:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Implement and configure Neutron routers via service VMs.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This change will introduce a Cisco configuration agent (here after called the
config agent) similar to the current L3 agent, but for service VMs.&lt;/p&gt;
&lt;p&gt;The diagram below provides a high level overview of how the config agent
fits in with other components and its north and sound bound interfaces.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;+––––––––––––––––––––+
|cisco routing       |
|service plugin      |
+–––––––––+––––––––––+
          |
          |
+–––––––––+––––––––––+
|cisco configuration |
|agent               |
+–––––––––+––––––––––+
          |
+–––––––––+––––––––––+
|service VM          |
|(CSR1kv)            |
+––––––––––––––––––––+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that unlike the l3 agent, the config agent can manage and configure
multiple devices. There can be one or more config agents in the system.
The plugin will divide the total number of devices (to manage) among these
agents. But at any given time, a service VM is configured by one and only one
config agent. This assignment is done by the plugin.&lt;/p&gt;
&lt;p&gt;The config agent can be run in any node, even including the controller/network
node as long as it can reach the devices.&lt;/p&gt;
&lt;section id="failure-handling"&gt;
&lt;h3&gt;Failure handling&lt;/h3&gt;
&lt;p&gt;Config agents implement the agent state reporting framework and send status
reports periodically. This mechanism is also used to detect a failed agent.
In case of a failed agent, the service VM and the services configured in it is
transferred to a different config agent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="assumptions"&gt;
&lt;h3&gt;Assumptions&lt;/h3&gt;
&lt;p&gt;The service VMs are owned and managed by the cloud admin. They are not visible
to the tenants. They are connected to a management network which is mapped to a
provider network in neutron. This management network can be seperate from the
openstack management network. Also the VM which provides the network service is
considered as a trusted VM which the admin can safely connect to his management
network.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="design"&gt;
&lt;h3&gt;Design&lt;/h3&gt;
&lt;p&gt;The config agent has a modular design with a number of components.
They are:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Plugin RPC: Handle the communication towards the plugin side.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Device driver: Configuration logic for individual device(s). Also
encapsulates the configuration protocol. e.g: Netconf or REST.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Service helper: Encapsulates the logic for any bookkeeping operation or
intermediate conversions, before calling the driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Health monitoring: Monitor the state of the device(s) being configured and
report unreachable device(s) back to plugin.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Components:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;+––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+
|                                                            |
|                     +————————+                             |
|                    +—––––––+ |                             |
|                    |Plugin | |                             |
|                    |RPC    +—+                             |
|                    +–––––––+                               |
|    +––––––––––+                     +––––––––––––––––+     |
|    |Health    |                     |(routing)       |     |
|    |Monitoring|    Config agent     |service helper  |-+   |
|    +––––––––––+                     +-–––––––––––––––+ |   |
|                                      +_________________+   |
|                                                            |
|                   +–––––––+                                |
|                   |Device |                                |
|                   |Driver |—+                              |
|                   +——–––––+ |                              |
|                    +––––––——+                              |
|                                                            |
+––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When additional services are added, they can add their own Plugin RPC, service
helper and device driver. Also, a service can have more than one device driver
too. The device driver to be used to configure for a particular device is
specified by the plugin as part of the resource dict in the RPC message.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative solution would be to configure the devices (service VMs)
directly from the service plugin. Though possible, this increases the load on
the plugin which is also responsible for the API and DB components too.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;The config agent does not use persistence. Hence no new models are added.
All existing models are unchanged.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Having a seperate config agent for configuration tasks and health monitoring
reduces load on the neutron server, when compared to doing this from the plugin
directly. Secondly, since the config agent need not be colocated with the device
it configures and can manage multiple devices, agent state reporting traffic to
neutron server is reduced, compared to the l3 agent.&lt;/p&gt;
&lt;p&gt;Since the config agent orchestrates how configurations for multiple services are
applied in a device, the control plane load on the device is reduced and
the risk of mis-configuration states is alleviated.&lt;/p&gt;
&lt;p&gt;The config agent makes use of device drivers, which themselves uses Netconf,
REST APIs etc., to configure devices. These mechanisms need to connect and
authenticate with the device and establish a session before configurations can
be made. Session establishment adds an additional but necessary overhead.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The service VMs have a management port which is connected to a management
network. The config agent connects to the devices over this management network
and hence the host where it is running should have connectivity to this network.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None. The routing service helper exposes the same RPC methods as the reference
l3 agent maintaining backward compatibility.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Hareesh Puthalath &amp;lt;hareesh-puthalath&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The work is split up into two parts:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The config agent itself.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Routing service driver for CSR1kv.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;There are no new library requirements.
It does depend on a modified service plugin referred in the blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/cisco-routing-service-vm"&gt;https://blueprints.launchpad.net/neutron/+spec/cisco-routing-service-vm&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Complete unit test coverage of the code is included.&lt;/p&gt;
&lt;p&gt;For tempest test coverage, third party testing will be provided. The Cisco
CI reports on all changes affecting the config agent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None directly.
Though documentation needs to indicate how to use the config agent, if desired.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.cisco.com/c/en/us/products/routers/cloud-services-router-1000v"&gt;http://www.cisco.com/c/en/us/products/routers/cloud-services-router-1000v&lt;/a&gt;-
series/index.html&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 04 Aug 2014 00:00:00 </pubDate></item><item><title>DHCP Service LoadBalancing Scheduler</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/dhcpservice-loadbalancing.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/dhcpservice-loadbalancing"&gt;https://blueprints.launchpad.net/neutron/+spec/dhcpservice-loadbalancing&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;With the current Agent Management and Scheduler extensions we are not able to
effectively distribute the DHCP namespaces when there are multiple Network
Nodes available. Existing scheduler(Chance Scheduler) does not load balance
the DHCP namespace properly across multiple Network Nodes based on the network
load of DHCP agents.&lt;/p&gt;
&lt;p&gt;Chance scheduler schedules DHCP namespaces unevenly, which is not suitable when
large number of namespaces are created.
Chance scheduler schedules around 90% of DHCP namespaces on a single Network
Node and remaining 10% of namespaces are distributed across remaining Network
Nodes.&lt;/p&gt;
&lt;p&gt;This blueprint attempts to address this issue by proposing a new DHCP agent
scheduler which will equally distribute the DHCP namespaces across multiple
Network Nodes based on DHCP namespace count of the DHCP agent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;In the Neutron server, we have written a DHCP agent scheduler which will
keep track of the DHCP services running on the Network Nodes based on the
“network_scheduler_driver” configuration of ‘neutron.conf’.&lt;/p&gt;
&lt;p&gt;‘LeastNetworksScheduler’ type of DHCP scheduler will be triggered only if the
“network_scheduler_driver” parameter is set to LeastNetworksScheduler.
The default value for this flag is ‘ChanceScheduler’.&lt;/p&gt;
&lt;p&gt;When the new network is created the DHCP agent scheduler will fetch the dhcp
agents with minimum number of networks hosted on it. And schedules the newly
created DHCP namespace service on those minimally loaded DHCP agents.&lt;/p&gt;
&lt;p&gt;Here the dhcp agent load is decided based on the number of DHCP namespaces
which are already created on the dhcp agent. ‘LeastNetworksScheduler’ will
return as many number of minimally loaded DHCP agents as mentioned in
‘dhcp_agents_per_network’ configuration parameter.&lt;/p&gt;
&lt;p&gt;In this implementation the DHCP namespace count is calculated based on report
status messages received from DHCP agents.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;A new column named “load” will be added in the “Agents” table. This column
contains the Agent load based on the DHCP namespaces count which are hosted
on that particular agent. The table will be sorted based on the load and least
loaded top n Agents will be supplied for scheduler to host the DHCP namespaces.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;This feature can be enabled by setting the flag network_scheduler_driver =
LeastNetworksScheduler which is configurable from “neutron.conf”. If the flag
is set to ChanceScheduler, none of this code will be executed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;praveen-sm-kumar&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;shiva-m&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Highlevel tasks include:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Refactor the code of ChanceScheduler and introduce new class named
LeastNetworksScheduler
This activity includes moving the common methods to parent class named
DHCPScheduler and inheriting those methods in ChanceScheduler and
LeastNetworksScheduler classes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LeastNetworksScheduler
This class will have the implementation to get the dhcp agents which is
hosting least number of networks. Subsequently it will schedule the
respective DHCP namespace services on those minimally loaded DHCP agents.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Will reuse few methods from current scheduler classes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The code will be covered with unit tests.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Will be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Current documentation will have to be enhanced to add the content specific to
DHCP service load balancing scheduler.&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Scheduler section of Openstack Configuration Reference document needs to be
modified.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;The code has been submitted for review at the below link
&lt;a class="reference external" href="https://review.openstack.org/#/c/137017"&gt;https://review.openstack.org/#/c/137017&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 01 Aug 2014 00:00:00 </pubDate></item><item><title>Remove the use of resource autodeletion in unit tests</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/remove-unit-test-autodeletion.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/remove-unit-test-autodeletion"&gt;https://blueprints.launchpad.net/neutron/+spec/remove-unit-test-autodeletion&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint describes the rational for removing resource
autodeletion in the unit tests.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The Neutron unit tests currently decorate resource creation methods
with contextlib.contextmanager to allow resources to be automatically
deleted when they are no longer needed.  This strategy is a legacy of
a time when this explicit cleanup was required to ensure isolation
between tests, but is now unnecessary since db state is automatically
thrown away after each test.  The strategy has the following negative
impacts on much of Neutron’s unit test suite:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;an execution penalty, since deletion of every created resource is
always done and is performed through the wsgi layer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;a debugging penalty, since contextmanagers are generators with the
consequent loss of stack context&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;a readability penalty, since the test code is riddled with
unnecessary ‘with’ blocks around resource creation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;a coverage penalty, since implicit deletion testing is likely to
hide gaps in testing of resource deletion&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Resource creation methods should be modified to not perform
autodeletion, as follows:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;remove the contextlib.contextmanager decorator&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;change ‘yield’ statements to ‘return’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;remove the do_delete or no_delete parameter&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;remove the conditional block that deletes the resource(s)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition, all clients of the resource creation methods should be
updated to no longer pass a do_delete/no_delete parameter and perform
a regular call (e.g. create_resource()) rather than creating a with
block (e.g. with create_resource():).  It also may make sense to
update the names of resource creation methods, since they are often of
the form ‘resourcename’ rather than ‘create_resourcename’.&lt;/p&gt;
&lt;p&gt;Care will have to be taken to ensure that explicit tests for deletion
are added if they do not already exist for a given resource type.
Autodeletion ensured that any resource whose creation was tested also
had its deletion validated to some extent, but this validation will
have to be explicit from now on.  This is arguably desirable, since
relying on the ‘magic’ of autodeletion to provide test coverage can
potentially lull developers into a false sense of security.&lt;/p&gt;
&lt;p&gt;There may also be tests that create multiple resources in a way that
depended on autodeltion to prevent uniqueness constraint violation.
It will be necessary to perform explicit deletion in those cases where
removal of autodeletion provokes test failures.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The alternative to not removing autodeletion is continuing to live
with the penalties it imposes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Removal of autodeletion should have a positive impact on the execution
time of the unit test suite.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developers and reviewers familiar with the current
contextmanager-based model of resource creation in unit tests will
have to be educated as to the move to simpler creation methods and the
need for explicit testing of deletion.&lt;/p&gt;
&lt;p&gt;Once concern voiced at the removal of the contextmanager decorator was
that it would disallow the convenience of managing the lifecycle of
multiple resources via contextlib.nested.  If necessary, this
capability can be replicated by creating a helper method that accepts
a list of creation functions and ensures that the resources created
are cleaned up.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;kevinbenton&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;marun&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Add explicit tests for deletion for resource types that have
previously relied on autodeletion to perform implicit testing of
deletion.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Disable autodeletion in each resource creation method
(e.g. NeutronDbPluginV2TestCase.network) in the unit test suite
and fix any test failures that result.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove support for autodeletion (parameters, deletion calls) from
the resource creation methods and update their callers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove the contextmanager decorator from resource creation
methods, rename the creation methods (e.g. network -&amp;gt;
create_network), and update their clients.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 11 Jul 2014 00:00:00 </pubDate></item><item><title>Big Switch - Convert L3 functions to L3 Service plugin</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/bsn-l3-service-plugin.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/bsn-l3-service-plugin"&gt;https://blueprints.launchpad.net/neutron/+spec/bsn-l3-service-plugin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Move the L3 functions from the Big Switch monolithic plugin to a separate L3
service plugin so the fabric can provide L3 functionality for ML2 or the Big
Switch Plugin from one common code base.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;There is no way to use the Big Switch L3 features when using the Big Switch
ML2 driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Remove the L3 functions from the Big Switch core plugin and put them into an
L3 service plugin. This will allow the Big Switch backend to provide L3 service
when using the Big Switch plugin or the ML2 driver.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Database migration for L3 tables will be needed for new service plugin.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;An L3 service plugin configuration will be required for the BSN core plugin.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;kevinbenton&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Separate code into L3 service plugin module&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Re-organize BSN L3 tests into separate code from current unit test files&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;This will be completed after the L3 offload functionality is done since that
will require more L3 factoring and is a higher priority.[1]&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The current unit tests and 3rd party CI will cover this change since no
new features are being added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The service plugin will have to be referenced in the configuration guide for
the Big Switch plugin and the Big Switch ML2 agent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/bsn-blended-l3-agent"&gt;https://blueprints.launchpad.net/neutron/+spec/bsn-blended-l3-agent&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description><pubDate>Thu, 10 Jul 2014 00:00:00 </pubDate></item><item><title>FWaaS changes to support Distributed Virtual Router(DVR)</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/neutron-dvr-fwaas.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-dvr-fwaas"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-dvr-fwaas&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;As we move to the DVR model, current L3 based services such as FWaaS that rely
on seeing both sides of the traffic on the same namespace router are broken.
The reference implementation of FWaaS is built on iptables and is stateful in
that connections are tracked. DVR by intent distributes the routing
functionality across instances on compute nodes and all traffic is no longer
routed through a centralized router to achieve goals of scalability.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;To maintain FWaaS functionality in the context of a DVR deployment the first
step (which is being targeted in this proposal)  is to ensure that we can
preserve current perimeter Firewall functionality (North - South) and ensure
that the manner in which rules are applied does not break normal DVR
East - West traffic flow.&lt;/p&gt;
&lt;p&gt;DVR[1] classifies North - South traffic into two categories:&lt;/p&gt;
&lt;p&gt;Default SNAT use case - traffic flowing out to the external network will go
through the Network/Service Node, and the SNAT Namespace hosted there, to get
out. Response traffic will again go thru the SNAT Namespace for translation
and is then directly switched to the appropriate VM in a Compute Node.&lt;/p&gt;
&lt;p&gt;VMs with Floating IPs(FIP) use case - traffic flowing out will go through the
Internal Router for routing and translation and then through the FIP Namespace
on the Compute Node to the external network through its br-ex. And on the
incoming traffic, again the flow is through the br-ex on the Compute Node,
then the FIP Namespace and through the Internal Router which also handles
translation to the VM.&lt;/p&gt;
&lt;p&gt;DVR runs L3Agent on the Network Node as well as on the Compute Nodes. Since
the FWaaS Agent runs in the context of the L3Agent, the FWaaS Plugin to Agent
messaging is already available. In the context of both of the above use cases,
FWaaS Agent on the Network/Service Node should install the Firewall Rules in
the SNAT Namespace, and the FWaaS Agent in the Compute Nodes should install
the Firewall Rules in the IR Namespace to be applied on traffic flowing
through the FIP Namespace (to ensure that there is no effect on East - West
flows). In this manner, the FWaaS requirement of seeing traffic on both
directions is satisfied for both of these use cases. FWaaS Agent can use the
agent_mode configuration option to determine whether it is on a
Network/Service node or Compute node to make the determination on how to
install the rules.&lt;/p&gt;
&lt;p&gt;The SNAT interfaces are prefixed with ‘sq-’ in the SNAT namespace. The
interface of interest in the IR namespace has the prefix ‘rfp-’. The API’s
being added as part of DVR support in the L3Agent[2] will be used by the FWaaS
Agent to make this determination for inserting the Firewall Rules
appropriately.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None. This is required as DVR - FWaaS integration will be broken.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;No impact, the changes are on the Agent/iptables Driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;No new REST API is introduced.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;The effort is to minimize the Security impact as DVR functionality breaks
FWaaS. Coverage for North - South traffic but no support for East - West
traffic which will be addressed as a separate proposal post Juno.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None to existing.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;No Support for FWaaS on East - West traffic.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Deployers should be aware that this only targets North - South functionality.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee: skandasw / badveli_vishnuus / (TBD)
Other contributors: TBD&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;FWaaS Agent changes to recognize agent_mode to identify appropriate
Namespace and interface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Corresponding FWaaS driver changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Patches awaiting merge on [1].&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests, Tempest API tests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;DVR and FWaaS documentation changes to reflect requirements.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-ovs-dvr"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-ovs-dvr&lt;/a&gt;
[2] &lt;a class="reference external" href="https://review.openstack.org/#/c/89413/"&gt;https://review.openstack.org/#/c/89413/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 10 Jul 2014 00:00:00 </pubDate></item><item><title>Add the functionality to sync resources between Neutron and Nuage VSD</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/nuage-neutron-sync.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/nuage-neutron-sync"&gt;https://blueprints.launchpad.net/neutron/+spec/nuage-neutron-sync&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The purpose of this blueprint is to add functionality to sync resources
between Neutron and Nuage VSD(Virtualized Services Directory).&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;If there is any inconsistency in the state of neutron and the VSD
database, there is no way to sync the resources between them.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposed change is to introduce support for state synchronization between
neutron and VSD in the Nuage plugin&lt;/p&gt;
&lt;p&gt;In case Nuage VSD loses its database or the database is restored using a backup
copy, there is a possibility that the resources in Neutron  and VSD are not in sync
and this can lead to unexpected behavior. The sync will run as part of Nuage plugin
at regular intervals.&lt;/p&gt;
&lt;p&gt;Neutron is considered as the master. The sync logic will get the state from Neutron and will
send it to VSD. VSD will compare this state with its own state and if there are less resources
in VSD as compared to Neutron, the resources will be created in VSD. In case there are more
resources in VSD, they will be deleted from VSD.&lt;/p&gt;
&lt;p&gt;Sync will be controlled by two config parameters “enable_sync” and “sync_interval”.
If the “enable_sync” parameter is set to true, the sync will start when Neutron
server starts and will try to sync resources. The sync will run periodically at an
interval specified for the “sync_interval” parameter.&lt;/p&gt;
&lt;p&gt;Assumption:
1. If the resource exists in VSD, all of its attributes are in sync with the corresponding
Neutron resource.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;sayaji15&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Modify the nuage plugin to add sync logic&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will be provided.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 09 Jul 2014 00:00:00 </pubDate></item><item><title>Providernet Extension support for Nuage Plugin</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/providernet-ext-support-for-nuage-plugin.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/providernet-ext-support-for-nuage-plugin"&gt;https://blueprints.launchpad.net/neutron/+spec/providernet-ext-support-for-nuage-plugin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Adding provider-network extension support to existing nuage networks’ Plugin&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Current Nuage Plugin does not support Neutron’s providernet extension.
Nuage’s VSP supports this feature and the support for extension needs
to be added in the plugin code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Adding extension support code in Nuage plugin.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;The provider extended attributes for networks enable administrative users to specify how
network objects map to the underlying networking infrastructure. This fits well with
Nuage’s ability to map the overlay with the underlay provided option. There will not be a
significant change in the plugin behavior. When the network is created with provider
options enabled, segments information (id, physical_network, vlan_id) is passed to the
Nuage’s backend and it will be acted upon. Backend will either accept it or will fail
the request and the response will be relayed back to the user. In case of a failure,
resource operation in neutron will also fail. In Juno, we want to keep the implementation
most basic.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Ronak Shah&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;ronak-malav-shah&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Extension code in Nuage plugin
Nuage Unit tests addition
Nuage CI coverage addition&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit Test coverage for providernet extension within Nuage unit test
Nuage CI will be modified to start supporting this extension tests as and when
corresponding tests are added in tempest&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 09 Jul 2014 00:00:00 </pubDate></item><item><title>Nuage Networks’ ML2 Mechanism Driver</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/nuage-ml2-mechanism-driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ml2-mech-driver-nuage"&gt;https://blueprints.launchpad.net/neutron/+spec/ml2-mech-driver-nuage&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Adding mechanism driver in ML2 plugin for Nuage Networks&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Nuage’s VSP fits well via its northbound API exposure to both ML2 based mechanism
driver as well as via monolithic plugin. As nuage strive to add more features and
functionality to its monolithic plugin, it is important from other integration
point of view to also support ml2 mechanism driver framework. This is the effort
to start achieving that goal.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;In Juno release, mechanism driver will support basic L2 functionality as a
stepping stone to enhance it in later release.
It will implement CRUD APIs for network, subnets and ports. Idea is to
reuse as much of the code base from the current monolithic plugin itself and
for that reason driver class will inherit nuage plugin class as one of the
parent.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Monolithic Nuage Plugin&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;In order for mechanism driver to talk to Nuage’s VSD, it will
require certain configuration to be read from the file. This is
similar approach to nuage’s monolithic plugin. Along with parameters
mentioned at etc/neutron/plugins/nuage/nuage_plugin.ini, user will
have to pass reference to precreated net-partition as well. Once
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-ml2-mechanismdriver-extensions"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-ml2-mechanismdriver-extensions&lt;/a&gt;
is implemented (if at all), will add support for it in next release.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Ronak Shah&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;ronak-malav-shah&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;ML2 mechanism driver code
Unit tests
Nuage CI infrastructure with ML2 driver (similar to the one with monolithic plugin)&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit Test coverage
Support for this driver in Nuage CI&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 08 Jul 2014 00:00:00 </pubDate></item><item><title>Layer 3 service plugin to support hardware based routing (SVI) on Brocade VDX</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/brocade-l3-svi-service-plugin.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/brocade-l3-svi-service-plugin"&gt;https://blueprints.launchpad.net/neutron/+spec/brocade-l3-svi-service-plugin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint exploits the L3 SVI functionality in the Brocade VDX
switch via an L3 router service plugin.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Brocade Hardaware supports SVI (Switch Virtual Interface) which provides ASIC
level routing/gateway functionality in the switch for configured VLANs. This
Service plugin provides support for this feature which enables line rate
routing/gateway functionality.&lt;/p&gt;
&lt;p&gt;Please see definition of SVI in the references section of this document.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This proposal will introduce a Layer 3 service plugin which will interface
with the Brocade VDX switch using NETCONF. NETCONF interface on the switch
will be used to program the SVI on the switch.&lt;/p&gt;
&lt;p&gt;This plugin works in conjuction with Brocade ML2 Driver which will continue
to manage networks, subnets, and ports.&lt;/p&gt;
&lt;p&gt;We plan to support the full API.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The alternative approach is to use the open source agent based layer 3 router
plugin and update the L3 agent to interact with Brocade Hardware.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;In the Brocade specific DB a table will be added to track the SVI created on
a tenant basis. Mapping of the SVI to the VLAN will also be provided.&lt;/p&gt;
&lt;p&gt;new table: brocade_db.svi (id, vlan, tenant_id)
id - standard uuid
vlan - svi’s associated vlan
tenant_id: tenant this svi belongs to&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There are no changes to any existing code patterns, hence there is no
significant change in performance profile. Instead of software L3 service
this blueprrint provides the same service using the VDX hardware. NETCONF
requests to the switch may add a very slight change to the execution time of
the API but we expect this change to be minor and will affect only setups
depolying this hardware based functionality.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Shiv Haris
&lt;a class="reference external" href="mailto:sharis%40brocade.com"&gt;sharis&lt;span&gt;@&lt;/span&gt;brocade&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;
IRC - shivharis&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;L3-SVI Service Plugin&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack related enhancements to support this plugin&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Complete unit test coverage of the code will be provided with mocked hardware.&lt;/p&gt;
&lt;p&gt;Brocade will provide Third-Party tempest code coverage of this functionality. This
will be implemented as a CI (continuous integration) Testing. L3 routing tests will
be enabled.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation to configure and deploy this service plugin will be provided
in the Openstack wiki.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;SVI General definition:
Wikipedia: &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Switvh_virtual_interface"&gt;http://en.wikipedia.org/wiki/Switvh_virtual_interface&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 07 Jul 2014 00:00:00 </pubDate></item><item><title>Big Switch - Have ML2 driver bind IVS VIF type</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/bsn-ml2-bind-ivs.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/bsn-ml2-bind-ivs"&gt;https://blueprints.launchpad.net/neutron/+spec/bsn-ml2-bind-ivs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Big Switch ML2 driver needs to be responsible for binding the IVS VIF type
since there is no binding agent running for this virtual switch.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, the Big Switch ML2 driver is only responsible for configuring VLANs
in the fabric. It doesn’t do anything with the vSwitch so it leaves the
responsibility of binding the ports to the OpenVSwitch driver. However, it
needs to support IVS switches as well, which will not have a binding driver
since they are directly controlled by the backend controller. Therefore, it
will need to be responisble for responding to the bind_port calls for hosts
with the IVS switches and mark them as bound.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;At the port binding method to the Big Switch ML2 driver and have it respond
to port binding calls for IVS ports.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Deployers will be able to deploy IVS vswitches with the Big Switch ML2 plugin.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;kevinbenton&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add the port binding methods to the ML2 driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add unit tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;In addition to the unit tests, a new 3rd party CI test case will be added
for IVS deployed under ML2.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Mention that IVS can be used in conjuction with Big Switch Ml2 deployments.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 04 Jul 2014 00:00:00 </pubDate></item><item><title>Big Switch - ML2 external attachment for vlan_switch type</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/bsn-ml2-ext-attach.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/bsn-ml2-ext-attach"&gt;https://blueprints.launchpad.net/neutron/+spec/bsn-ml2-ext-attach&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec is to add the ability for the Big Switch ML2 driver to
configure external attachment points for the vlan_switch type.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Once the external attachment point extension[1] is implemented, ML2
drivers will have the ability to bind external attachment points to
neutron networks. Since the Big Switch backend has full control over
the fabric, it can bind physical ports to neutron networks. However,
the code needs to be added in the ML2 driver to take these calls and
pass them to the backend controller.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add the appropriate external attachment methods to the Big Switch ML2
driver to relay the information to the backend controller.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;kevinbenton&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add the relevant methods to the Big Switch ML2 driver to receive the external
attachment calls and relay them to the backend controller.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add unit tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Implementation of external attachment point in the ML2 plugin.[1]&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests until a physical testbed can be setup in the 3rd party CI.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/neutron-specs/blob/master/specs/juno/neutron-externa"&gt;https://github.com/openstack/neutron-specs/blob/master/specs/juno/neutron-externa&lt;/a&gt;    l-attachment-points.rst&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description><pubDate>Fri, 04 Jul 2014 00:00:00 </pubDate></item><item><title>Cisco VPNaaS with in-band Cisco CSR router</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/cisco-vpnaas-with-cisco-csr-router.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/cisco-vpnaas-with-cisco-csr-router"&gt;https://blueprints.launchpad.net/neutron/+spec/cisco-vpnaas-with-cisco-csr-router&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Enhance the Cisco IPSec site-to-site VPNaaS solution, by integrating it with
a Cisco Cloud Services Router (CSR) running as a Neutron router.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;In the current Proof of Concept Cisco VPNaaS, a Cisco CSR VM runs
out-of-band from OpenStack, and parallel to a reference Neutron router.
The Cisco CSR is started manually, and independently of OpenStack. the router
is statically provisioned and information on the Cisco CSR is stored in an
.ini file for use by the Cisco VPNaaS driver.&lt;/p&gt;
&lt;p&gt;When a VPN IPSec site-to-site connection is established, the VPNaaS drivers
use the .ini information to communicate with the Cisco CSR and configure
the VPN IPSec site-to-site connection. A packet redirect is configured on the
Neutron router, to send all packets for the remote end, to the Cisco CSR.&lt;/p&gt;
&lt;p&gt;The issues with this are:
* Cisco CSR is manually started and provisioned for use.
* Static configuration of all Cisco CSRs is established before Neutron startup.
* We are effectively using two routers to provide VPNaaS capability.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;A separate blueprint, cisco-routing-service-vm [2], will be providing a Cisco CSR
VM as a Neutron router, dynamically creating and provisioning the Cisco CSR
when a router specifying this type is created.&lt;/p&gt;
&lt;p&gt;This blueprint proposes to update the Cisco VPNaaS driver to work with this
“in-band” Cisco CSR. The VPNaaS driver will obtain information (user, password,
mgmt IP, etc.) on the Cisco CSR dynamically, instead of statically from a config
file, as done currently, so that VPN IPSec connections can then be provisioned.&lt;/p&gt;
&lt;p&gt;Combined, these two blueprints will allow automatic creation and provisioning
of Cisco CSRs, dynamic provisioning of VPNaaS connections, and eliminate the
need for a second router and packet redirection.&lt;/p&gt;
&lt;p&gt;Specifically, in the context of VPNaaS, the user can create a CSR1kV VM based
Neutron router, and then create a VPN service with IPsec site-to-site connections,
which will use that router.&lt;/p&gt;
&lt;p&gt;To mitigate the risk of the dependency on the Cisco Routing Service VM
blueprint [2], the VPN implementation can be phased. In the first phase, the
code would attempt to obtain information on the CSR from the L3 plugin, but
if not available, could read the config from an INI file (as done currently
in the device driver).&lt;/p&gt;
&lt;p&gt;The user could setup a CSR out-of-band manually (as done today), udpate the
INI file, and then proceed to create the VPN service and connections.
When the cisco-routing-service-vm [2] is upstreamed, the VPN code that does
the fallback INI file reading could be removed.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;With the current out-of-band Cisco CSR, the VPNaaS driver could re-read the
.ini file whenever it changes to obtain updated router information. That
allows dynamically creating VPNaaS connections, but still requires manual
start-up and provisioning of the CSR (and use of dual routers).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Eliminates the need for operator to manually start and provision the Cisco CSR
and create the .ini file.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;No effect to the VPNaaS performance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Deployment becomes much easier.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;pmichali&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Removal of device driver code that reads the .ini file with Cisco CSR info.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modification of service driver to obtain Cisco CSR info and pass to device
driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modification of the device driver to use the passed information, instead of
.ini file info.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update unit tests to reflect changes made.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Requires the cisco-routing-service-vm blueprint implementation, which provides
the Cisco CSR as a Neutron router and manages the life-cycle of the router.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will be updated accordingly. The cisco-routing-service-vm BP will
have Tempest tests. Currently, there are no Tempest fucntional tests for
VPNaaS, but as they become available, third-party tests will be created for
the Cisco CSR implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[1] Out-of-band VPN setup: &lt;a class="reference external" href="http://docwiki.cisco.com/wiki/Install_and_Setup_of_Cisco_Cloud_Services_Router_(CSR)_for_OpenStack_VPN"&gt;http://docwiki.cisco.com/wiki/Install_and_Setup_of_Cisco_Cloud_Services_Router_(CSR)_for_OpenStack_VPN&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[2] &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/cisco-routing-service-vm"&gt;https://blueprints.launchpad.net/neutron/+spec/cisco-routing-service-vm&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[3] &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ipsec-vpn-reference"&gt;https://blueprints.launchpad.net/neutron/+spec/ipsec-vpn-reference&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 03 Jul 2014 00:00:00 </pubDate></item><item><title>Config option to control visibility of cisco-policy-profile resources for tenants</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/cisco-policy-profile-visibility.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/cisco-policy-profile-visibility"&gt;https://blueprints.launchpad.net/neutron/+spec/cisco-policy-profile-visibility&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Config option to control visibility of cisco-policy-profile resources for tenants&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, cisco-policy-profile resources must be explicitly assigned to tenants.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This proposes adding a config option to Cisco N1KV plugin to control the visibility
of these resources.&lt;/p&gt;
&lt;p&gt;The options may be True/False.
Selecting True would allow tenants access to all the cisco-policy-profile resources
without the need for explicit assignment.
The False option would turn off the visibility and require explicit assignment of
a cisco-policy-profile resources to a tenant.
Default value is True&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Admin needs to explicitly assign cisco-policy-profile resources to tenants.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;A new visibility option will be added in cisco_plugin.ini file.
Its default value will be True, which means it’s enabled by default.
The change will take immediate effect after it’s merged.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;fenzhang&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;add visibility option in cisco_plugins.ini file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;retrieve this option and control the visibility of cisco-policy-profile resources
based on its value in neutron/plugins/cisco/db/n1kv_db_v2.py file&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The UT test cases will be added to cover this change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Will need to document it in user manual&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 01 Jul 2014 00:00:00 </pubDate></item><item><title>Group-based Policy Abstractions for Neutron</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/group-based-policy-abstraction.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/group-based-policy-abstraction"&gt;https://blueprints.launchpad.net/neutron/+spec/group-based-policy-abstraction&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes an extension to the Neutron API with a declarative
policy driven connectivity model that presents simplified application-oriented
interfaces to the user.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The current Neutron model of networks, ports, subnets, routers, and security
groups provides the necessary building blocks to build a logical network
topology for connectivity. However, it does not provide the right level
of abstraction for an application administrator who understands the
application’s details (like application port numbers), but not the
infrastructure details likes networks and routes. Not only that, the current
abstraction puts the burden of maintaining the consistency of the network
topology on the user.  The lack of application developer/administrator focussed
abstractions supported by a declarative model make it hard for those users
to consume Neutron as a connectivity layer.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The policy framework described in this blueprint complements the current
Neutron model with the notion of policies that can be applied between groups of
endpoints. As users look beyond basic connectivity, richer network services
with diverse implementations and network properties are naturally expressed as
policies. Examples include service chaining, QoS, path properties, access
control, etc.&lt;/p&gt;
&lt;p&gt;This proposal suggests a model that allows application administrators to
express their networking requirements using group and policy abstractions, with
the specifics of policy enforcement and implementation left to the underlying
policy driver. The main advantage of the extensions described in this blueprint
is that they allow for an application-centric interface to Neutron that
complements the existing network-centric interface.&lt;/p&gt;
&lt;p&gt;More specifically the new abstractions will achieve the following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Show clear separation of concerns between application and infrastructure
administrator.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The application administrator can then deal with a higher level abstraction
that does not concern itself with networking specifics like
networks/routers/etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The infrastructure administrator will deal with infrastructure specific
policy abstractions and not have to understand application specific concerns
like specific ports that have been opened or which of them expect to be
limited to secure or insecure traffic. The infrastructure admin will also
have ability to direct which technologies and approaches used in rendering.
For example, if VLAN or VxLAN is used.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allow the infrastructure admin to introduce connectivity constraints
without the application administrator having to be aware of it (e.g. audit
all traffic between two application tiers).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allow for independent provider/consumer model with late binding and n-to-m
relationships between them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allow for automatic orchestration that can respond to changes in policy or
infrastructure without requiring human interaction to translate intent to
specific actions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Complement the governance model proposed in the OpenStack Congress project by
making Policy Labels available for enforcement.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following new terminology is being introduced:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Endpoint (EP):&lt;/strong&gt; An L2/L3 addressable entity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Endpoint Group (EPG):&lt;/strong&gt; A collection of endpoints.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Contract:&lt;/strong&gt; It defines how the application services provided by an EPG can be
accessed. In effect it specifies how an EPG communicates with other EPGs. A
Contract consists of Policy Rules.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Policy Rule:&lt;/strong&gt; These are individual rules used to define the communication
criteria between EPGs. Each rule contains a Filter, Classifier, and Action.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Classifier:&lt;/strong&gt; Characterizes the traffic that a particular Policy Rule acts on.
Corresponding action is taken on traffic that satisfies this classification
criteria.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Action:&lt;/strong&gt; The action that is taken for a matching Policy Rule defined in a
Contract.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Filter:&lt;/strong&gt; Provides a way to tag a Policy Rule with Capability and Role labels.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Capability:&lt;/strong&gt; It is a Policy Label that defines what part of a Contract a
particular EPG provides.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Role:&lt;/strong&gt; It is a Policy Label that defines what part of a Contract an EPG wants
to consume.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Contract Scope:&lt;/strong&gt; An EPG conveys its intent to provide or consume a Contract
(or its part) by defining a Contract Scope which references the target
Contract.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Selector:&lt;/strong&gt; A Contract Scope can define additional constraints around choosing
the matching provider or consumer EPGs for a Contract via a Selector.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Policy Labels:&lt;/strong&gt; These are labels contained within a namespace hierarchy and
used to define Capability and Role tags used in Filters.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bridge Domain:&lt;/strong&gt; Used to define a L2 boundary and impose additional
constraints (such as no broadcast) within that L2 boundary.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Routing Domain:&lt;/strong&gt; Used to define a non-overlapping IP address space.&lt;/p&gt;
&lt;p&gt;Here is an example of how a three tier application would look like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;+–––––––––+          +–––––––+          +–––––––+          +–––––––+
|         |          | Web   |          | App   |          |DB     |
| Outside |          | EPG   |          | EPG   |          |EPG    |
| Public  | +––––––––+  +––+ | +––––––––+  +––+ | +––––––––+  +––+ |
| Network +–+Web     |  |VM| +–+App     |  |VM| +–+DB      |  |VM| |
| EPG     | |Contract|  +––+ | |Contract|  +––+ | |Contract|  +––+ |
|         | +––––––––+       | +––––––––+       | +––––––––+       |
|         |          |  +––+ |          |  +––+ |          |  +––+ |
|         |          |  |VM| |          |  |VM| |          |  |VM| |
|         |          |  +––+ |          |  +––+ |          |  +––+ |
+–––––––––+          +–––––––+          +–––––––+          +–––––––+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Example CLI:&lt;/p&gt;
&lt;p&gt;(exmaple only shows access to the Web Server Tier from the Outside Network)&lt;/p&gt;
&lt;p&gt;Create Classifier&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;classifier&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;Insecure&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Web&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Access&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;protocol&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt;
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="n"&gt;IN&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Create Contract using the Classifier&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;Web&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Contract&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;classifier&lt;/span&gt; &lt;span class="n"&gt;Insecure&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Web&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Access&lt;/span&gt;
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="n"&gt;ALLOW&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Create EPG providing the Contract&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;epg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;Web&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;EPG&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;provides&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;Web&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Contract&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Create Endpoint in EPG&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;ep&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;epg&lt;/span&gt; &lt;span class="n"&gt;Web&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;EPG&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Launch Web Server VM using Endpoint in EPG&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;nova&lt;/span&gt; &lt;span class="n"&gt;boot&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="n"&gt;cirros&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;flavor&lt;/span&gt; &lt;span class="n"&gt;m1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nano&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;nic&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;EP&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Web&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Specify connectivity of Outside world VMs to Web Server&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;epg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;Outside&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;EPG&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;consumes&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;Web&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Contract&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that the Contract Provider/Consuming Scopes are not explicitly shown in
the above diagram but define each providing and consuming relation between an
EPG and a Contract as shown below:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;        +––––––––––+
        |Web       |
        |Contract  |
        |Consuming |
        |Scope     |
        +–––+––––––+
+–––––––––+ |               +––––––––––+
|         | |               | Web      |
| Outside | |               | EPG      |
| Public  | | +––––––––+    |  +––+    |
| Network +–+–+Web     +––+–+  |VM|EP  |
| EPG     |   |Contract|  | |  +––+    |
|         |   +––––––––+  | |          |
|         |               | |  +––+    |
|         |               | |  |VM|EP  |
|         |               | |  +––+    |
+–––––––––+               | |          |
                          | +––––––––––+
                          +
                     +––––+–––––+
                     |Web       |
                     |Contract  |
                     |Providing |
                     |Scope     |
                     +––––––––––+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Since a new level of abstraction is being proposed here, a direct alternate
does not exist in the current model.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;New Database Objects to support Group Policy:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;+–––––––––––––+     +–––––––––––––––+      +–––––––––––+
|             |     |   Contract    |      |Contracts  |
|   Endpoint  |     |   Providing/  |      |           |
|   Groups    +–––––+   Consuming   +––––––+           |
|             |     |   Scopes      |      +–––––+–––––+
+––––––+––––––+     +–––––––––––––––+            |
       |                                   +–––––+–––––+
       |                                   |Policy     |
+––––––+––––––+                            |Rules      |
|             |                            |           |
|  Endpoints  |                      +–––––+––––––+––––+––––––––+
|             |                      |            |             |
+–––––––––––––+                      |            |             |
                                     |            |             |
                               +–––––+––+  +––––––+–––––+ +–––––+––+
                               |Filters |  |Classifiers | |Actions |
                               |        |  |            | |        |
                               +––––––––+  +––––––––––––+ +––––––––+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;All objects have the following common attributes:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;id - standard object uuid&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;name - optional name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;description - optional annotation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Endpoint&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;epg_id - UUID of the EndpointGroup (EPG) that this Endpoint (EP) belongs to&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;EndpointGroup&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;endpoints - list of endpoint uuids&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;contract_providing_scopes - list of ContractProvidingScope uuids&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;contract_consuming_scopes - list of ContractConsumingScope uuids&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Contract&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;policy_rules - ordered list of PolicyRule uuids&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;contract_providing_scopes - list of ContractProvidingScope uuids&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;contract_consuming_scopes - list of ContractConsumingScope uuids&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;child_contracts - ordered list of Contract uuids&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;ContractProvidingScope&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;contract_id - uuid of the Contract that is being provided by the EPG&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;selectors - list of Selectors uuids&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;capabilites - list of PolicyLabel uuids&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;providing_epg - EndpointGroup uuid&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;ContractConsumingScope&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;contract_id - uuid of the Contract that is being consumed by the EPG&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;selectors - list of Selectors uuids&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;roles - list of PolicyLabels&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;consuming_epg - EndpointGroup uuid&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Selector&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;scope - enum: GLOBAL, TENANT, EPG&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;value - None for GLOBAL, or uuid of tenant/EPG&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;PolicyLabel&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;namespace - string, a namespace identifier for policy labels&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;name - string, not optional&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;PolicyRule&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;filter - uuid of Filter&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;classifier - uuid of Classifier&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;actions - list of Action uuids&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Filter&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;provider_capablilities - list of PolicyLabel uuids&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;consumer_roles - list of PolicyLabel uuids&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Classifier&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;protocol - enum: TCP, IP, ICMP&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;port_range - single port number or range (as used in FWaaS firewall_rule)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;direction - enum: IN, OUT, BI&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Action&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;type - enum: ALLOW, REDIRECT, QOS, LOG, MARK, COPY&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;value - uuid of a resource that performs the action, for example in the
case of REDIRECT, its the uuid of the ServiceWrapper&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;ServiceWrapper&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;neutron_service - uuid of service or service_chain&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;L2Policy&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;endpoint_groups - list of EndpointGroup uuids&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;l3_policy_id - uuid of the l3_policy&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;L3Policy&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;l2_policies - list of L2Policy uuids&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ip_version - enum, v4 or v6&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ip_pool - string, IPSubnet with mask, used to pull subnets from if the
user creates an EPG without specifying a subnet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;default_subnet_prefix_length - int, used as the default subnet length if
the user creates an EPG without a subnet&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The way ip_pool and default_subnet_prefix_length work is as follows: When
creating L3Policy a default ip_pool and default_subnet_prefix_length are
created. If a user creates an EPG, a subnet will be pulled from ip_pool using
default_subnet_prefix_length.&lt;/p&gt;
&lt;p&gt;Objects to support Mapping to existing Neutron resources&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;EndpointPortBinding (extends Endpoint)&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;neutron_port_id - uuid of Neutron Port that this EP maps to&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;EndpointGroupNetworkBinding (extends EndpointGroup)&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;neutron_subnets - list of Neutron Subnet uuids&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;L2PolicyBinding (extends l2_policy)&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;neutron_network_id - reference to a Neutron network&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;L3PolicyBinding (extends l3_policy)&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;neutron_routers - list of Neutron Router uuids&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Appropriate foreign key constraints will be added to maintain the referential
integrity of the model.&lt;/p&gt;
&lt;p&gt;Database migrations:
New tables are being added to the schema, however the existing schema remains
unchanged.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The following new resources are being introduced:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;gp_supported_actions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ALLOW'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'REDIRECT'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;gp_supported_directions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'IN'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'OUT'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'BI'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;gp_supported_protocols&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'TCP'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'UDP'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ICMP'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;gp_supported_scopes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'GLOBAL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'TENANT'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'EPG'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;ENDPOINTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'endpoints'&lt;/span&gt;
&lt;span class="n"&gt;ENDPOINT_GROUPS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'endpoint_groups'&lt;/span&gt;
&lt;span class="n"&gt;CONTRACTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'contracts'&lt;/span&gt;
&lt;span class="n"&gt;CONTRACT_PROVIDING_SCOPES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'contract_providing_scopes'&lt;/span&gt;
&lt;span class="n"&gt;CONTRACT_CONSUMING_SCOPES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'contract_consuming_scopes'&lt;/span&gt;
&lt;span class="n"&gt;POLICY_RULES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'policy_rules'&lt;/span&gt;
&lt;span class="n"&gt;FILTERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'filters'&lt;/span&gt;
&lt;span class="n"&gt;CLASSIFIERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'classifiers'&lt;/span&gt;
&lt;span class="n"&gt;ACTIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'actions'&lt;/span&gt;
&lt;span class="n"&gt;SELECTORS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'selectors'&lt;/span&gt;
&lt;span class="n"&gt;POLICY_LABELS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'policy_labels'&lt;/span&gt;
&lt;span class="n"&gt;L2_POLICIES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'l2_policies'&lt;/span&gt;
&lt;span class="n"&gt;L3_POLICIES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'l3_policies'&lt;/span&gt;

&lt;span class="n"&gt;RESOURCE_ATTRIBUTE_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ENDPOINTS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'endpointgroup_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid__or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                             &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;ENDPOINT_GROUPS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                 &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'endpoints'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_none_to_empty_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'bridge_domain_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                             &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'provided_contract_scopes'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                     &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                                     &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                      &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_none_to_empty_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                      &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'consumed_contract_scopes'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                     &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                                     &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                     &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_none_to_empty_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                     &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;CONTRACTS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                 &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'child_contracts'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                            &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_none_to_empty_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'policy_rules'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                         &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_none_to_empty_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;CONTRACT_PROVIDING_SCOPES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                 &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'endpointgroup_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                             &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'contract_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'selector_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'capabilities'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                         &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_none_to_empty_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;CONTRACT_CONSUMING_SCOPES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                   &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'endpointgroup_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                             &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'contract_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'selector_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'roles'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                  &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_none_to_empty_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;POLICY_RULES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                 &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'enabled'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'filter_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'classifier_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                          &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'actions'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_none_to_empty_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;FILTERS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                 &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'provider_capabilities'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                  &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                                  &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                                  &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_none_to_empty_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                  &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'consumer_roles'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                           &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_none_to_empty_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;CLASSIFIERS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                 &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'protocol'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;convert_protocol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;gp_supported_protocols&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
        &lt;span class="s1"&gt;'port_range'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:port_range'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                       &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;convert_port_to_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'direction'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;gp_supported_directions&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;ACTIONS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                 &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'action_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;convert_action_to_case_insensitive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;gp_supported_actions&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'allow'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'action_value'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                         &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;SELECTORS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                 &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'scope'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;convert_scope_to_case_insensitive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;gp_supported_scopes&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                  &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'tenant'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                  &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;POLICY_LABELS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
               &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                 &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'namespace'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                 &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;L2_POLICIES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                 &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'endpoint_groups'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                            &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_none_to_empty_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'routing_domain_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                              &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                              &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                              &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;L3_POLICIES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'primary_key'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                 &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:string'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                      &lt;span class="s1"&gt;'required_by_policy'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'ip_version'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
                       &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'ip_pool'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:subnet'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'10.0.0.0/8'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'default_subnet_prefix_length'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_to_int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="c1"&gt;# ipv4 specific validation is&lt;/span&gt;
                            &lt;span class="c1"&gt;# performed in the plugin code.&lt;/span&gt;
                            &lt;span class="s1"&gt;'type:values'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;127&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt;
                        &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'l2_policies'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                           &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_none_to_empty_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The following defines the mapping to classical (existing) Neutron resources
using attribute extension:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;EXTENDED_ATTRIBUTES_2_0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;gpolicy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ENDPOINTS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'neutron_port_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                            &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;gpolicy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ENDPOINT_GROUPS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'neutron_subnets'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                            &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_none_to_empty_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;gpolicy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;L2_POLICIES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'neutron_network_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                               &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_or_none'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                               &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;gpolicy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;L3_POLICIES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'neutron_routers'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'allow_post'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'allow_put'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s1"&gt;'validate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type:uuid_list'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                            &lt;span class="s1"&gt;'convert_to'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_none_to_empty_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'is_visible'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;The connectivity model used here is consistent with OpenStack/Neutron’s current
white list model - that is, there is no connectivity outside an EPG unless
explicitly allowed.&lt;/p&gt;
&lt;p&gt;The rendering of the proposed new abstractions happens via existing Security
Groups and Firewall as a Service constructs. As such, no new constructs or
implementation that will directly affect the current security framework are
being introduced.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Does this change touch sensitive data such as tokens, keys, or user data?&lt;/p&gt;
&lt;p&gt;No&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this change alter the API in a way that may impact security, such as
a new way to access sensitive information or a new way to login?&lt;/p&gt;
&lt;p&gt;No&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this change involve cryptography or hashing?&lt;/p&gt;
&lt;p&gt;No&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this change require the use of sudo or any elevated privileges?&lt;/p&gt;
&lt;p&gt;No&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this change involve using or parsing user-provided data? This could
be directly at the API level or indirectly such as changes to a cache layer.&lt;/p&gt;
&lt;p&gt;No&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can this change enable a resource exhaustion attack, such as allowing a
single API interaction to consume significant server resources? Some examples
of this include launching subprocesses for each connection, or entity
expansion attacks in XML.&lt;/p&gt;
&lt;p&gt;The exposed risk here is no different from the existing APIs and would largely
depend on the Policy Driver implementation.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Integration with following projects will be required:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;python-neutronclient&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;horizon&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;heat&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;devstack&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;A new layer of abstraction is being introduced. All performance considerations
that are relevant to existing Neutron will apply and be taken into
consideration during the implementation. It should be noted though that the use
of this new layer of abstraction/extensions is optional, and as such will not
affect the performance of the existing implementation if the former is not
used.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Config additions&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Policy Plugin class&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Policy Plugin driver class&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;This will be a new API, and will not affect existing API.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Sumit Naiksatam (snaiksat) - Launchpad blueprint assignee&lt;/p&gt;
&lt;p&gt;Robert Kukura (rkukura)&lt;/p&gt;
&lt;p&gt;Mandeep Dhami (mandeep-dhami)&lt;/p&gt;
&lt;p&gt;Mohammad Banikazemi (banix)&lt;/p&gt;
&lt;p&gt;Stephen Wong (s3wong)&lt;/p&gt;
&lt;p&gt;Prasad Vellanki (prasad-vellanki)&lt;/p&gt;
&lt;p&gt;Hemanth Ravi (hemanth-ravi)&lt;/p&gt;
&lt;p&gt;Subrahmanyam Ongole (osms69)&lt;/p&gt;
&lt;p&gt;Ronak Shah (ronak-malav-shah)&lt;/p&gt;
&lt;p&gt;Rudra Rugge (rudrarugge)&lt;/p&gt;
&lt;p&gt;Kanzhe Jiang (kanzhe-jiang)&lt;/p&gt;
&lt;p&gt;Kevin Benton (kevinbenton)&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Policy Manager
Policy Driver&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Both, functional and, system tests will be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Both, API and, Admin guide will be updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Weekly IRC meetings wherein this blueprint has been discussed since Nov 2013&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Meetings/Neutron_Group_Policy"&gt;https://wiki.openstack.org/wiki/Meetings/Neutron_Group_Policy&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Group Policy Wiki - &lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/GroupPolicy"&gt;https://wiki.openstack.org/wiki/Neutron/GroupPolicy&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 01 Jul 2014 00:00:00 </pubDate></item><item><title>ofagent: physical interface mappings</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/ofagent-physical-interface-mappings.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ofagent-physical-interface-mappings"&gt;https://blueprints.launchpad.net/neutron/+spec/ofagent-physical-interface-mappings&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;ofagent currently has “bridge_mappings” config option inherited
from ovs agent.  it assumes multiple bridges are available.
the assumption is ok for ovs agent but not desirable for ofagent.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;introduce “physical_interface_mappings” config option for ofagent
with a similar semantics to linuxbridge.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;deprecate bridge_mappings for ofagent later.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;document the upgrade procedure for deployers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;no alternative i can think of right now.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;a deployer who’s using ofagent might need to tweak his configuration.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create veth pairs for each bridges in the existing bridge_mappings&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;use physical_interface_mappings instead of bridge_mappings&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;yamamoto&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;kakuma&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;see “Proposed change” section.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;we need to stop installing flows in physical bridges.
we plan to do that in the following.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/98702/"&gt;https://review.openstack.org/#/c/98702/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;ryu/ofagent third party testing would find regressions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;document the upgrade procedure for deployers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 01 Jul 2014 00:00:00 </pubDate></item><item><title>Reorganize neutron migrations (Once they’ve been ‘healed’)</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/reorganize_migrations.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/reorganize-migrations"&gt;https://blueprints.launchpad.net/neutron/+spec/reorganize-migrations&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A good chunk of current migrations apply only to certain plugins making them
configuration-dependent. A migration path dependent on configuration poses a
serious upgrade problem. The Neutron DB is being restructured in a way that
the DB schema will always be the same regardless of Neutron’s configuration.
For this reason, logic for handling configuration-dependent migrations should
go; similarly configuration dependent migrations should be made ‘independent’.
Possibly they should also be squashed so that by reducing the overall number
of migration we might be able to speed up DB ugrade process.&lt;/p&gt;
&lt;p&gt;The work described in this blueprint relies on the Neutron DB healing
blueprint, whose spec can be found at: &lt;a class="reference external" href="https://review.openstack.org/95738/"&gt;https://review.openstack.org/95738/&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;There are currently over 100 migrations in Neutron’s DB upgrade path.
A migration often applies only to certain plugins, and is skipped if currently
neutron is configured with a different plugin. This creates a serious upgrade
problem.&lt;/p&gt;
&lt;p&gt;As an example, the devstack job for Neutron for testing an upgrade from havana
to icehouse fails because the ‘metering’ service plugin is specified only in
the icehouse configuration; however since it was introduced in havana, some
fundamental migrations to make it work where skipped. Hence the upgrade fails
as soon as the first migration touching metering DB models is encountered.&lt;/p&gt;
&lt;p&gt;This problem is already being dealt with by “healing” neutron DB schema in a
way such that its end state will be the same regardless of conf values.&lt;/p&gt;
&lt;p&gt;Nevertheless, there a few more things to take care of:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Existing DB migrations which apply to specific plugins must become
plugin-agnostic&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The logic for handling plugin-specific migrations should go in order to
prevent plugin-specific migration from being pushed in the future.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposed change is rather simple: remove the logic for skipping
migrations according to the current configuration, and make all migrations
“global”.&lt;/p&gt;
&lt;p&gt;As this blueprint looks back at the whole migration history, which stretches
back to folsom, this is also a good chance to coalesce this rather long path
by squashing intra-release migrations together, and removing from the path
versions which are now not anymore supported.&lt;/p&gt;
&lt;p&gt;For instance, the revised path could:
1) Start at Havana Release&lt;/p&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;Have a single, configuration-independent, migration to Icehouse&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;3) Resume the ‘traditional’ path from Icehoue up to trunk, ensuring that
all migrations in this path become however configuration-independent&lt;/p&gt;
&lt;p&gt;This new migration path MUST ensure correct operation of upgrade/downgrades
from Havana to Icehouse. To this aim, this change will introduce:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A new ‘Havana’ initial state. This will be independent from configuration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A single migration to go from Havana to Icehouse and vice versa.
This migration will be able to upgrade an Havana database to Icehouse and
viceversa. The downgrade side of this migration will assume the Icehouse
schema is already in an “healed” state. Hence the following step.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A healing step immediately before Icehouse. This migration will
have only the downgrade side. This is for ensuring the database is in a
healed state as the new downgrade migration to Havana makes this
assumption. Being the healing migration idempotent, this should not
be a problem.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;NOTE: If there is consensus to keep allowing users running unsupported
releases to upgrade to Icehouse directly then initial statuses for Folsom
and Grizzly might be kept.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;One alternative would be to leave everything as it is at the moment, and add
a test (integrated with flake8) to prevent new plugin-dependent migrations
from being added to the path; Also the check for asessing whether a migration
should be executed or skipped will be bypassed.&lt;/p&gt;
&lt;p&gt;This should work, but it will still leave us with a lot of plugin-specific
migrations which might confuse users. Also, there will be leftover, unused
code in the source tree which will eventually end up bitrotting.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;The migration path up to Havana will be removed.
This can be substituted with Grizzly if there is an agreement to provide
users running the now unsupported Grizzly to uprade to a more recent release.&lt;/p&gt;
&lt;p&gt;Intra-release migrations between Havana and Icehouse (and possibly between
Grizzly and Havana) will be squashed into a single migration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Nada&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;Nonw&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;If migrations are squashed, upgrade will obviously be faster.
No impact for runtime performance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Operators which already already running havana should be able to upgrade
to icehouse without any problem.&lt;/p&gt;
&lt;p&gt;For operators running Icehouse, Havana downgrade should be smooth, both if
they executed or not already the ‘healing’ migration.&lt;/p&gt;
&lt;p&gt;Operators running versions prior to Havana might still be supported,
if versions older than Havana are kept in the migration path.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;It will be no longer possible to create plugin-specific migrations.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;In rough terms we might expect a first step where the migration logic is
removed, and all migrations made independent of configuration.
In a second step instead a new initial state will be defined and intra-release
migrations prior to Icehouse will be squashed.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;salvatore-orlando
akamyshnikova&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Even if these work items are not orthogonal, dependencies among them are not
necessarily represented by the order in which appear in this document.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;remove all folsom and grizzly migrations. Create a new “Havana” initial
migration - in a “healed” state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;make conditional migrations unconditional&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ensure a healing step is performed also in downgrade direction.
This is for ensuring unconditional downgrades don’t fail because of a
database not in a “healed” state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;remove logic for managing conditional migrations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;squash migration between havana and icehouse in a single migration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;deal with conditional migrations between “icehouse” and the healing step&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;DB migration refactoring is a prerequisite for this blueprint.
&lt;a class="reference external" href="https://review.openstack.org/#/c/95738/"&gt;https://review.openstack.org/#/c/95738/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;No additional tests should be added. Instead, some unit tests concerning
plugin-specific migrations might be removed.&lt;/p&gt;
&lt;p&gt;Existing grenade tests should be enough to validate the new upgrade path.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 23 Jun 2014 00:00:00 </pubDate></item><item><title>bulk-get-device-details</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/bulk-get-device-details.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/bulk-get-device-details"&gt;https://blueprints.launchpad.net/neutron/+spec/bulk-get-device-details&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Introduce a rpc call to get device details for multiple devices instead of one
by one.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;An agent needs to communicate with Neutron server in order to get some infomation
about the devices (to handle devices added for example).
Currently there’s an rpc call that can be used by the agent to get the details
of a device, get_device_details . This call needs to be issued for each device.
See neutron/agent/rpc.py .&lt;/p&gt;
&lt;p&gt;The purpose of this blueprint is to add a call to get the details of multiple
devices. This way instead of making N calls for N devices only one call will be
made.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Introduce a rpc call to get device details for multiple devices instead of one
by one.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Performane will be improved by this change&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Rossella Sblendido&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;rossella-s&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will be added&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;No impact&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 19 Jun 2014 00:00:00 </pubDate></item><item><title>Support Router Advertisement Daemon (radvd) for IPv6</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/ipv6-radvd-ra.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-ipv6-radvd-ra"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-ipv6-radvd-ra&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add support for radvd to Neutron, and use radvd as the preferred reference
implementation for IPv6 Router Advertisements and SLAAC. &lt;a class="reference internal" href="#radvd" id="id1"&gt;&lt;span&gt;[RADVD]&lt;/span&gt;&lt;/a&gt; is
open-source software that implements advertisements of IPv6 router addresses
and IPv6 routing prefixes using NDP.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;span id="problemdescription"/&gt;&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Router Advertisements (RAs) are fundamental to the IPv6 Neighbor Discovery
standard &lt;a class="reference internal" href="#rfc-4861" id="id2"&gt;&lt;span&gt;[RFC_4861]&lt;/span&gt;&lt;/a&gt;. Without radvd, Neutron would need to rely on dnsmasq for
RA functionality, which has a number of shortcomings:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;For DHCP the dnsmasq process runs in its own (dhcp) namespace. For RAs we
would need to run additional dnsmasq processes in router namespaces. Since we
don’t want to change the current DHCP functionality we would have to disable
prefix delegation for the dnsmasq processes running in router
namespaces. This would lead to a lot of overhead and scale issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unicast RAs are not supported by dnsmasq. Unicast RAs are a useful
feature. For example, they can be used to provide internet access to specific
end points when the default assignment is Unique Local Addresses (ULA).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some older versions of dnsmasq included with distributions have insufficient
IPv6 support.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This proposal is intended to cover announcing RAs, providing the announcement
information requested from the ipv6_ra_mode attribute.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;If IPv6 is enabled, start a radvd process in the namespace of each
router. Enable the Neutron L3 agent to support radvd configuration and
updating.&lt;/p&gt;
&lt;p&gt;The L3 agent will be updated to support radvd configuration based on the
attributes of the subnets associated with the router. Since radvd is configured
by a config file, the L3 agent will maintain a separate config file per router
namespace. The radvd process will need to be restarted when a configuration is
changed.&lt;/p&gt;
&lt;p&gt;When a subnet is deleted, the associated radvd configuration needs to be
updated so that the prefix is no longer advertised. The L3 agent will modify
the config and restart the radvd process.&lt;/p&gt;
&lt;p&gt;Some radvd settings will affect the configuration of DHCP. The DHCP agent will
be updated to treat subnet attributes and configure dnsmasq so that is is
compatible with how radvd is configured.&lt;/p&gt;
&lt;p&gt;Reasonable default values for some radvd settings, like RA interval and
lifetime, will be chosen in the first implementation. Follow-up bugs or feature
requests can be filed to add Neutron config options for radvd settings.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We could use dnsmasq for RA and SLAAC support. The shortcomings of this are
given in section &lt;a class="reference internal" href="#problemdescription"&gt;&lt;span class="std std-ref"&gt;Problem description&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;No change to the API, but the user/admin should know how to use the two IPv6
addressing attributes &lt;a class="reference internal" href="#two-mode" id="id3"&gt;&lt;span&gt;[TWO_MODE]&lt;/span&gt;&lt;/a&gt; to configure subnets for IPv6 addressing.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;ipv6
ra
mode&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;ipv6
address
mode&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;radvd
A,M,O&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;&lt;em&gt;N/S&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;em&gt;N/S&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Off&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;VM obtains IPv6 address based on non-OpenStack services on
the network, or only creates a link-local address (not
sourced by OpenStack).&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;em&gt;N/S&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;slaac&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Off&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;VM obtains IPv6 address from external router using SLAAC&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;&lt;em&gt;N/S&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dhcpv6-
stateful&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Off&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;VM obtains IPv6 address and optional info from dnsmasq
using DHCPv6 stateful&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;em&gt;N/S&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dhcpv6-
stateless&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Off&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;VM obtains IPv6 address from external router using SLAAC
and optional info from dnsmasq using DHCPv6 stateless&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;slaac&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;em&gt;N/S&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1,0,0&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;VM obtains IPv6 address from radvd using SLAAC&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;dhcpv6-
stateful&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;em&gt;N/S&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0,1,1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;VM obtains IPv6 address and optional info from external
DHCPv6 server using DHCPv6 stateful&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;dhcpv6-
stateless&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;&lt;em&gt;N/S&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1,0,1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;VM obtains IPv6 address from radvd using SLAAC and
optional info from external DHCPv6 server using
DHCPv6 stateless&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;slaac&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;slaac&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1,0,0&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;VM obtains IPv6 address from OpenStack radvd using SLAAC&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;dhcpv6-
stateful&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dhcpv6-
stateful&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0,1,1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;VM obtains IPv6 address from dnsmasq using DHCPv6 stateful
and optional info from dnsmasq using DHCPv6 stateful&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;dhcpv6-
stateless&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dhcpv6-
stateless&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1,0,1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;VM obtains IPv6 address from radvd using SLAAC and
optional info from dnsmasq using DHCPv6 stateless&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;slaac&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dhcpv6-
stateful&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;&lt;em&gt;Invalid combination&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;slaac&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dhcpv6-
stateless&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;&lt;em&gt;Invalid combination&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;dhcpv6-
stateful&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;slaac&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;&lt;em&gt;Invalid combination&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;dhcpv6-
stateful&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dhcpv6-
stateless&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;&lt;em&gt;Invalid combination&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;dhcpv6-
stateless&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;slaac&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;&lt;em&gt;Invalid combination&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;dhcpv6-
stateless&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;dhcpv6-
stateful&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;&lt;em&gt;Invalid combination&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;N/S&lt;/em&gt; = &lt;em&gt;Not Specified&lt;/em&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;There is no security impact directly related to radvd, but it should be noted
that the default security group settings for IPv6 interfaces allow RAs from Neutron
routers and/or from the subnet’s default gateway.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;CLI changes?&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;This change introduces one radvd instance per router namespace that is created
by neutron. The radvd instances may load new configuration data when interfaces
are added into or removed from the namespaces. Significant system performance
degradation is not expected.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;install radvd&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;config options&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;gessau&amp;gt; Henry Gessau&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;anthony-veiga&amp;gt; Anthony Veiga&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;baoli&amp;gt; Robert Li&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;leblancd&amp;gt; Dane Leblanc&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&amp;lt;scollins&amp;gt; Sean Collins&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;L3 agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;dhcp agent&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;IPv6 two attributes &lt;a class="reference internal" href="#bp-2attr" id="id4"&gt;&lt;span&gt;[BP_2ATTR]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update SG when gateway address changes &lt;a class="reference internal" href="#pv-sg-ra" id="id5"&gt;&lt;span&gt;[PV_SG_RA]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Consolidated L3 agent? &lt;a class="reference internal" href="#bp-consl3" id="id6"&gt;&lt;span&gt;[BP_CONSL3]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;radvd package &lt;a class="reference internal" href="#radvd" id="id7"&gt;&lt;span&gt;[RADVD]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note: For each SLAAC-enabled subnet, the Neutron L3 Agent will need to either
detect or anticipate which specific IPv6 address is generated by each
host. Note that for the initial release of IPv6 in OpenStack, the ability to
anticipate or derive each SLAAC-generated address was added with the change set
for &lt;a class="reference internal" href="#bp-pv-slaac" id="id8"&gt;&lt;span&gt;[BP_PV_SLAAC]&lt;/span&gt;&lt;/a&gt;. This algorithm assumes that interface IDs used in forming
addresses are generated using EUI-64.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Full unit test coverage.&lt;/p&gt;
&lt;p&gt;Look into the feasibilty of adding functional tests. (Not currently considered
essential.)&lt;/p&gt;
&lt;p&gt;Add tempest tests like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;API tests for network/subnet create for each of the modes (see &lt;a class="reference internal" href="#api-tests" id="id9"&gt;&lt;span&gt;[API_TESTS]&lt;/span&gt;&lt;/a&gt;):&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;unspec/unspec, SLAAC/SLAAC, stateful/stateful, stateless/stateless&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scenario ping test for SLAAC/SLAAC, stateful/stateful, stateless/stateless&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;How to configure IPv6 addressing. Overview for Neutron and specifically for
subnets.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;div role="list" class="citation-list"&gt;
&lt;div class="citation" id="radvd" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;RADVD&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id7"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.litech.org/radvd/"&gt;Linux IPv6 Router Advertisement Daemon (radvd)&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="bp-2attr" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id4"&gt;BP_2ATTR&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ipv6-two-attributes"&gt;Two Attributes Proposal to Control IPv6 RA Announcement and
Address Assignment&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="rfc-4861" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;RFC_4861&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://tools.ietf.org/html/rfc4861"&gt;Neighbor Discovery for IP version 6 (IPv6)&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="two-mode" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;TWO_MODE&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.dropbox.com/s/9bojvv9vywsz8sd/IPv6%20Two%20Modes%20v3.0.pdf"&gt;IPv6 Two Modes v3.0.pdf&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="bp-pv-slaac" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id8"&gt;BP_PV_SLAAC&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ipv6-provider-nets-slaac"&gt;Provider Networking - upstream SLAAC support&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="bp-consl3" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;BP_CONSL3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/l3-agent-consolidation"&gt;L3 agent consolidation&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="api-tests" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;API_TESTS&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/100134"&gt;Add IPv6 API test cases for Neutron Subnet API&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="pv-sg-ra" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;PV_SG_RA&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1290252"&gt;Router RA rule need to be updated when router is created after
VM port&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
</description><pubDate>Thu, 19 Jun 2014 00:00:00 </pubDate></item><item><title>Add ipset to security group</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/add-ipset-to-security.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/add-ipset-to-security"&gt;https://blueprints.launchpad.net/neutron/+spec/add-ipset-to-security&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now neutron uses iptables to achieve security group functions, but iptables
chain is linear storage and filtering, we can use ipset to improve security
group’s performance.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Now neutron uses iptables to achieve security group functions, but there are
following problems.&lt;/p&gt;
&lt;p&gt;Problem 1:
When a security group has many rules between other security group, this would
affect security group’s performance.&lt;/p&gt;
&lt;p&gt;Problem 2:
When a port is updated, the security group chain related to that port will
be destroyed and rebuilt, this would affect L2 agent’s performance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposal is to improve security group performance based on existing
security group agent codes.&lt;/p&gt;
&lt;p&gt;In L2 agent, it makes use of ipset to optimize the iptables rule chain. When a
port is created, L2 agent will add a additional ipset chain to it’s iptables
chain, if the security group that this port belongs to has rules between other
security group, the member of that security group will add to ipset chain.&lt;/p&gt;
&lt;p&gt;When a port is created in default security group, its corresponding iptables
rules in L2 agent like these(old result):
-A neutron-openvswi-i92605eaf-b -m state –state INVALID -j DROP
-A neutron-openvswi-i92605eaf-b -m state –state RELATED,ESTABLISHED -j RETURN
-A neutron-openvswi-i92605eaf-b -s 192.168.83.20/32 -j RETURN
-A neutron-openvswi-i92605eaf-b -s 192.168.83.19/32 -j RETURN
-A neutron-openvswi-i92605eaf-b -s 192.168.83.16/32 -j RETURN
-A neutron-openvswi-i92605eaf-b -s 192.168.83.17/32 -j RETURN
-A neutron-openvswi-i92605eaf-b -s 192.168.83.18/32 -j RETURN
-A neutron-openvswi-i92605eaf-b -s 192.168.83.15/32 -j RETURN&lt;/p&gt;
&lt;p&gt;The new iptables rules by using ‘iptables+ipset’ like these:
-A neutron-openvswi-i92605eaf-b -m state –state INVALID -j DROP
-A neutron-openvswi-i92605eaf-b -m state –state RELATED,ESTABLISHED -j RETURN
-A neutron-openvswi-i92605eaf-b -m set –match-set ${ipset_name} src -j RETURN&lt;/p&gt;
&lt;p&gt;The ipset chain like this:
Name: ${ipset_name}
Type: hash:ip
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16632
References: 1
Members:
192.168.83.16
192.168.83.17
192.168.83.15
192.168.83.18
192.168.83.19
192.168.83.20&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;1) iptables-save/iptables-load time will be greatly reduced, as we just need to
modify one ipset per security group, and not all the bunch of duplicated rules
per port.&lt;/p&gt;
&lt;p&gt;2) With iptables, kernel has to linearly go evaluating after all iptables rules
in chain order, while for an ipset in iptables, a lots of rules will become
into a “hash” with much faster evaluation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Considered a deployer doesn’t provide ipset in their system, using
‘iptables+ipset’ to enhance security group will be optional.
A configuration flag will be added to L2 agent configuration file:&lt;/p&gt;
&lt;p&gt;[securitygroup]
enable_ipset_enhancement = False&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~shihanzhang"&gt;https://launchpad.net/~shihanzhang&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~mangelajo"&gt;https://launchpad.net/~mangelajo&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Improve ‘security_group_rules_for_devices’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add ipset chain in ‘_add_rule_by_security_group’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests should be enough, as this is to optimize already existing
functionality which is already covered by tempest&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://ipset.netfilter.org"&gt;http://ipset.netfilter.org&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 18 Jun 2014 00:00:00 </pubDate></item><item><title>LBaaS Driver Interface changes for new Object Model</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/lbaas-objmodel-driver-changes.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-objmodel-driver-changes"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-objmodel-driver-changes&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The upcoming LBaaS object model and API changes for Juno will require some
driver interface changes, for new objects and backwards compatibility.&lt;/p&gt;
&lt;p&gt;New interfaces include create_load_balancer (and the rest of crud) and
create_listener.  Create_vip is going away, and will be supported in a shim
layer for older drivers.  M:N health monitor associations are also going away.&lt;/p&gt;
&lt;p&gt;The new object model and API blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint does not cover changes for the new TLS or L7 functionality.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;With the upcoming LBaaS object model and API changes, we will need new
interfaces for the backend load balancing drivers, and a shim layer so that
things continue to work with older drivers during a depcrecation period.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;When loading the driver, neutron will determine if it is a new object model
driver or an older legacy driver, and pick an appropriate implemenation/shim
class depending on which.&lt;/p&gt;
&lt;p&gt;The new driver interface methods will be passed objects with attributes,
instead of dictionaries as used in the icehouse drivers.  For expediency’s
sake, initially these objects will be the standard neutron sqlalchemy objects,
but full sqlalchemy functionality is not guaranteed in the future.  Basic
attributes and dependent object lookups will be supported long-term.&lt;/p&gt;
&lt;p&gt;The new driver interface will be made up of handler classes that implement
create, update, and delete methods.  Example, subject to change:&lt;/p&gt;
&lt;p&gt;sample_driver.py:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;SampleDriver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LoadBalancerAbstractDriver&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load_balancer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyLoadBalancerManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;listener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;member&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ef&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MemberHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xyz&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatsGatherer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;health_monitor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HMHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyLoadBalancerManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseManager&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lb_obj&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"create"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lb_obj&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"update"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lb_obj&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"delete"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Supported driver handlers:
* load_balancer
* listener
* pool
* member
* health_monitor
* stats&lt;/p&gt;
&lt;p&gt;The following older driver methods will be translated/supported.  Differences
from existing behavior are noted next to each method.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create_vip - combination of one load_balancer and listener object from above.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update_vip&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete_vip&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create_pool - first object created&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update_pool&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete_pool&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;stats&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create_member&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update_member&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete_member&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update_pool_health_monitor&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create_pool_health_monitor&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete_pool_health_monitor&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Limitations of older driver shim:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Multiple listeners on a load balancer is not supported.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multiple pools on a listener is not supported.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Many-to-many associations for health monitors is not supported.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subnet id’s on member objects are not supported.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Driver breakage:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Some references to ldb.Vip will break until their maintainers update the
relevant driver (embrane, radware).  Tests for those drivers will be
temporarily disabled until fixed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;One proposed alternative for the backwards compatibility shim layer for the
drivers is to create a completely separate new LBaaS extension/plugin, with
completely separate database tables, and let both exist.  This would involve
duplicate drivers and db tables.  We decided not to use this approach, and
the general implementation plan for the lbaas api/driver changes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create new LBaaS extension using database tables that have merged fields
between old and new model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change front-end of old extension to “translate” into operations on new model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Changer drivers to use new model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deprecate / delete unused old model fields from database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deprecate / delete old front-end.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None, refer to object model blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None, refer to object model blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None, same impact as current driver implementations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None, same impact as current driver implementations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Upgrade to new LBaaS will involve a db migration; refer to object model
blueprint.  Older LBaaS drivers will continue to work, except that attempting
to add multiple listeners to a load balancer will fail.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Current LBaaS driver maintainers will need to eventually update their drivers
to the new interface.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~brandon-logan"&gt;https://launchpad.net/~brandon-logan&lt;/a&gt;
&lt;a class="reference external" href="https://launchpad.net/~dougwig"&gt;https://launchpad.net/~dougwig&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Modify layer above drivers to call new entry points.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify layer above drivers to call old driver interface methods for older
drivers, translating the newer object model as needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New abstract_driver with new interfaces.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Updating the reference haproxy driver will be in another blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Existing tests against older drivers will continue to pass, unless testing
the M:N health monitor relationship.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New tests will be added for new entry points will be added when the reference
driver is updated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Broken drivers, as specified in “Proposed change”, will result in disabled
tests until the drivers are fixed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement"&gt;https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/1gsTm4GBdu"&gt;https://etherpad.openstack.org/p/1gsTm4GBdu&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/juno-lbaas-mid-cycle-hackathon"&gt;https://etherpad.openstack.org/p/juno-lbaas-mid-cycle-hackathon&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 17 Jun 2014 00:00:00 </pubDate></item><item><title>SecurityGroup  Extension support for Nuage Plugin</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/securitygroup-ext-for-nuage-plugin.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/securitygroup-ext-for-nuage-plugin"&gt;https://blueprints.launchpad.net/neutron/+spec/securitygroup-ext-for-nuage-plugin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Adding securitygroup extension support to existing nuage networks’ Plugin&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Current Nuage Plugin does not support Neutron’s securitygroup extension.
Nuage’s VSP supports this feature and the support for extension needs
to be added in the plugin code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Adding extension support code in Nuage plugin.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Existing securitygroup tables in neutron will be supported.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;VSP’s securitygroup equivalent object’s scope is either per router or per subnet.
Where Neutron’s is per tenant. Because of this, the mapping between
neutron and VSP resource always happens at the port create or update time; such
that port’s router/subnet is known and thus sg attachment point in VSP is known.
Following workflow can be imagined:
1) neutron security-group-create sg1
No-op from VSP point of view
2) neutron security-group-rule-create –direction ingress –protocol tcp –port_range_min 80 –port_range_max 80 &amp;lt;sg-id&amp;gt;
No-op from VSP point of view
3a) neutron port-create 9d0b9f4a-1a72-4c17-a538-06ee7501d185 –name sub1 –security-group 8eb7ee8e-6d15-4a0d-b13a-0affeba438ae
3b) neutron port-update 71083f7d-1450-4bee-9c40-728b7ffd2876 –security-group c6c08246-bad7-4d82-a0ad-4a42327c9516
If this is the first port getting attached to that security-group,
this is where corresponding vport-tag (for sg) and rules (for sg-rules) are created on VSP.
Subsequent port-create/update for this sg will simply increment counter and add value to vport to vporttag
mapping.&lt;/p&gt;
&lt;p&gt;Similarly, when the last port attached to this group is deleted, the vport-tag(sg) and the rules(vptag rules)
will be deleted.&lt;/p&gt;
&lt;p&gt;CRUD operation on securitygroup will be supported in normal fashion.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Ronak Shah&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;ronak-malav-shah&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;divya.hc&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Extension code in Nuage plugin
Nuage Unit tests addition
Nuage CI coverage addition&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit Test coverage for security-group extension within Nuage unit test
Nuage CI will be modified to start supporting this extension tests&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 16 Jun 2014 00:00:00 </pubDate></item><item><title>Support DHCPv6 stateless and stateful mode in Dnsmasq</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/ipv6-dnsmasq-dhcpv6-stateless-stateful.html</link><description>

&lt;p&gt;As &lt;a class="reference internal" href="#spec-radvd" id="id1"&gt;&lt;span&gt;[Spec_RADVD]&lt;/span&gt;&lt;/a&gt; is proposed to use radvd as the preferred reference
implementation for IPv6 Router Advertisements and SLAAC, this spec is
to allow tenant VM to obtain stateful dhcpv6 address or stateless
dhcpv6 address by Dnsmasq when ipv6_address_mode of a tenant subnet is set.&lt;/p&gt;
&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/dnsmasq-ipv6-dhcpv6-stateless"&gt;https://blueprints.launchpad.net/neutron/+spec/dnsmasq-ipv6-dhcpv6-stateless&lt;/a&gt;
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/dnsmasq-ipv6-dhcpv6-stateful"&gt;https://blueprints.launchpad.net/neutron/+spec/dnsmasq-ipv6-dhcpv6-stateful&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;1. When dhcpv6 stateful is set as IPv6 address mode of a tenant subnet,
OpenStack admin wishes tenant VMs can obtain IPv6 address and optional
info (such as DNS info) from OpenStack network service.&lt;/p&gt;
&lt;p&gt;2. When dhcpv6 stateless is set as IPv6 address mode of a tenant subnet,
router advertisement is taken care of by either external router or
OpenStack managed RADVD. OpenStack admin wishes tenant VMs can obtain
IPv6 address by SLAAC and obtain optional info from OpenStack network
service.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+----------------------------------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                                                      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                                                      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                                                      &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;+---------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+------------------------------+&lt;/span&gt;     &lt;span class="o"&gt;+---------------------------+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;                                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dhcp&lt;/span&gt; &lt;span class="n"&gt;namespace&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+--------------+&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+-----------+&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;namespace&lt;/span&gt;  &lt;span class="o"&gt;+----------+&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;dnsmasq&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;RADVD&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+-+---+-----+--------+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+----+--------+++&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+-------&amp;gt;&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;qdhcp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;xxxx&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;xxxx&lt;/span&gt;  &lt;span class="o"&gt;||&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+-------+------+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+----+---------+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+-----&amp;gt;&lt;/span&gt;  &lt;span class="n"&gt;VM&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+------------------------------+&lt;/span&gt;     &lt;span class="o"&gt;+---------------------------+&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+-------+------+&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;                                &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;+--+--------------------------------+-+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+--------+--------+&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;+------------------+------------------+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+--------+--------+&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;+------+------+&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;eth0&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+---------------+&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;+------+------+&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;eth0&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+---------------+&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="o"&gt;+-----+-----+&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+------+-------+&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="n"&gt;eth0&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;eth0&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------------------+-----+-----+----------------------------+&lt;/span&gt;    &lt;span class="o"&gt;+--------+-------+------+---------+&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;                           &lt;span class="o"&gt;+--------------------------------------------------------+&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;                                                     &lt;span class="o"&gt;|&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;+------------------------------------------------------------------------+&lt;/span&gt;
                             &lt;span class="n"&gt;IPv6&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;optional&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;RA&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
                                                              &lt;span class="o"&gt;+----------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;According to &lt;a class="reference internal" href="#dnsmasq-manpage" id="id2"&gt;&lt;span&gt;[DNSMASQ_MANPAGE]&lt;/span&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;1. DHCPv6 stateless mode: dnsmasq in ‘static’ mode with ‘–dhcp-optsfile’
option specified can be leveraged to use dnsmasq as a simple stateless
dhcp server.&lt;/p&gt;
&lt;p&gt;2. DHCPv6 stateful mode: dnsmasq in ‘static’ mode with ‘–dhcp-hostsfile’
and ‘–dhcp-optsfile’ options specified can be leveraged to use dnsmasq
as stateful dhcp server.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;In Icehouse release, ipv6_ra_mode and ipv6_address_mode are introduced
to subnet API to enable tenant network IPv6 support.&lt;/p&gt;
&lt;p&gt;Rest API change for IPv6 modes in Icehouse reference: &lt;a class="reference internal" href="#ipv6-modes-rest" id="id3"&gt;&lt;span&gt;[IPv6_MODES_REST]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint will implement the functionality required to satisfy
IPv6 Subnets with ipv6_address_mode set to ‘dhcpv6-stateful’ or
‘dhcpv6-stateless’.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This change will require support in python-neutronclient for the two
IPv6 subnet attributes - which is currently in &lt;a class="reference external" href="https://review.openstack.org/#/c/75871/"&gt;review&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This change will change the behavior of Neutron in specific
configurations, when the IPv6 attributes for Subnets are set.
Previously, the attributes were no-ops.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Subnets will be created with ‘ipv6_address_mode’ set to
‘dhcpv6-stateful’ or ‘dhcpv6-stateless’.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If no dnsmasq process for subnet’s network is launched,
Neutron will launch new dnsmasq process on subnet’s dhcp port
in ‘qdhcp-‘ namespace. If previous dnsmasq process is already
launched, restart dnsmasq with new configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron will update dnsmasq process and restart it when subnet gets
updated.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Shixiong&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;xuhanp&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Break down this &lt;a class="reference external" href="https://review.openstack.org/#/c/70649"&gt;code review&lt;/a&gt;
into smaller patches, and submit new code review for dhcpv6
stateful/stateless mode.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The assumption of this spec is Router Advertisement is provided by
either provider network router or OpenStack Network Service (One
implementation is RADVD &lt;a class="reference internal" href="#spec-radvd" id="id4"&gt;&lt;span&gt;[Spec_RADVD]&lt;/span&gt;&lt;/a&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bump DNSMASQ version to 2.63 to support IPv6 tag. &lt;a class="reference internal" href="#dnsmasq-verstion" id="id5"&gt;&lt;span&gt;[DNSMASQ_VERSTION]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add unit tests to support Subnets created with the ipv6_address_mode
set to ‘dhcpv6-stateful’ or ‘dhcpv6-stateless.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify that dnsmasq can be launched with expected mode and options,
in correct namespace.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add tempest API and scenairo tests for stateful and stateless dhcpv6.
Reference: &lt;a class="reference internal" href="#api-tests-ipv6" id="id6"&gt;&lt;span&gt;[API_TESTS_IPV6]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation about this network configuration will need to be
written.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;div role="list" class="citation-list"&gt;
&lt;div class="citation" id="spec-radvd" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;Spec_RADVD&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id4"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/101306"&gt;Spec for adding support for radvd for IPv6 SLAAC&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="dnsmasq-manpage" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;DNSMASQ_MANPAGE&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html"&gt;DNSMASQ man page&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="api-tests-ipv6" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;API_TESTS_IPV6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/100134"&gt;Add IPv6 API test cases for Neutron Subnet API 254&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="dnsmasq-verstion" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;DNSMASQ_VERSTION&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1233339"&gt;DNSMASQ minimum version for IPv6&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="citation" id="ipv6-modes-rest" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;IPv6_MODES_REST&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;cite&gt;Rest API change for IPv6 modes in Icehouse&lt;/cite&gt;
&amp;lt;&lt;a class="reference external" href="http://docs-draft.openstack.org/43/88043/9/gate/gate-neutron-specs-docs/82c251a/doc/build/html/specs/juno/ipv6-provider-nets-slaac.html#rest-api-impact"&gt;http://docs-draft.openstack.org/43/88043/9/gate/gate-neutron-specs-docs/82c251a/doc/build/html/specs/juno/ipv6-provider-nets-slaac.html#rest-api-impact&lt;/a&gt;&amp;gt;_&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
</description><pubDate>Thu, 12 Jun 2014 00:00:00 </pubDate></item><item><title>OFAgent: Merge br-int and br-tun</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/ofagent-merge-bridges.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ofagent-merge-bridges"&gt;https://blueprints.launchpad.net/neutron/+spec/ofagent-merge-bridges&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;merge br-int and br-tun and stop using OVS patch ports feature.
this involves drastic flow table changes.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;ofagent aims to be portable among switch implementations.
currently it uses some of OVS specific features.
patch ports is one of them.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;merge br-int and br-tun into a single bridge.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;give up and declare that tunnel support is only for OVS.  this is not
what we want to do.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;use veth pair instead.  this is not ideal as it still requires
multiple logical bridge feature.  besides that, it likely involve
some performance loss because patch ports is better optimized than
veth pair.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;because OVS patch ports hardly have negative performace effects for fast path,
this change is not expected to improve performance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;when upgrading the agent, deployer might want to remove br-tun.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;yamamoto&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;kakuma&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;design flow table.  see &lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/OFAgent/FlowTable"&gt;flow_table&lt;/a&gt; for WIP design.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;implement it in ofagent neutron agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;document the upgrade procedure&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;strictly speaking, none.
but the following items are nice to have before this.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/l2-population"&gt;ofagent-l2pop&lt;/a&gt; blueprint (our WIP implementation relies on this)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;matrohon’s &lt;a class="reference external" href="https://review.openstack.org/#/c/96181/"&gt;get_device_details-enhancement&lt;/a&gt;.
or other way to obtain device’s mac_address.
(for example, make l2pop provide device-id for entries.)
we want to use it for node local routing of packets.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;existing third party testing&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;document the upgrade procedure&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;WIP flow table for this blueprint
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/OFAgent/FlowTable"&gt;https://wiki.openstack.org/wiki/Neutron/OFAgent/FlowTable&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;WIP implementation of the above
&lt;a class="reference external" href="https://github.com/yamt/neutron/tree/ofagent-merge-bridges"&gt;https://github.com/yamt/neutron/tree/ofagent-merge-bridges&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 09 Jun 2014 00:00:00 </pubDate></item><item><title>Migrate to oslo-messaging</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/oslo-messaging.html</link><description>

&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Neutron currently uses an older version of Oslo’s RPC code which is being
deprecated in favor of oslo.messaging.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Neutron will be updated to utilize oslo.messaging and the copied code from
oslo-incubator will be removed from the tree.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.  oslo.messaging is the only supported RPC framework from the Oslo team.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;The content of the notifications should not change; however, configuration
options will slightly change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The underlying library uses the compatible wire format, so users upgrading
should not be impacted.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;This is a code refactor for a new library api, so performance changes will be
minimal.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Configuration options will change slightly to utilize the standard set from
oslo.messaging. The options are standard across other OpenStack projects, so
deployers will benefit from the standardization.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.  Shims will be used to provide compatibility with internal code
interfaces.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;ihrachys&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Introduce shims modules for existing RPC classes with Neutron&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Introduce exception compatibility layer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Convert shims to use oslo.messaging constructs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Future work could include removal of shims, but this can be done later.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Exisiting Unit, Functional, and Tempest tests will ensure the refactor does
not introduce any regressions.  Grenade testing should validate that the
message payload are compatible.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Messaging configuration will need to be updated to reflect the set of options
provided by oslo.messaging.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 09 Jun 2014 00:00:00 </pubDate></item><item><title>Layer 3 service plugin to support hardware based routing on Arista devices</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/arista-l3-service-plugin.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/arista-l3-service-plugin"&gt;https://blueprints.launchpad.net/neutron/+spec/arista-l3-service-plugin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint is to implement a L3 service plugin to support hardware based
Layer 3 routing in Arista devices.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;This service plugin implements neutron L3 routing features on Arista hardware.
It communicates with Arista hardware fabric over JSON RPC to automate
the provisioning of routing on Arista devices (both at leaf and spine layer).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This proposal is to introduce a new Layer 3 service plugin that uses JSON RPC to
to communicate with Arista hardware fabric to provide full L3 routing functionality.&lt;/p&gt;
&lt;p&gt;This plugin works in conjuction with Arista ML2 Driver, which manages the
networks, subnets, and ports.
This service plugin and ML2 Driver leverage the resources and topology knowledge
to facilitate the automation of L2 and L3 provisioning in Arista hardware.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The alternative approach is to use the open source agent based layer 3 router
plugin and update the L3 agent to interact with Arista Hardware.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;n.a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;n.a&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;n.a.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;n.a.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;This service plugin is event based triggered. No polling is deployed.
There are no changes to any existing code patterns. Note that the events here
means invocation of the APIs.
This plugin uses JSON RPC to communicate with Arista hardware. Arista ML2 Driver
uses the same mechanism and implements bulk operations to support scale
deployements. This plugin will leverage the same mechanisms.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Configuration knobs will be provided to the adminstrators to take advantage of
various deployment topologies supported by Arista fabric. These configuration
knobs will be documented on OpenStack wiki.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;n.a.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Sukhdev Kapur
&lt;a class="reference external" href="mailto:sukhdev%40arista.com"&gt;sukhdev&lt;span&gt;@&lt;/span&gt;arista&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;
IRC - Sukhdev&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;L3 Service Plugin&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DevStack related enhancements to support this plugin&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Complete unit test coverage of the code will be provided.&lt;/p&gt;
&lt;p&gt;For full tempest test coverage, Arista third party testing is implemented
and is described at the following wiki.
With implementation of this Plugin, the test list will be updated. For example,
Floating IP related tests will be removed and L3 routing function tests will be
included. The updated list of tests will be published.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Arista-third-party-testing"&gt;https://wiki.openstack.org/wiki/Arista-third-party-testing&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation to configure and deploy this service plugin will be provided
in the Openstack wiki.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;n.a.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Sun, 01 Jun 2014 00:00:00 </pubDate></item><item><title>Add support for Keystone V3 APIs in the python-neutronclient.</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/keystone-v3-api-support.html</link><description>

&lt;section id="url-of-the-launchpad-blueprint"&gt;
&lt;h2&gt;URL of the launchpad blueprint:&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/python-neutronclient/+spec/keystone-api-v3-support"&gt;https://blueprints.launchpad.net/python-neutronclient/+spec/keystone-api-v3-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint is meant to capture the changes necessary to the
python-neutronclient to integrate with python-keystoneclient for authentication
and session management.  All clients have this requirement.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h3&gt;Problem description&lt;/h3&gt;
&lt;p&gt;Python-neutronclient lacks Keystone V3 support. Furthermore, it is duplicating
python-keystoneclient logic by maintaining its own version of Keystone V2
authentication API and session management (i.e. endpoint lookup). A major
drawback with this approach is that it must be constantly updated in response
to any Keystone API changes. Maintenance is also a burden as authentication
and session management are not consistent across all OpenStack Python clients.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h3&gt;Proposed change&lt;/h3&gt;
&lt;p&gt;Utilizing python-keystoneclient for authentication and session management
so that they are completely abstracted from python-neutronclient. The changes
are twofold, CLI (shell) and SDK (Client).&lt;/p&gt;
&lt;section id="cli"&gt;
&lt;h4&gt;CLI&lt;/h4&gt;
&lt;p&gt;For CLI, the global identity arguments, which are common to all the OpenStack
Python clients, should be provided and facilitated by python-keystoneclient.
Python-neutronclient does not need to know about them. It simply need a way
to convey them to the end users. Therefore, the following global identity
arguments will be isolated and eventually be facilitated by
python-keystoneclient:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-auth-url&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–insecure&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-cacert&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-cert&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-key&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-token&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-username&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-user_id&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-password&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-user-domain-id&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-user-domain-name&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-tenant-name&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-tenant-id&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-project-name&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-project-id&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-project-domain-id&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-project-domain-name&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-region-name&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-service-type&lt;/em&gt; (Default to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network&lt;/span&gt;&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-endpoint-type&lt;/em&gt; (Default to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;publicURL&lt;/span&gt;&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-url&lt;/em&gt; (DEPRECATED, should be using &lt;em&gt;–os-endpoint&lt;/em&gt; instead)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-endpoint&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;–os-auth-strategy&lt;/em&gt; (DEPRECATED, absence of &lt;em&gt;–os-auth-url&lt;/em&gt; signify no auth)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="client"&gt;
&lt;h4&gt;Client&lt;/h4&gt;
&lt;p&gt;Use &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;keystoneclient.session.Session&lt;/span&gt;&lt;/code&gt; for session management and
python-keystoneclient auth plugin for authentication. This is done by
introducing two optional arguments, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;session&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;auth&lt;/span&gt;&lt;/code&gt;,  to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutronclient.common.clientmanager.ClientManager&lt;/span&gt;&lt;/code&gt; class:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ClientManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""Manages access to API clients, including authentication.&lt;/span&gt;
&lt;span class="sd"&gt;    """&lt;/span&gt;
    &lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ClientCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;neutron_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;make_client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Provide support for old quantum commands (for example&lt;/span&gt;
    &lt;span class="c1"&gt;# in stable versions)&lt;/span&gt;
    &lt;span class="n"&gt;quantum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;neutron&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;auth_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;endpoint_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;tenant_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;api_version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;auth_strategy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;insecure&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;ca_cert&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;log_credentials&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;service_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;
                 &lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Where caller can optionally pass in an instance of
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;keystoneclient.session.Session&lt;/span&gt;&lt;/code&gt; in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;session&lt;/span&gt;&lt;/code&gt; and an instance of
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;keystoneclient.auth.base.BaseAuthPlugin&lt;/span&gt;&lt;/code&gt; in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;auth&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;session&lt;/span&gt;&lt;/code&gt; is provided, we shall use it for HTTP session management instead
of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutronclient.client.HTTPClient&lt;/span&gt;&lt;/code&gt;. This is done by providing shims for the
the existing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutronclient.client.HTTPClient&lt;/span&gt;&lt;/code&gt; to preserve backward
compatibility.&lt;/p&gt;
&lt;p&gt;Changes to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutronclient.client&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;SessionHTTPClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HTTPClient&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""Shims for HTTPClient.&lt;/span&gt;

&lt;span class="sd"&gt;    Requests are delegated to keystoneclient Session.&lt;/span&gt;
&lt;span class="sd"&gt;    """&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;service_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'network'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;endpoint_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'publicURL'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;_construct_http_client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'session'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'auth'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;SessionHTTPClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;HTTPClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutronclient.common.clientmanager.ClientManager&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutronclient.v2_0.client.Client&lt;/span&gt;&lt;/code&gt;, instead of instantiating
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutronclient.client.HTTPClient&lt;/span&gt;&lt;/code&gt;, it will just call
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutronclient.client._construct_http_client&lt;/span&gt;&lt;/code&gt; to get a HTTP client
object.&lt;/p&gt;
&lt;p&gt;At some point in the future if we choose to completely remove the old HTTPClient,
we should also remove the ServiceCatalog class and all the home-grown parsing
that goes with it.  It’s much cleaner to simply let the keystone client do
all that parsing.  bklei will add a fixme comment in the code to note that
for future cleanup.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h4&gt;Alternatives&lt;/h4&gt;
&lt;p&gt;None – this is a required change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h4&gt;Data model impact&lt;/h4&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h4&gt;REST API impact&lt;/h4&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h4&gt;Security impact&lt;/h4&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h4&gt;Notifications impact&lt;/h4&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h4&gt;Other end user impact&lt;/h4&gt;
&lt;p&gt;In order to authenticate with V3 in keystone, if a username is provided
for authentication, the user’s domain name or id must also be provided.
Similarly, if a tenant/project name is provided, the tenant’s domain name
or id must also be specified.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h4&gt;Performance Impact&lt;/h4&gt;
&lt;p&gt;Shouldn’t be any – the same calls to keystone are being made, just via
the keystone client instead of the neutron specific HTTPClient.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h4&gt;Other deployer impact&lt;/h4&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h4&gt;Developer impact&lt;/h4&gt;
&lt;p&gt;Same as the end user impact.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h3&gt;Implementation&lt;/h3&gt;
&lt;section id="assignee-s"&gt;
&lt;h4&gt;Assignee(s)&lt;/h4&gt;
&lt;p&gt;Bradley Klein (bklei)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h4&gt;Work Items&lt;/h4&gt;
&lt;p&gt;Need to import the keystone client session and auth plugin, and construct
both to authenticate.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h3&gt;Dependencies&lt;/h3&gt;
&lt;p&gt;None, the keystone client already provides what is needed for this change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;p&gt;Unit testing comprehensively tests the keystone integration, those tests will
be modified/enhanced to also test the new V3 code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h3&gt;Documentation Impact&lt;/h3&gt;
&lt;p&gt;The new domain specific parameters for the neutron command should be documented.
It would also probably make sense to mention that the python-keystoneclient
supports both v2 and v3 auth based on the value provided by auth-url.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h3&gt;References&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 29 May 2014 00:00:00 </pubDate></item><item><title>Neutron OVS agent - Dont Fragment flag</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/neutron-ovs-agent-df-gre-vxlan.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/neutron-ovs-agent-df-gre-vxlan"&gt;https://blueprints.launchpad.net/neutron/+spec/neutron-ovs-agent-df-gre-vxlan&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Overlay network introduce an additionnal overhead. Depends on the underlying
protocol and physical transport the ‘real’ MTU may have strong constraints.
However, from an instance, or a cloud user point of view, this should not be
a problem. And the Ethernet MTU inside VM should be, when possible, at least
1500 bytes.&lt;/p&gt;
&lt;p&gt;Thus when using overlay protocol -here GRE and VXLAN- that use IP, it is
possible under certain conditions to leverage the Dont Fragment -DF- bit. Once
that bit will be set to 0, it will allow encapsulated packet to be split by
the IP stack of the hypervisor. The main goal is to allow 1500 bytes MTU
overlayed network to cross 1500 byte MTU physical network.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The problem is to span overlayed network on physical network with a smaller (or
equal MTU). As said before, the main usecase is to carry 1500 bytes MTU virtual
network over 1500 bytes MTU physical network. It’s mainly required on older
network part. Once the network will be upgraded, the MTU on physical adapter
will be raised, and no fragementation will happen anymore.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Set the options:df_default option in OVS when creating VXLAN and GRE tunnels.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Use iptables with -j DF –clear somewehere.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;IP fragmentation could impact the network efficiency and causes some
additional load on network nodes&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;It will ease some deployments by being able to span virtual networks over
MTU-limited physical network.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;pierre-rognant&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The work concern only the OVS agent. No impact on other neutron component.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Ensure that the default behaviour remains unchanged.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Add the new ‘dont_fragment’ flag in the documentation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;OVS reference documentation:
* &lt;a class="reference external" href="http://openvswitch.org/ovs-vswitchd.conf.db.5.pdf"&gt;http://openvswitch.org/ovs-vswitchd.conf.db.5.pdf&lt;/a&gt; (p. 24)&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 28 May 2014 00:00:00 </pubDate></item><item><title>Remove openvswitch run-time version checks</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/remove-openvswitch-version-check.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/remove-openvswitch-version-check"&gt;https://blueprints.launchpad.net/neutron/+spec/remove-openvswitch-version-check&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The current method of checking openvswitch and kernel versions for specific
feature support is brittle, distro-specific and unsupportable.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;When VXLAN tunnels are enabled, openvswitch-using agents call ovs_lib code to
check that the installed kernel and openvswitch versions are greater than a
minimum specified version. Due to distro-specific differences in 1) the fields
returned by modinfo and 2) the minimum required version due to the practice of
backporting, this run-time checking method fails.&lt;/p&gt;
&lt;p&gt;In addition to VXLAN, other specific openvswitch features will need to be
tested for in the future. As the number of features and versions and distros
grows, checking version numbers becomes increasingly unsustainable and should
not be done at agent start, but instead at package installation or deployment.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Trying to test features by version numbers across multiple distros is a fool’s
errand. It is much better to leave dependency management to the distros and
packaging as they are the only ones who really know what version dependencies
exist in their environment. The run-time checks should be completely removed
from ovs_lib and the agents.&lt;/p&gt;
&lt;p&gt;If an attempt is made to use a specific openvswitch feature fails, a helpful
error message suggesting that updating openvswitch &lt;em&gt;may&lt;/em&gt; resolve the issue
should be logged.&lt;/p&gt;
&lt;p&gt;To help deployment tools, a script will be created that attempts to use
specific openvswitch features and exits 0 for success and 1 for failure. This
way a deployment can be aborted, e.g. in devstack, if the feature is enabled
but not available in the current openvswitch/kernel versions without trying
to keep track of version numbers or incurring a messy run-time feature check
at agent start.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Openvswitch does not have the ability to query whether it supports certain
features, so the only way to reliably test whether a feature exists at runtime
is to try to use the feature and see if it works. It would be possible, but
unacceptably messy, to attempt to use all required OVS features at agent start
and exit the agent on failure. Dependency management should be handled at
packaging and/or deployment and not checked every time an agent is started by
modifying system state.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Negligible improvement in openvswitch-using agents due to removal of checks.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Existing deployments will be unaffected as they will already have the
appropriate dependencies for their deployment.&lt;/p&gt;
&lt;p&gt;Deployments using distro packaging will be unaffected as the dependencies will
already be handled by the packaging.&lt;/p&gt;
&lt;p&gt;Source installs, e.g. devstack, should run the feature test script to verify
that an appropriate version of openvswitch has been installed on the system.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Agents using openvswitch will no longer need to check openvswitch versions
when using version-specific openvswitch features. Testing is simplified since
the version-check feature is being removed and no longer requires testing.&lt;/p&gt;
&lt;p&gt;Devstack can also be modified to run the external feature test script before
deployment and fail early in the case of a configuration/dependency mismatch.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;otherwiseguy&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Remove runtime version checks and associated tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create the feature test script&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This will essentially be a refactoring of:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/88121/"&gt;https://review.openstack.org/#/c/88121/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;into two pieces, the runtime check -&amp;gt; separate script and the existing code
removal in that patch.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;As this implementation primarily removes code that should not exist, it also
removes the need for testing the version checking code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 28 May 2014 00:00:00 </pubDate></item><item><title>L3 Agent Responsiveness</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/l3-agent-responsiveness.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/l3-agent-responsiveness"&gt;https://blueprints.launchpad.net/neutron/+spec/l3-agent-responsiveness&lt;/a&gt;&lt;/p&gt;
&lt;dl class="field-list simple"&gt;
&lt;dt class="field-odd"&gt;Author&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-odd"&gt;&lt;p&gt;Carl Baldwin &amp;lt;&lt;a class="reference external" href="mailto:carl.baldwin%40hp.com"&gt;carl&lt;span&gt;.&lt;/span&gt;baldwin&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class="field-even"&gt;Copyright&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-even"&gt;&lt;p&gt;2014 Hewlett-Packard Development Company, L.P.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;On agent restart, the L3 agent loops through all routers to be sure they’re in
sync with the database.  This task can take over an hour on a heavily loaded
system because of rootwrap, sudo and other inefficiencies.  This task locks out
RPC processing until it is done.  From a user’s perspective, it appears that
the system is completely unresponsive to floating ip and port changes.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;On agent restart, the L3 agent immediately kicks off a periodic task called
&lt;em&gt;_sync_routers_task&lt;/em&gt;.  This task grabs a semaphore which locks out the
&lt;em&gt;_rpc_loop&lt;/em&gt; until it is done.  This makes the L3 agent unresponsive to new work
coming in via RPC.  Floating IPs need to wait to become active or inactive,
router gateways don’t get plugged or unplugged, and subnet ports cannot be
manipulated.  This gives a poor impression to a user who has just made an API
call to get something done.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;section id="overview"&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
&lt;p&gt;This blueprint proposes unifying &lt;em&gt;_sync_routers_task&lt;/em&gt; and &lt;em&gt;_rpc_loop&lt;/em&gt; in to a
single processing loop.  This single loop will give priority to RPC messages.
In other words, an RPC message about a given router will bump that router ahead
in the queue before all of the routers that are in the queue from the
&lt;em&gt;_sync_routers_task&lt;/em&gt; code path.&lt;/p&gt;
&lt;p&gt;The justification for prioritizing in this way is that &lt;em&gt;_sync_routers_task&lt;/em&gt;
requests maintenance updates to routers.  It is meant to catch the somewhat
unlikely case that a change was made to a router while the agent was down.  RPC
messages generally represent changes to the system that are being requested
through the API in the moment.  When you consider this, it is clear that RPC
messages should be given precedence to improve the user experience.&lt;/p&gt;
&lt;p&gt;To be fair, the &lt;em&gt;_sync_routers_task&lt;/em&gt; is also helpful if the system reboots
after a crash.  In this case, these updates are more than just maintenance.
However, in this case, each router on the system is already down.  It is still
prudent to respond to user requests with priority.&lt;/p&gt;
&lt;p&gt;Each update will carry a timestamp so that they can be prioritized by time if
there are many updates at once with the same priority.&lt;/p&gt;
&lt;section id="parallelism"&gt;
&lt;h4&gt;Parallelism&lt;/h4&gt;
&lt;p&gt;The current L3 implementation allows processing many routers in parallel.  In
fact, there is virtually no bound on the number of routers that can be
processed in parallel except for the limit of 1000 grean threads.  In reality
though, it is not practical to process more than 4-8 routers in parallel
because there are enough contention points that prevent proper cooperation
between the threads that most of them get starved anyway.&lt;/p&gt;
&lt;p&gt;This blueprint implementation will create a _process_routers_loop to process
all updates.  This loop will use a green thread pool of fixed size.  The loop
will continuously spawn worker threads to ensure that the maximum number of
workers are either processing a router or waiting on the queue for the next
update to come in.&lt;/p&gt;
&lt;p&gt;The size of the worker pool can easily be made configurable in a follow on to
this blueprint if there is enough demand.  However, based on testing done at
scale, the size will initially be set to 8.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="exclusiverouterprocessor"&gt;
&lt;h4&gt;ExclusiveRouterProcessor&lt;/h4&gt;
&lt;p&gt;A new worker will spawn and immediately call _process_router_update.  This
method will immediately look to the queue for the next router update.  It will
block (friendly green thread style block) until one is available.&lt;/p&gt;
&lt;p&gt;At this point, there are some timing and coordination issues to consider.  The
ExclusiveRouterProcessor class was designed to take care of these.&lt;/p&gt;
&lt;p&gt;First, since there are multiple workers and many routers, we don’t want to have
multiple workers touching the same router at once.  To avoid this, the queue
implementation will return an instance of ExclusiveRouterProcessor that
guarantees that worker has exclusive access to the router, even if other update
messages come in while it is being processed.  This worker will be considered
the master for this router until updates are finished.&lt;/p&gt;
&lt;p&gt;Second, there is the possibility that a new update for the router will come in
and bubble to the front of the priority queue while the router is being
processed with outdated information.  To handle this case, the worker that
picks up this new update will try to get exclusive access to the router by
creating an instance of ExclusiveRouterProcessor.  This instance will realize
that it is not the master processor and will simply append the update to the
list of updates that the master instance will process.&lt;/p&gt;
&lt;p&gt;When the master instance is done processing the router, it will check its queue
of updates to see if the router needs to be processed again.  If another update
is found, it will process the router again, fetching new information from the
DB.  It will loop until there are no more updates.  This covers the case where
a user is actively making updates to a router over a period of time.  The
router simply needs to be processed several times in a row to respond to these
updates until the user is finished.&lt;/p&gt;
&lt;p&gt;It is important to note here that the new update must have bubbled all the way
to the front of the priority queue and a worker needs to grab it off of the
queue before the router processor will loop on the router and process it
multiple times in a row.  Without this important distinction, the algorthim
would be subject to a denial of service attack where 8 routers could completely
starve all of the other routers on the system.&lt;/p&gt;
&lt;p&gt;The complexity in this class is mostly around making a guarantee that there
is only one master processor for any given router.  The rest is around the
&lt;a class="reference internal" href="#timing"&gt;Timing&lt;/a&gt; issues discussed next.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="timing"&gt;
&lt;h4&gt;Timing&lt;/h4&gt;
&lt;p&gt;Each update carries a timestamp that is initialized to the time when the update
was received.&lt;/p&gt;
&lt;p&gt;The ExclusiveRouterProcessor class carries one timestamp per router that is
updated to just before a database query fetched the latest data about the
router.  This timestamp is &lt;em&gt;not&lt;/em&gt; recorded until the router has been processed
using those data.  It will be recorded by calling the fetched_and_processed
method.  This is very important because the timestamp records the age of the
data that was last used to complete an update to the router on the system.
This handles the time delta between when the data were fetched and when the
router is finally updated.&lt;/p&gt;
&lt;p&gt;In the case of &lt;em&gt;_sync_routers_task&lt;/em&gt;, the same timestamp is used for the update
and for the age of the data since the system will immediately run a query to
get all of the router data after the updates are created.  However, the new
implementation will still update all routers.  They will just be updated with
a lower priority than the RPC generated updates.&lt;/p&gt;
&lt;p&gt;An update will be processed for a router iff the update timestamp is newer than
the most recent router_data_timestamp.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Speeding up the L3 agent has been a work item for some time.  Progress has been
made in this area during the Icehouse time frame.  For example, sudo was found
to have an inefficiency that added 100 milliseconds or more to each invocation.
This affected the L3 agent’s ability to plumb routers in a timely manner.&lt;/p&gt;
&lt;p&gt;In the Juno timeframe, we will get a new daemon mode for rootwrap which will
speed up the agent a great deal.&lt;/p&gt;
&lt;p&gt;The bottom line is that speeding up the agent will not be enough.  On an agent
hosting hundreds of routers, there will still be a significant delay caused by
the &lt;em&gt;_sync_routers_task&lt;/em&gt; which will affect the end user experience.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Improved responsiveness to L3 changes made through the API following an agent
restart.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;This change will allow deployers of large scale cloud deployments using L3
agent to breathe easier.  They will be able to deploy updates to the code base,
restart the L3 agents and not worry about the effect it has on the system’s
overall responsiveness.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~carl-baldwin"&gt;carl-baldwin&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/78819"&gt;https://review.openstack.org/#/c/78819&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;No new gate tests will be required as this does not change functionality.  The
implementation will be fully unit tested including new tests to cover the
functionality of the priority queue and router processor.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/78819"&gt;https://review.openstack.org/#/c/78819&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 23 May 2014 00:00:00 </pubDate></item><item><title>Quota extension support for MidoNet plugin</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/midonet-support-quotas-ext.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/midonet-support-quotas-ext"&gt;https://blueprints.launchpad.net/neutron/+spec/midonet-support-quotas-ext&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add support for quotas extension in MidoNet plugin.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Current MidoNet plugin does not support quotas extension, which can be
supported simply by adding “quotas” in supported_extension_aliases
field in the plugin and “quotas” table in the Neutron database.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add quotas in supported_extension_aliases in the plugin as well as
“quotas” table in the Neutron database.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;“quotas” table will be created in the Neutron Database.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Users can start using quotas API with MidoNet plugin.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;This introduces a new DB migration script.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tomoe&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Add “quotas” in supported_extension_aliases
Add “quotas” table in the DB&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Tempest test tempest.api.network.admin.test_quotas covers this feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 21 May 2014 00:00:00 </pubDate></item><item><title>Allow the external IP address of a router to be specified</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/specify-router-ext-ip.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/specify-router-ext-ip"&gt;https://blueprints.launchpad.net/neutron/+spec/specify-router-ext-ip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There currently is no way to specify the IP address given to a
router on its external port. This blueprint allows external IPs
to be set and the action is restricted to admin-only by default.&lt;/p&gt;
&lt;p&gt;This spec was originally approved for Juno, however due to time
constraints and conflicts with all of the DVR work ongoing at the
end of the cycle, the code was reduced to a read-only version at
the deadline.&lt;/p&gt;
&lt;p&gt;The remaining code to finish the work is already complete and
has received several reviews.[1] It affects about 100 lines of
the L3 code so it has a small footprint and shouldn’t take too
much additional effort of reviewers to merge.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The current router API doesn’t allow any control over the IP
address given to the external interface on router objects.
This makes it difficult for scenarios where tenant routers have
to be assigned a well-known address that receives special
treatment on the provider network.&lt;/p&gt;
&lt;p&gt;Or, even if the address was originally randomly assigned,
there is no way to delete the router, move it to another project,
and preserve the previously assigned address.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Allow the external IP to be specified for a router in the
external_gateway_info passed to router_update. By default, this
will be restricted by policy.json to an admin-only operation.&lt;/p&gt;
&lt;p&gt;The format of this will be the standard fixed_ips format used
when specifying an IP address for a normal port so it offers
the flexibility of specifying a subnet_id instead of an IP directly.&lt;/p&gt;
&lt;p&gt;Requested addresses will be permitted to be any address inside any of the
subnets associated with the external network except for the gateway addresses.
They will not be affected by allocation pool ranges.&lt;/p&gt;
&lt;p&gt;If an address is already in use, the API will return a Conflict
error (HTTP 409).&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;‘external_fixed_ips’ is a field under ‘external_gateway_info’ that contains
the external IP address of the router interface. This field already exists
in the current API due to the previous partial implementation that allows
the addresses to be read. The only difference is that the field can now be
updated by an admin (or other user with the privileges defined in policy.json).&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;external_fixed_ips&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;fixed_ip
format
for
ports&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RO, owner
RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;generated&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Same as fixed_ips
field validation
for normal ports.&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;External IP
addresses&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Right now only one fixed IP may be specified, but this may be adjusted in the
future if routers support multiple external IPs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;N/A if the default policy.json is left unmodified. If it’s modified to allow
all users to set an IP, standard users will be allowed to ignore the allocation
ranges defined on the external subnet.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;The IP validation will use the same validation that is used for any port IP
address so this change should be IPv6 compatible.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;The community will rejoice in elation that such an amazing feature is
even possible, let alone implemented, in software.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;kevinbenton&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Make the changes to the L3 db code, API, and policy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update neutronclient&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;Unit tests should be adequate since there will be no new behavior outside
of the IP address assignment, which is well contained in the neutron code.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;Indicate that tenants can see their router’s external IP and that
admins can specify router IPs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;The developer API documentation will need to be updated to indicate
that the external router IP can now be set.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/83664/"&gt;https://review.openstack.org/#/c/83664/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Related bugs:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1255142"&gt;https://bugs.launchpad.net/neutron/+bug/1255142&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1188427"&gt;https://bugs.launchpad.net/neutron/+bug/1188427&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 21 May 2014 00:00:00 </pubDate></item><item><title>Freescale SDN Mechanism Driver for Neutron ML2 plugin</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/fsl-sdn-os-mech-driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/fsl-sdn-os-mech-driver"&gt;https://blueprints.launchpad.net/neutron/+spec/fsl-sdn-os-mech-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;FSL-SDN MD : Freescale SDN Mechanism Driver&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;CRD&lt;span class="classifier"&gt;Cloud Resource Discovery Service - like neutron,&lt;/span&gt;&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;uses keystone authentication for all ReSTful calls.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Freescale SDN (FSL-SDN) Mechanism Driver proxies ReSTful calls (formatted for
CRD Service) from ML2 plugin of Neutron to CRD Service.&lt;/p&gt;
&lt;p&gt;It supports the Cloud Resource Discovery (CRD) service by updating
the Network, Subnet and Port Create/Update/Delete data into the CRD database.&lt;/p&gt;
&lt;p&gt;CRD service manages network nodes, virtual network appliances and openflow
controller network applications.&lt;/p&gt;
&lt;p&gt;The basic work flow is as shown below.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+---------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="n"&gt;Neutron&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;ML2&lt;/span&gt; &lt;span class="n"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+-------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="n"&gt;Freescale&lt;/span&gt; &lt;span class="n"&gt;SDN&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="n"&gt;Mechanism&lt;/span&gt; &lt;span class="n"&gt;Driver&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-+--------+----------------------+&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;ReST&lt;/span&gt; &lt;span class="n"&gt;API&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------+-------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="n"&gt;CRD&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Openstack neutron based networks and ports information is required by
CRD service to managed virtual network appliances and openflow controller
apps.&lt;/p&gt;
&lt;p&gt;In order to send this information from neutron service, a new ML2
mechanism driver is required to post the _postcommit data to the CRD
service.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Freescale Mechanism driver handles the following postcommit operations.&lt;/p&gt;
&lt;p&gt;Network create/update/delete
Subnet  create/update/delete
Port    create/delete&lt;/p&gt;
&lt;p&gt;Supported network types by FSL OF Controller include vlan and vxlan.&lt;/p&gt;
&lt;p&gt;Freescale SDN mechanism driver handles VM port binding within in the
mechanism driver (like ODL MD).&lt;/p&gt;
&lt;p&gt;‘bind_port’ functions verifies the supported network types (vlan,vxlan)
and calls context.set_binding with binding details.&lt;/p&gt;
&lt;p&gt;Freescale Openflow Controller manages the flows required on OVS.&lt;/p&gt;
&lt;p&gt;Sequence flow of events for create_network is as follows:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;create_network&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;neutron&lt;/span&gt;    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;  &lt;span class="n"&gt;ML2_plugin&lt;/span&gt;
  &lt;span class="n"&gt;ML2_plugin&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;  &lt;span class="n"&gt;FSL&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;SDN&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;MD&lt;/span&gt;
  &lt;span class="n"&gt;FSL&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;SDN&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;MD&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;  &lt;span class="n"&gt;crd_service&lt;/span&gt;
  &lt;span class="n"&gt;FSL&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;SDN&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;MD&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt; &lt;span class="n"&gt;crd_service&lt;/span&gt;
  &lt;span class="n"&gt;ML2_plugin&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt; &lt;span class="n"&gt;FSL&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;SDN&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;MD&lt;/span&gt;
  &lt;span class="n"&gt;neutron&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;--&lt;/span&gt; &lt;span class="n"&gt;ML2_plugin&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Port binding task is handled within the mechanism driver, So OVS agent driver
is not required when this mechanism driver is enabled.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Negligible/None&lt;/p&gt;
&lt;p&gt;Though data is sent from mechansim driver to CRD service, the performance
impact is negligible(less than 1%) or None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;This change doesn’t take immediate effect.&lt;/p&gt;
&lt;p&gt;To work with the change, neutron need to be configured with ml2,
and fslsdn as mechanism driver with CRD service running.&lt;/p&gt;
&lt;p&gt;The following configuration changes are to be made to enable
Freescale SDN mechanism driver.&lt;/p&gt;
&lt;p&gt;In [ml2] section of /etc/neutron/plugins/ml2/ml2_conf.ini,
modify ‘mechanism_drivers’ attributes as,&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;mechanism_drivers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fslsdn&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Update /etc/neutron/plugins/ml2/ml2_conf_fslsdn.ini, as below.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ml2_fslsdn&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;crd_auth_strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;keystone&lt;/span&gt;
&lt;span class="n"&gt;crd_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="mf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;9797&lt;/span&gt;
&lt;span class="n"&gt;crd_auth_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="mf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="n"&gt;crd_tenant_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;
&lt;span class="n"&gt;crd_password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;crd_user_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;CRD service must be running in the Controller.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;trinath-somanchi&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Mechanism Driver (mechanism_fslsdn.py)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Complete Unit testing coverage of the code is included.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For tempest test coverage, 3rd party testing is provided (Freesacle CI).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Freescale CI reports on all changes affecting this driver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing is done using devstack and CRD service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CRD service logs are also posted into the CI log repository.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Configuration Reference guide will be updated from the code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 20 May 2014 00:00:00 </pubDate></item><item><title>Neutron/L3 High Availability VRRP</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/l3-high-availability.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/l3-high-availability"&gt;https://blueprints.launchpad.net/neutron/+spec/l3-high-availability&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The aim of this blueprint is to add High Availability Features on
virtual routers.&lt;/p&gt;
&lt;p&gt;High availability features will be implemented as extensions and drivers.
A first driver on the agent side will be based on Keepalived.&lt;/p&gt;
&lt;p&gt;A new scheduler will be also added in order to be able to spawn multiple
instances of a same router on many agents for the redundancy.&lt;/p&gt;
&lt;p&gt;The DVR blueprint will leverage this proposal as a Service node specifically
for SNAT traffic. See the reference for the DVR BP at the end of this
specification&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently we are able to spawn more than one l3 agent, and a l3 agent is able
to handle more than one external network, however each l3 agent is a SPOF.&lt;/p&gt;
&lt;p&gt;If an l3 agent fails, all virtual routers of this agent will be lost,
and consequently all VMs connected to these virtual routers will be isolated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;For the Neutron server side:&lt;/p&gt;
&lt;p&gt;The idea of this blueprint is to schedule a virtual router to at least two l3
agents, but this limit could be increased by changing a parameter in the
neutron configuration file.&lt;/p&gt;
&lt;p&gt;For the Neutron L3 agent side:&lt;/p&gt;
&lt;p&gt;The current router interfaces management in the l3 agent will be abstracted in
order to introduce the possibility to add drivers for that purpose. As a first
implementation of a driver, an HA Keepalived driver will be added. All the IPs
will be converted to VIPs.&lt;/p&gt;
&lt;p&gt;In order to hide the HA traffic from the tenant point of view a HA network will
be added and all the virtual router instances will be connected through a HA
port to this network.&lt;/p&gt;
&lt;p&gt;Flows:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;        &lt;span class="o"&gt;+----+&lt;/span&gt;                          &lt;span class="o"&gt;+----+&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-------+&lt;/span&gt; &lt;span class="n"&gt;QG&lt;/span&gt; &lt;span class="o"&gt;+------+&lt;/span&gt;           &lt;span class="o"&gt;+-------+&lt;/span&gt; &lt;span class="n"&gt;QG&lt;/span&gt; &lt;span class="o"&gt;+------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+-+--+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+-+--+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;VIPs&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;VIPs&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;+--+-+&lt;/span&gt;      &lt;span class="o"&gt;+--+-+&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;KEEPALIVED&lt;/span&gt;&lt;span class="o"&gt;+---+&lt;/span&gt; &lt;span class="n"&gt;HA&lt;/span&gt; &lt;span class="o"&gt;+------+&lt;/span&gt; &lt;span class="n"&gt;HA&lt;/span&gt; &lt;span class="o"&gt;+----+&lt;/span&gt;&lt;span class="n"&gt;KEEPALIVED&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;+--+-+&lt;/span&gt;      &lt;span class="o"&gt;+--+-+&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="n"&gt;VIPs&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;VIPs&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+-+--+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+-+--+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-------+&lt;/span&gt; &lt;span class="n"&gt;QR&lt;/span&gt; &lt;span class="o"&gt;+------+&lt;/span&gt;           &lt;span class="o"&gt;+-------+&lt;/span&gt; &lt;span class="n"&gt;QR&lt;/span&gt; &lt;span class="o"&gt;+------+&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;+----+&lt;/span&gt;                          &lt;span class="o"&gt;+----+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As a phase 2 of the keepalived driver implementation, the Keepalived driver
will start a conntrackd instance in order to not lose the established
connections when switching from the active to standby.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The first driver is going to be based on Keepalived. We could use some
alternative drivers based on other protocols for ex: Common Address Redundancy
Protocol (CARP).&lt;/p&gt;
&lt;p&gt;By default a config parameter will be added in order to specify whether the
virtual routers will be HA or not. In addition, an admin-only API is introduced
which will allow admins to migrate existing routers to HA mode.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Two new columns will be added to the router_extra_attributes table in order to
specify whether the virtual router will be HA or not and to specify the virtual
router id.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;ha
ha_vr_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool
int&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, admin
RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;False
N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A
N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Set router as HA
HA virtual router id&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The ha_vr_id will be limited to 255 due to VRRP protocol. This limit will have
to be removed when introducing a new driver without this limitation.&lt;/p&gt;
&lt;p&gt;A new table will be introduced to specify the association between a router,
the agents and the HA ports that are going to be used for the HA
administrative traffic.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Key&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;port_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;PRI&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HA port id&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;router_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;l3_agent_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;UUID&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;priority&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;int&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;50&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;state&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;enum&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;active/standby&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;router-create    Create a router for a given tenant.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;::&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;router-create –name another_router –ha=true&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Admin can only set this attribute. The tenants need not be aware about
this attribute in the router table. So it is not visible to the tenant.&lt;/p&gt;
&lt;p&gt;Request&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;::&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;POST /v2.0/routers
Accept: application/json&lt;/p&gt;
&lt;p&gt;{
“router”:{
“name”:”another_router”,
“admin_state_up”:true,
“ha”:true}
}&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Response&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;::&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;{
“router”:{
“status”:”ACTIVE”,
“external_gateway_info”:null,
“name”:”another_router”,
“admin_state_up”:true,
“ha”:true,
“tenant_id”:”6b96ff0cb17a4b859e1e575d221683d3”,
“id”:”8604a0de-7f6b-409a-a47c-a1cc7bc77b2e”}
}&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;router-show    Show information of a given router.&lt;/p&gt;
&lt;p&gt;Request&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;::&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;GET /v2.0/routers/a9254bdb-2613-4a13-ac4c-adc581fba50d
Accept: application/json&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Response&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;::&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;{
“routers”:[{
“status”:”ACTIVE”,
“external_gateway_info”:{
“network_id”:””
},
“name”:”router1”,
“admin_state_up”:true,
“ha”:true,
“tenant_id”:”33a40233088643acb66ff6eb0ebea679”,
“id”:”a9254bdb-2613-4a13-ac4c-adc581fba50d”}]
}&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;router-update    Create a router for a given tenant.&lt;/p&gt;
&lt;p&gt;Admin can only update the HA mode of a router.&lt;/p&gt;
&lt;p&gt;Admin only context:&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;::&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;neutron router-update router1 –ha=True&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There will be no network performance impact. Spawning a new virtual router may
be a bit longer due to the delay of starting the Keepalived/Conntrackd
processes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Since this implementation relies on Keepalived, Keepalived will have to be
deployed on each l3 node. The required version of Keepalived is the
version 1.2.0 in order to have the IPV6 support.&lt;/p&gt;
&lt;p&gt;In addition, conntrackd will be required to be run on each node.&lt;/p&gt;
&lt;p&gt;There is no plan to migrate automatically the original virtual routers to
the HA virtual routers when updating a previous Openstack installation.
So after a migration and with the l3_ha configuration parameter set to “True”,
the new routers created will be HA while the older ones will be unchanged.
Cloud admins can migrate existing virtual routers to be HA routers by using
the new API. This API is not exposed to tenants.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Sylvain Afchain &amp;lt;sylvain-afchain&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Assaf Muller &amp;lt;amuller&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;HA L3 Extension, DB bases&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HA L3 Scheduler&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keepalived manager&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L3 agent driver abstraction introduction, Keepalived driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Conntrackd support&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The code will be covered by unit tests.
When multi-nodes test will be available, tempest test will be introduced.&lt;/p&gt;
&lt;p&gt;A document explaining how to test all the patches during the review
process will be updated here :&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.google.com/document/d/1P2OnlKAGMeSZTbGENNAKOse6B2TRXJ8keUMVvtUCUSM"&gt;https://docs.google.com/document/d/1P2OnlKAGMeSZTbGENNAKOse6B2TRXJ8keUMVvtUCUSM&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Document deployer impacts.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/q/topic:bp/l3-high-availability,n,z"&gt;https://review.openstack.org/#/q/topic:bp/l3-high-availability,n,z&lt;/a&gt;
&lt;a class="reference external" href="https://git.openstack.org/cgit/openstack/neutron-specs/tree/specs/juno/neutron-ovs-dvr.rst"&gt;https://git.openstack.org/cgit/openstack/neutron-specs/tree/specs/juno/neutron-ovs-dvr.rst&lt;/a&gt;
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/L3_High_Availability_VRRP"&gt;https://wiki.openstack.org/wiki/Neutron/L3_High_Availability_VRRP&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 19 May 2014 00:00:00 </pubDate></item><item><title>rootwrap daemon mode</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/rootwrap-daemon-mode.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/rootwrap-daemon-mode"&gt;https://blueprints.launchpad.net/neutron/+spec/rootwrap-daemon-mode&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Neutron is one of projects that heavily depends on executing actions on network
nodes that require root priviledges on Linux system. Currently this is achieved
with oslo.rootwrap that has to be run with sudo. Both sudo and rootwrap produce
significant performance overhead. This blueprint covers mitigating the sudo
and rootwrap introduced part of the overhead by using the new mode of
rootwrap operation called ‘daemon mode’.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;As Miguel Angel Ajo stated in &lt;a class="footnote-reference brackets" href="#ml" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;On a database with 1 public network, 192 private networks, 192 routers, and
192 nano VMs, with OVS plugin:&lt;/p&gt;
&lt;p&gt;Network node setup time (rootwrap): 24 minutes&lt;/p&gt;
&lt;p&gt;Network node setup time (sudo):     10 minutes&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;As you can see, rootwrap presents major overhead comparing to plain sudo usage
and most of this overhead is due to long Python interpreter startup time
required for every request.
Details of the overhead are covered in &lt;a class="footnote-reference brackets" href="#rw-bp" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This blueprint proposes adopting oslo.rootwrap daemon model which allows
to run rootwrap as a daemon. The daemon works just as a usual rootwrap but
will accept commands to be run over authenticated UNIX domain socket instead of
command line, running continuously in background.
An overview of rootwrap daemon is at &lt;a class="footnote-reference brackets" href="#rw-eth" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Two new configuration options should be added:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rootwrap_mode&lt;/span&gt;&lt;/code&gt; = daemon | process will make agents use daemon
or the usual rootwrap process; daemon will be enabled by default.
This option could be deprecated in the future if we consider the daemon
mode performs as we expect.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rootwrap_config&lt;/span&gt;&lt;/code&gt; will provide path to rootwrap config file used to run
daemon, by default it will point to the neutron provider rootwrap files.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;root_helper&lt;/span&gt;&lt;/code&gt; is passed around in Neutron (as opposed to use of global
config in other projects) we have to make root_helper as some object
encapsulating all necessary info to run commands with root priviledges.
This is done in the first patch &lt;a class="footnote-reference brackets" href="#cr-rh" id="id4" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The patch introduces two root helper classes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ProcessHelper&lt;/span&gt;&lt;/code&gt; (base) simply runs command as is, with no wrappers;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;WrappedProcessHelper&lt;/span&gt;&lt;/code&gt; runs commands with a wrapper just as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;root_helper&lt;/span&gt;&lt;/code&gt;
option used to do.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These classes have two interface methods:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create_process&lt;/span&gt;&lt;/code&gt; starts a process and returns Popen instance associated
with it;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;execute&lt;/span&gt;&lt;/code&gt; starts a process (using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create_process&lt;/span&gt;&lt;/code&gt; by default), feeds it
some input and captures return code along with stdout and stderr output.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create_process&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;execute&lt;/span&gt;&lt;/code&gt; methods in the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron.agent.linux.utils&lt;/span&gt;&lt;/code&gt; module are still there but they just preprocess
arguments and pass them to appropriate methods of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;root_helper&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The second step &lt;a class="footnote-reference brackets" href="#cr-rw" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; would be to create those configuration options and
add another root helper class &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RootwrapDaemonHelper&lt;/span&gt;&lt;/code&gt;. This class would employ
one rootwrap client for all instances with same rootwrap_config. Its
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;execute&lt;/span&gt;&lt;/code&gt; method would just call &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;execute&lt;/span&gt;&lt;/code&gt; method of rootwrap client that
would pass request to the daemon.&lt;/p&gt;
&lt;p&gt;Note that we can’t currently start long-running processes using daemon so
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create_process&lt;/span&gt;&lt;/code&gt; will use usual rootwrap to start the process. Also the gain
for long running processes is negligible.&lt;/p&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;This change will start oslo rootwrap daemons running as root, and available
to neutron via a well authenticated (OTP) unix domain socket.&lt;/p&gt;
&lt;p&gt;Therefore &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron-rootwrap-daemon&lt;/span&gt;&lt;/code&gt; should be added to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sudoers&lt;/span&gt;&lt;/code&gt; file,
with the same settings used for neutron-rootwrap.&lt;/p&gt;
&lt;p&gt;Security is handled by oslo-rootwrap which is quite well proven.&lt;/p&gt;
&lt;p&gt;All security issues with using client+daemon instead of plain rootwrap are
covered in &lt;a class="footnote-reference brackets" href="#rw-bp" id="id6" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;This change introduces performance boost for agents that rely on calling a huge
amount of commands with rootwrap. Current state of rootwrap daemon shows over
10x speedup comparing to usual &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sudo&lt;/span&gt; &lt;span class="pre"&gt;rootwrap&lt;/span&gt;&lt;/code&gt; call. Total speedup for agents
will be less impressive but should be very noticeable. The rootwrap daemon
implementation includes a benchmark which generated the speedup results.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;This change introduces two new config variables:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rootwrap_mode&lt;/span&gt;&lt;/code&gt; using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;daemon&lt;/span&gt;&lt;/code&gt; as default;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rootwrap_config&lt;/span&gt;&lt;/code&gt; must point to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rootwrap.conf&lt;/span&gt;&lt;/code&gt; deployed for Neutron
(default &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/etc/neutron/rootwrap.conf&lt;/span&gt;&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that by default &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_rootwrap_daemon&lt;/span&gt;&lt;/code&gt; will be turned off so to get the
speedup one will have to turn it on. With it turned on &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;root_helper&lt;/span&gt;&lt;/code&gt; config
option is ignored and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron-rootwrap-daemon&lt;/span&gt;&lt;/code&gt; is used to run most commands
that require root priviledges.&lt;/p&gt;
&lt;p&gt;This change also introduces new binary &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron-rootwrap-daemon&lt;/span&gt;&lt;/code&gt; that should
be deployed beside &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;neutron-rootwrap&lt;/span&gt;&lt;/code&gt; and added to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sudoers&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;The community is broadly interested in faster agent operation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Use sudo without rootwrap, at the cost of lower security, or
by implementing specific sudo plugins to allow equivalent
equivalent rootwrap filtering. That would require maintaining
C sudo plugins specific for openstack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rewrite rootwrap into C, but that requires code auditing, and
also deviates from the standard python of the openstack community.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automatically translate rootwrap into C++, and obtain a compiled
version, this option has been explored, and seems to be possible
via shedskin with small modifications to rootwrap to avoid dynamic
typing. By the way, shedskin is experimental, and some python
modules are not implemented. Also the C++ produced code is not easily
human readable, and may need a security assesment. This solution
doesn’t eliminate the sudo performance impact, which is not negligible.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-solutions"&gt;
&lt;h3&gt;Other Solutions&lt;/h3&gt;
&lt;p&gt;Other solutions are mostly related to rootwrap optimizations and are
covered in &lt;a class="footnote-reference brackets" href="#rw-bp" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; (some of them are covered in &lt;a class="footnote-reference brackets" href="#eth" id="id8" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;This is not the only option of what can be done on the Neutron side besides
switching to rootwrap daemon (see &lt;a class="footnote-reference brackets" href="#eth" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; for details):&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Avoid unnecessary locking in router processing in L3 agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Avoid unnecessary calls&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Consolidate system calls: Carl Baldwin explored this option, and proved to
be very difficult and invasive to the code base.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of these can be done with rootwrap daemon as well since every call to the
daemon still impose some overhead.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;twilson (Terry Wilson, otherwiseguy @ freenode)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Original contributor:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;yorik-sar (Yuriy Taraday, YorikSar @ freenode)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Abstract out root_helper calls to classes - done &lt;a class="footnote-reference brackets" href="#cr-rh" id="id10" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement rootwrap daemon support - done, needs rebase &lt;a class="footnote-reference brackets" href="#cr-rw" id="id11" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;This change doesn’t change APIs so it doesn’t require additional integration
tests. If tempest is happy with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;use_rootwrap_daemon&lt;/span&gt;&lt;/code&gt; turned on, the feature
works.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Existing functional tests will exercise the rootwrap client side when performing
agents functional testing. Rootwrap also has it’s own functional testing for
the rootwrap client/daemon pieces &lt;a class="footnote-reference brackets" href="#rw-func" id="id12" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;7&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;No API tests are required.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;As we are including two new configuration settings, those need to be
properly documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;Developer documentation may be updated to describe how to use the
new interface to execute system commands, if any change were made to the
interface.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="rw-bp" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id2"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id6"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id7"&gt;3&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;oslo.rootwrap blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/oslo.rootwrap/+spec/rootwrap-daemon-mode"&gt;https://blueprints.launchpad.net/oslo.rootwrap/+spec/rootwrap-daemon-mode&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="ml" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Original mailing list thread:
&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2014-March/029017.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2014-March/029017.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="rw-eth" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Daemon design overview:
&lt;a class="reference external" href="https://etherpad.openstack.org/p/rootwrap-agent"&gt;https://etherpad.openstack.org/p/rootwrap-agent&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="cr-rh" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id4"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id10"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;Change request “Abstract out root_helper calls to classes”:
&lt;a class="reference external" href="https://review.openstack.org/82787"&gt;https://review.openstack.org/82787&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="cr-rw" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id5"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id11"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;Change request “Implement rootwrap daemon support”:
&lt;a class="reference external" href="https://review.openstack.org/84667"&gt;https://review.openstack.org/84667&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="eth" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id8"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id9"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;p&gt;Original problem statement summarized here:
&lt;a class="reference external" href="https://etherpad.openstack.org/p/neutron-agent-exec-performance"&gt;https://etherpad.openstack.org/p/neutron-agent-exec-performance&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="rw-func" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id12"&gt;7&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;Rootwrap daemon functional testing
&lt;a class="reference external" href="https://github.com/openstack/oslo.rootwrap/blob/master/tests/test_functional.py"&gt;https://github.com/openstack/oslo.rootwrap/blob/master/tests/test_functional.py&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Fri, 16 May 2014 00:00:00 </pubDate></item><item><title>Ability to assign cisco nw profile to multi-tenants in single request</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/cisco-network-profile-multi-tenants-support.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/cisco-network-profile-multi-tenants-support"&gt;https://blueprints.launchpad.net/neutron/+spec/cisco-network-profile-multi-tenants-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add the support to assign a cisco network profile to multiple tenants in a single request&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently with Cisco N1kv plugin, admin is only able to assign cisco network profile to one
tenant in a request. So admin has to send multiple requests to assign a cisco network profile
to multiple tenants.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposed change is to make the create network profile and update network profile functions to
take a list of tenant ids, and then update the profile-tenant binding info accordingly.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The Alternative way is to send multiple requests, assigning to one tenant per request.
This alternative is obviously too tedious for admin users, especially when a admin has a lot
of tenants to manage.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;for network_profile resource, ‘add_tenant’ and ‘remove_tenant’ attributes are changed to
‘add_tenants’ and ‘remove_tenants’. And Instead of taking one tenant id, now they are taking
a list of tenant ids.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;There is a corresponding change in python-neutronclient:
In cisco network profile create cli, admin can add repeated –add-tenant
option;
In cisco network profile update cli, admin can add repeated –add-tenant and
repeated –remove-tenant option&lt;/p&gt;
&lt;p&gt;in horizon:
admin can select multiple tenants during creating cisco network profile;
admin can select or deselect multiple tenants during updating cisco network profile.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;fenzhang&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;modify create and update network profile functions in neutron/plugins/cisco/db/nikv_db_v2.py file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;modify network profile attributes in neutron/plugins/cisco/extensions/network_profile.py file&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;blueprint in python-neutronclient and horizon:
&lt;a class="reference external" href="https://blueprints.launchpad.net/horizon/+spec/cisco-network-profile-multi-tenants-support"&gt;https://blueprints.launchpad.net/horizon/+spec/cisco-network-profile-multi-tenants-support&lt;/a&gt;
&lt;a class="reference external" href="https://blueprints.launchpad.net/python-neutronclient/+spec/cisco-network-profile-multi-tenants-support"&gt;https://blueprints.launchpad.net/python-neutronclient/+spec/cisco-network-profile-multi-tenants-support&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The UT test cases will be added to cover this change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 02 May 2014 00:00:00 </pubDate></item><item><title>ofagent: port monitoring w/o ovsdb accesses</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/ofagent-port-monitor.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ofagent-port-monitor"&gt;https://blueprints.launchpad.net/neutron/+spec/ofagent-port-monitor&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;ofagent currently scans ovsdb (via ovs-vsctl command) to get a list of ports.
ovsdb is not likely available for other openflow switch implementations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;implement the functionality using OFPMP_PORT_DESC instead of ovsdb.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(optional) use OFPT_PORT_STATUS asynchronous messages to
avoid periodic polling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;as there is no pure openflow equivalent for port external-ids,
we plan to use port name to identify devices. (as linuxbridge does)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;implement switch-specific methods for every switch implementations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;use of-config
at a glance of the spec, it doesn’t seem usable at this point, though.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;in case asyncronous messages are used, performance might be improved.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;yamamoto&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;kakuma&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;see “Proposed change” section.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;p&gt;but some of bug fixes need to be merged to make this useful.
for example, &lt;a class="reference external" href="https://review.openstack.org/#/c/88224/"&gt;https://review.openstack.org/#/c/88224/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;ryu/ofagent third party testing would find regressions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://www.opennetworking.org/sdn-resources/onf-specifications/openflow"&gt;https://www.opennetworking.org/sdn-resources/onf-specifications/openflow&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenFlow 1.3.3 7.3.5.7 Port Description&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenFlow 1.3.3 7.4.3 Port Status Message&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Fri, 02 May 2014 00:00:00 </pubDate></item><item><title>ML2 Provider-network partial specs</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/provider-network-partial-specs.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/provider-network-partial-specs"&gt;https://blueprints.launchpad.net/neutron/+spec/provider-network-partial-specs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint will allow creation of provider networks with provider
attributes partially provided. This capability will be implemented only for
the ML2 plugin.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, all provider attributes for tenant networks are chosen by neutron,
while for provider networks &lt;strong&gt;all&lt;/strong&gt; the provider attributes must be specified
by admins. For provider networks, admins cannot specify some provider
attributes and delegate the choice of remaining ones to neutron-server. This
means that admins must know the valid and unallocated physical_networks and
segmentation_ids when creating provider networks.&lt;/p&gt;
&lt;p&gt;This blueprint will let admins specify some provider attributes, and let
neutron choose the remaining attributes from pools of allowable values.&lt;/p&gt;
&lt;p&gt;Use cases:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create a (vlan) network for baremetal deployment without focusing
on physical_network/segmentation_id choices,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create “service” networks (typically networks for storage) which
are provided over vlan on a specific physical_network without focusing on
segmentation_id choice,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create gre/vxlan networks for testing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Vlan/gre/vxlan ML2 type drivers will be extended in order to support partially
providing provider/multi-provider network attributes on network create, and
let type drivers choose a network from tenant network pools.&lt;/p&gt;
&lt;p&gt;More precisely type drivers will choose a network from tenant network pools
matching provided attributes and allocate it. If no candidate is found the type
driver will raise a NoNetworkAvailable exception. The network delete process
will not change: the network will be returned to its tenant network pool.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative solution would be to provide alternative type driver
implementations for previous network types allowing to partially specify
provider attributes. This solution does not require new configuration options
but ML2 type manager must check that at most one type driver is provided per
network type.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;This blueprint reduces constraints on provider network attributes on network
create:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If provider:network_type=vlan is specified, then provider:physical_network
and provider:segmentation_id are optional:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vlan&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;network_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;vlan&lt;/span&gt;
&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;network_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;vlan&lt;/span&gt;\
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;physical_network&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If provider:network_type=gre is specified, then provider:segmentation_id is
optional:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;gre&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;network_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;gre&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If provider:network_type=vxlan is specified, then provider:segmentation_id is
optional:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vxlan&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;network_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;vxlan&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The same constraint reduction applies on multi-provider attributes on network
create:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;neutron&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;multi&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;segments&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;true&lt;/span&gt;\
    &lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;network_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;vlan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;physical_network&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;multi&lt;/span&gt;\
    &lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;network_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;gre&lt;/span&gt;\
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;p&gt;Provider/multi-provider network default policy will not change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:
Cedric Brandily &amp;lt;cbrandily&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Update ML2 plugin/type manager in order to allow reserve_provider_network
to return allocated network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend vlan type driver to support partial specs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend gre/vxlan type driver to support partial specs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update ML2 multi-provider to support partial specs&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The code will be covered by unit tests.&lt;/p&gt;
&lt;p&gt;Tempest tests will be provided. Tempest must be aware of network types
supported by tested deployment in order to tests partial specs on all
supported network types. The new tempest option &lt;strong&gt;partial_specs_scenario&lt;/strong&gt;
will be define to configure supported network types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Disable partial specs tests (default value):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;partial_specs_scenario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable vlan provider networks partial specs tests:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;partial_specs_scenario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vlan&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable vlan and gre provider networks partial specs tests:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;partial_specs_scenario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vlan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;gre&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Document deployer impacts.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/q/topic:bp/provider-network-partial-specs,n,z"&gt;https://review.openstack.org/#/q/topic:bp/provider-network-partial-specs,n,z&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 01 May 2014 00:00:00 </pubDate></item><item><title>Add firewall driver for McAfee NGFW firewall</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/kilo/mcafee-ngfw-fwaas-driver.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/mcafee-ngfw-fwaas-driver"&gt;https://blueprints.launchpad.net/neutron/+spec/mcafee-ngfw-fwaas-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Implements FWaaS driver for McAfee ngfw firewall&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;McAfee NGFW(next generation firewall) support/integration is missing.
It provides cloud admin/users more choice.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Add a new firewall driver for NGFW.
(neutron firewall driver. a subclass of FwaasDriverBase)&lt;/p&gt;
&lt;p&gt;Introduce a new driver for the existing reference FWaaS agent.
The FWaaS agent will load this new driver for NGFW firewall if configured.
There will be no changes to the existing reference FWaaS agent.&lt;/p&gt;
&lt;p&gt;The new driver gets user requests from the FWaaS agent and sends
these requests to the SMC server (NGFW management server) via REST API.
SMC server is a sort of a controller of firewall devices.&lt;/p&gt;
&lt;p&gt;The new driver needs the SMC server IP address and the API key (NGFW specific)
to talk to the SMC API. This information should be specified in the agent
configuration file. The new driver will read these information from the
configuration file and make connections to the SMC server REST API interface
using this information.&lt;/p&gt;
&lt;p&gt;The agent driver would inherit from the base class (FwaasDriverBase)
and overrides methods for NGFW-specific feature.&lt;/p&gt;
&lt;p&gt;The agent will run on network node as it is today.(But the agent doesn’t
have to run on network node. It will be addressed by future phase.
See the section of future work.)&lt;/p&gt;
&lt;p&gt;References to L3 router plugin in the diagram are added to help with
better understanding and is not in scope of this proposal
&lt;a class="reference internal" href="#ngfw-l3-router" id="id1"&gt;&lt;span&gt;[ngfw-l3-router]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;diagram for first implementation:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+---------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+---------+&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;+------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;l3&lt;/span&gt; &lt;span class="n"&gt;plugin&lt;/span&gt;&lt;span class="o"&gt;+--------------------+----+&lt;/span&gt; &lt;span class="n"&gt;Nova&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+---+-----+&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;+--+---+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;+---------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;firewall&lt;/span&gt; &lt;span class="n"&gt;plugin&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;+-----+---------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------|--------------|-----------+&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;rpc&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;L3_AGENT&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;+-----|---------+&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;l3&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+---+--+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;fwaas&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+-+----+&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;+---|-----------+&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;cloud&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt; &lt;span class="n"&gt;manages&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;+-----+------------++&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;SMC&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;management&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;|&amp;lt;-------------------+&lt;/span&gt; &lt;span class="n"&gt;spin&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;down&lt;/span&gt;
 &lt;span class="o"&gt;+----+--------------+&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                   &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tenant&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;cloud&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt; &lt;span class="n"&gt;manages&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;+----+----------------+&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;SG&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;                  &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="o"&gt;|&amp;lt;-----------------+&lt;/span&gt; &lt;span class="n"&gt;spin&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;down&lt;/span&gt;
 &lt;span class="o"&gt;+--+--+---------------+&lt;/span&gt;                    &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;remove&lt;/span&gt; &lt;span class="n"&gt;interfaces&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|...&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="n"&gt;tenant&lt;/span&gt; &lt;span class="n"&gt;networks&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;cloud&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;future work&lt;/p&gt;
&lt;p&gt;Firewall driver for config agent will be implemented during the third phase once
l3 routervm plugin and config agent are merged and which is enhanced to
support firewall service as well. &lt;a class="reference internal" href="#config-agent" id="id2"&gt;&lt;span&gt;[config-agent]&lt;/span&gt;&lt;/a&gt; &lt;a class="reference internal" href="#modular-l3-router-plugin" id="id3"&gt;&lt;span&gt;[modular-l3-router-plugin]&lt;/span&gt;&lt;/a&gt;
(Allowing multiple type of routers will be addressed by
&lt;a class="reference internal" href="#modular-l3-router-plugin" id="id4"&gt;&lt;span&gt;[modular-l3-router-plugin]&lt;/span&gt;&lt;/a&gt;. It’s different topic.)&lt;/p&gt;
&lt;p&gt;References to L3 router plugin in the diagram are added to help with
better understanding and is not in scope of this proposal
For details, please refer to &lt;a class="reference internal" href="#ngfw-l3-router" id="id5"&gt;&lt;span&gt;[ngfw-l3-router]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The main difference of config agent is that fwaas agent is tied to
network node and host fwaas instance which is instantiated on the physical
node, on the other hand the config agent is not tied to network node or
servicevm which serves fwaas instance and it can run anywhere as long as
it can receive RPC and communicate with fwaas management service.
This direction aligns with other similar activities.
&lt;a class="reference internal" href="#fwaas-csr1kv" id="id6"&gt;&lt;span&gt;[fwaas-csr1kv]&lt;/span&gt;&lt;/a&gt;, &lt;a class="reference internal" href="#fwaas-tcs" id="id7"&gt;&lt;span&gt;[fwaas-tcs]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;diagram for implementation with l3-routervm plugin and config agent:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+---------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Neutron&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;                                 &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+---------+&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;+------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;l3&lt;/span&gt; &lt;span class="n"&gt;plugin&lt;/span&gt;&lt;span class="o"&gt;+--------------------+------+&lt;/span&gt; &lt;span class="n"&gt;Nova&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+---+-----+&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;+--+---+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;+---------------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;firewall&lt;/span&gt; &lt;span class="n"&gt;plugin&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;+-----+---------+&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------|--------------|-----------+&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;rpc&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+---------------------|--------+&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;              &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+------+&lt;/span&gt;       &lt;span class="o"&gt;+---+--+&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;fwaas&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+---+--+&lt;/span&gt;       &lt;span class="o"&gt;+-+----+&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;config&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;agent&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------|------------|----------+&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
       &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;cloud&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt; &lt;span class="n"&gt;manageses&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;+-----+------------++&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;SMC&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;management&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;|&amp;lt;---------------------+&lt;/span&gt; &lt;span class="n"&gt;spin&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;down&lt;/span&gt;
 &lt;span class="o"&gt;+----+--------------+&lt;/span&gt;                      &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;                                     &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tenant&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;cloud&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt; &lt;span class="n"&gt;manages&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;+----+-----------+&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;SG&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;                         &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;|&amp;lt;------------------------+&lt;/span&gt; &lt;span class="n"&gt;spin&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;down&lt;/span&gt;
 &lt;span class="o"&gt;+--+--+----------+&lt;/span&gt;                           &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;remove&lt;/span&gt; &lt;span class="n"&gt;interfaces&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|...&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="n"&gt;tenant&lt;/span&gt; &lt;span class="n"&gt;networks&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;cloud&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None
Although this NGFW driver provides cloud users another choice for security,
this section is for the potential impact of the system. Not for user impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;User will have another choice of firewall provider.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;New service provider for the driver will be introduced.The deployer
who wants use NGFW needs to configure to use the l3 router plugin and
firewall driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;The NGFW fwaas driver provides cloud user more choice of Neutron FWaaS.
Thus it promotes Neutron FWaaS.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;rui-zang
yalei-wang
yamahata&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;FWaaS driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;third party CI&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once l3 routervm plugin and config agent are merged
* Refactor firewall driver into a driver for config agent&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;NGFW l3 router plugin &lt;a class="reference internal" href="#ngfw-l3-router" id="id8"&gt;&lt;span&gt;[ngfw-l3-router]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Third party testing would be added.&lt;/p&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Third party testing will be added to Intel CI.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;Scenario tests will be added to validate the NGFW driver implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Admin guide will be updated.&lt;/p&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;The another choice of FWaaS backend will be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;div role="list" class="citation-list"&gt;
&lt;div class="citation" id="ngfw-l3-router" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;ngfw-l3-router&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id5"&gt;2&lt;/a&gt;,&lt;a role="doc-backlink" href="#id8"&gt;3&lt;/a&gt;)&lt;/span&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/mcafee-ngfw-l3-router"&gt;https://blueprints.launchpad.net/neutron/+spec/mcafee-ngfw-l3-router&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/134198/"&gt;https://review.openstack.org/#/c/134198/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="citation" id="config-agent" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;config-agent&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://git.openstack.org/cgit/openstack/neutron-specs/tree/specs/juno/cisco-config-agent.rst"&gt;http://git.openstack.org/cgit/openstack/neutron-specs/tree/specs/juno/cisco-config-agent.rst&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="citation" id="fwaas-csr1kv" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id6"&gt;fwaas-csr1kv&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/fwaas-cisco"&gt;https://blueprints.launchpad.net/neutron/+spec/fwaas-cisco&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/129836/"&gt;https://review.openstack.org/#/c/129836/&lt;/a&gt;
spec&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/115308/"&gt;https://review.openstack.org/#/c/115308/&lt;/a&gt;
patch&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="citation" id="fwaas-tcs" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;fwaas-tcs&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/tcs-fwaas-netconf-host-plugin"&gt;https://blueprints.launchpad.net/neutron/+spec/tcs-fwaas-netconf-host-plugin&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/98104/"&gt;https://review.openstack.org/#/c/98104/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="citation" id="modular-l3-router-plugin" role="doc-biblioentry"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;modular-l3-router-plugin&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="backrefs"&gt;(&lt;a role="doc-backlink" href="#id3"&gt;1&lt;/a&gt;,&lt;a role="doc-backlink" href="#id4"&gt;2&lt;/a&gt;)&lt;/span&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/l3-plugin-for-routervm"&gt;https://blueprints.launchpad.net/neutron/+spec/l3-plugin-for-routervm&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/105078/"&gt;https://review.openstack.org/#/c/105078/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
</description><pubDate>Wed, 30 Apr 2014 00:00:00 </pubDate></item><item><title>Neutron routing service implemented using Cisco VM (and physical devices)</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/cisco-routing-service-vm.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/cisco-routing-service-vm"&gt;https://blueprints.launchpad.net/neutron/+spec/cisco-routing-service-vm&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;There is need to support Neutron’s routing service implemented in Cisco devices.
This blueprint targets that use case. In particular it implements routing using
the Cisco CSR1kv VM devices.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The implementation is done as a separate routing service plugin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Introduction of binding table to associate Neutron router with hosting device&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RPC Notifications and callbacks for interactions with Cisco configuration
agent (the latter defined and implemented in BP/patch:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/cisco-config-agent"&gt;https://blueprints.launchpad.net/neutron/+spec/cisco-config-agent&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;This could have been done as part of refactoring the existing routing service
plugin. However, this path was not taken in order to reduce impact as there is a
broader discussion in the community about L3 router modularization, flavor
framework etc.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;The basic l3 routing data models are extended via the regular Neutron extension
mechanism. The base classes will not be modified.&lt;/p&gt;
&lt;p&gt;Three new DB tables: &lt;strong&gt;hostingdevices&lt;/strong&gt;, &lt;strong&gt;HostedHostingPortBinding&lt;/strong&gt; and
&lt;strong&gt;routerhostingdevicebindings&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;HostingDevice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BASEV2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;models_v2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HasId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;models_v2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HasTenant&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="sd"&gt;"""Represents an appliance hosting Neutron router(s).&lt;/span&gt;

&lt;span class="sd"&gt;      When the hosting device is a Nova VM 'id' is uuid of that VM.&lt;/span&gt;
&lt;span class="sd"&gt;   """&lt;/span&gt;
   &lt;span class="c1"&gt;# complementary id to enable identification of associated Neutron resources&lt;/span&gt;
   &lt;span class="n"&gt;complementary_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
   &lt;span class="c1"&gt;# manufacturer id of the device, e.g., its serial number&lt;/span&gt;
   &lt;span class="n"&gt;device_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
   &lt;span class="n"&gt;admin_state_up&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="c1"&gt;# 'management_port_id' is the Neutron Port used for management interface&lt;/span&gt;
   &lt;span class="n"&gt;management_port_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                                  &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ports.id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                                &lt;span class="n"&gt;ondelete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"SET NULL"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
   &lt;span class="n"&gt;management_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;orm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models_v2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="c1"&gt;# 'protocol_port' is udp/tcp port of hosting device. May be empty.&lt;/span&gt;
   &lt;span class="n"&gt;protocol_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;cfg_agent_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                            &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'agents.id'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                            &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;cfg_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;orm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agents_db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="c1"&gt;# Service VMs take time to boot so we store creation time&lt;/span&gt;
   &lt;span class="c1"&gt;# so we can give preference to older ones when scheduling&lt;/span&gt;
   &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;HostedHostingPortBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BASEV2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="sd"&gt;"""Represents binding of logical resource's port to its hosting port."""&lt;/span&gt;
   &lt;span class="n"&gt;logical_resource_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;logical_port_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                               &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ports.id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                             &lt;span class="n"&gt;ondelete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"CASCADE"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                               &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;logical_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;orm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="n"&gt;models_v2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;primaryjoin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Port.id==HostedHostingPortBinding.logical_port_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;backref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;orm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hosting_info'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cascade&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'all'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uselist&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
   &lt;span class="c1"&gt;# type of router port: router_interface, ..._gateway, ..._floatingip&lt;/span&gt;
   &lt;span class="n"&gt;port_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
   &lt;span class="c1"&gt;# type of network the router port belongs to&lt;/span&gt;
   &lt;span class="n"&gt;network_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
   &lt;span class="n"&gt;hosting_port_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                               &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ports.id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                             &lt;span class="n"&gt;ondelete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'CASCADE'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
   &lt;span class="n"&gt;hosting_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;orm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="n"&gt;models_v2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;primaryjoin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Port.id==HostedHostingPortBinding.hosting_port_id'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="c1"&gt;# VLAN tag for trunk ports&lt;/span&gt;
   &lt;span class="n"&gt;segmentation_tag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;autoincrement&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;RouterHostingDeviceBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BASEV2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="sd"&gt;"""Represents binding between Neutron routers and their hosting devices."""&lt;/span&gt;
   &lt;span class="n"&gt;router_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'routers.id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ondelete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'CASCADE'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                         &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;orm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l3_db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="c1"&gt;# If 'auto_schedule' is True then router is automatically scheduled&lt;/span&gt;
   &lt;span class="c1"&gt;# if it lacks a hosting device or its hosting device fails.&lt;/span&gt;
   &lt;span class="n"&gt;auto_schedule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="c1"&gt;# id of hosting device hosting this router, None/NULL if unscheduled.&lt;/span&gt;
   &lt;span class="n"&gt;hosting_device_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                                 &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hostingdevices.id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                               &lt;span class="n"&gt;ondelete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'SET NULL'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
   &lt;span class="n"&gt;hosting_device&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;orm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hd_models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HostingDevice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The l3 routing service REST API remains intact. No new REST API is introduced.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;We create a virtual management network which is a Neutron provider Network that
CSR1kv VMs will have a VIF on as well as the config agent used to apply
configurations inside them. This configuration agent must be able to communicate
with the Neutron server for RPC. The regular Neutron management network is used
for that communication. The virtual management network and the Neutron
management network need not be the same and are preferably kept separate for
improved security isolation.&lt;/p&gt;
&lt;p&gt;Security issues coupled to metadata service do not apply since this
implementation does not support metadata service via Neutron router.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None to existing. This l3 routing service plugin uses its own RPC for
interactions with Cisco configuration agents. These agents are defined in
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/cisco-config-agent"&gt;https://blueprints.launchpad.net/neutron/+spec/cisco-config-agent&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;End users creating Neutron routers will experience a somewhat longer delay from
the time the Neutron router create request has returned until the Neutron router
is operational (i.e., forwarding packets). This is due to the time needed to
spin up a CSR1kv VM.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The Neutron and Nova services should not be significantly impacted by this
routing service plugin. The RPC is basically equivalent to the l3agent RPC
in terms of resulting traffic. Compared to the Linux namespace router
implementation a few more Neutron resources (ports, network, subnets) are
created by this implemenation when a Neutron router is created. We don’t expect
these extra operations to amount to significantly increased load of the Neutron
server.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;We believe this will have no impact on community L3 router service plugin, not
in its current implemenation, nor when DVR is merged. The deployer will have to
specify that the Cisco routing service plugin be used instead of the community
one. A configuration agent must also be deployed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;The below figure shows the new router service plugin and the components it
interacts with. The hosting device boxes are objects in the database and are
just to show that the router service plugin knows about devices it has placed a
Neutron router inside. The RouterHostingDeviceBindings box represents the
database table where this binding is stored.&lt;/p&gt;
&lt;p&gt;Novaclient is used to interact with Nova to requeat that CSR1kv VMs are created
and deleted.&lt;/p&gt;
&lt;p&gt;The plugin to config agent RPC is analogous to the l3 agent RPC. I.e., plugin
sends router-update/delete notifications to the config agent. The latter
periodically does get_routers() callback to hte plugin to fetch latest router
configurations for updated routers.&lt;/p&gt;
&lt;p&gt;The router information sent to the config agent includes information about the
device that is hosting the Neutron router. The config agent can thereby remotely
configure that device via a virtual management network (which is a Neutron
provider Network).&lt;/p&gt;
&lt;p&gt;All CSR1kv VMs that are spun up using Nova are owned by a special tenant. This
is also the case for the Neutron resources created for the CSR1kv VM instances.
These resources include: Neutron port on the virtual management network, Neutron
Networks with trunking capability and Neutron Ports on those networks.&lt;/p&gt;
&lt;p&gt;A CSR1kv VM instance will only host one Neutron Router. As a consequence, a
CSR1kv VM instance will be allocated solely to the tenant owning the Neutron
Router it hosts. This limitation is imposed not for performance reasons but to
reduce the scope of the implementation. It allows us to simplify the scheduling.
VPN and/or Firewall service instances may be hosted in a CSR1kv VM instance if
those instances are bound to the Neutron Router hosted in the CSR1kv VM
instance.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;                      &lt;span class="o"&gt;............&lt;/span&gt;
                      &lt;span class="o"&gt;.&lt;/span&gt;   &lt;span class="n"&gt;Nova&lt;/span&gt;   &lt;span class="o"&gt;.&lt;/span&gt;
                      &lt;span class="o"&gt;.&lt;/span&gt;   &lt;span class="n"&gt;api&lt;/span&gt;    &lt;span class="o"&gt;.&lt;/span&gt;
                      &lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="n"&gt;server&lt;/span&gt;  &lt;span class="o"&gt;.&lt;/span&gt;
                      &lt;span class="o"&gt;............&lt;/span&gt;
                            &lt;span class="o"&gt;^&lt;/span&gt;
                            &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;............................|.............&lt;/span&gt;     &lt;span class="o"&gt;.............&lt;/span&gt;     &lt;span class="o"&gt;..............&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Neutron&lt;/span&gt;                   &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Some&lt;/span&gt;      &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Nova&lt;/span&gt;       &lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt;                    &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt;    &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Compute&lt;/span&gt;    &lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt;           &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt;            &lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;                           &lt;span class="o"&gt;|&lt;/span&gt;            &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt;           &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;+-------+&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;+------------------------|---------+&lt;/span&gt;  &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt;           &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Hosting&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Cisco&lt;/span&gt; &lt;span class="n"&gt;Router&lt;/span&gt;         &lt;span class="n"&gt;Nova&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt;           &lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;+----&amp;gt;|&lt;/span&gt;&lt;span class="n"&gt;Device&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Service&lt;/span&gt; &lt;span class="n"&gt;Plugin&lt;/span&gt;       &lt;span class="n"&gt;client&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt;           &lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Svc&lt;/span&gt; &lt;span class="n"&gt;VM&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt;           &lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;+-------+&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;RPC&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;+------+&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;..............&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+-------+&lt;/span&gt;   &lt;span class="o"&gt;+-------------+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;NOTIFIC&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="o"&gt;|&amp;lt;---+&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;+-------+|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;Router&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&amp;lt;---------&amp;gt;|&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;    &lt;span class="n"&gt;Device&lt;/span&gt; &lt;span class="n"&gt;specific&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+-------+||&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;HostingDevice&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;CALLBACKS&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;    &lt;span class="n"&gt;protocol&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Hosting&lt;/span&gt;&lt;span class="o"&gt;||+&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Bindings&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;+------+&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;    &lt;span class="n"&gt;Netconf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;REST&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Device&lt;/span&gt; &lt;span class="o"&gt;|+&lt;/span&gt;    &lt;span class="o"&gt;+-------------+&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt;           &lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;+-------+&lt;/span&gt;                        &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt;           &lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="o"&gt;+----------------------------------+&lt;/span&gt;  &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt;           &lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;                                        &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt;           &lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;                                        &lt;span class="o"&gt;.&lt;/span&gt;     &lt;span class="o"&gt;.&lt;/span&gt;           &lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;..........................................&lt;/span&gt;     &lt;span class="o"&gt;.............&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee: bob-melander&lt;/p&gt;
&lt;p&gt;Other contributors: hareesh-puthalath, skandasw&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement new router DB mixin derived from extraroute DB mixin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement new mixin to manage CSR1kv VMs using Nova.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement RPC notifications and callbacks for interaction with config agent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement new routing service plugin that uses above mixins and RPC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create template configuration .ini file for the routing service plugin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create bash scripts that exemplify how to setup the routing service plugin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extend existing L3 routing unit test suite to cover new functionality.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Devstack must be updated to support this plugin.
The router service plugin uses Cisco config agent:
&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/cisco-config-agent"&gt;https://blueprints.launchpad.net/neutron/+spec/cisco-config-agent&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will be added for all new functionality.
Tempest support for 3rd party CI is ongoing work and will be ready for Juno.
Functional and scenario tests for community L3 implementation will be useful
also for this implementation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Will require new documentation in Cisco sections.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Tue, 29 Apr 2014 00:00:00 </pubDate></item><item><title>Enable JSON support for N1KV REST calls</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/cisco-n1kv-json-support.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/cisco-n1kv-json-support"&gt;https://blueprints.launchpad.net/neutron/+spec/cisco-n1kv-json-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Need to enable Cisco N1KV plugin to accept REST API responses in JSON.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, Cisco N1KV Neutron plugin and VSM (controller) communicate
using REST APIs. The VSM is capable of returning responses in XML and JSON.
However, the plugin handles only XML responses.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposed change is to use the Requests library to support handling of
REST API responses in JSON. The Requests library will replace the httplib2
library currently being used by the plugin.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;requests library version &amp;gt;= 1.1
(as per neutron requirements.txt)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;sopatwar&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;abhraut&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Replace httplib2 library used in the plugin with Requests library.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify all the methods in n1kvclient to use the Requests library.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace the current XML parsing logic in the response handlers for policy
profiles to handle JSON responses.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Currently, unit tests include coverage of XML responses.
The test code will be modified to handle JSON responses.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 25 Apr 2014 00:00:00 </pubDate></item><item><title>Faster API list responses</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/faster-list-responses.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/faster-list-responses"&gt;https://blueprints.launchpad.net/neutron/+spec/faster-list-responses&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Neutron API currently performs a policy check for each attribute of
each element in a list response; this is penalizing response times.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Slowness in API responses has been reported in a few bug reports; it has
also been observed recently with several plugins.
The root cause of this issue is that a policy engine check is performed for
every attribute of every resource returned in a response.
A list response can contain a lot of items; this is true in particular for
ports, especially when the API requests are executed with admin credentials
without filters.
In these cases the huge number of policy checks performed becomes a
non-negligible scalability limiting factor.
For a list operation, post-plugin operations (ie: policy checks) take
about 50% of the time spent in the plugin.&lt;/p&gt;
&lt;p&gt;While this problem is not difficult to solve, its solution might require
a change which can result in a slightly different policy engine behaviour.
The API layer for list responses puts every item through policy checks to
check which ones should not be visible to the user at all.
However it also puts every attribute through a policy check to exclude those
which should not be visible to the user, such as provider attributes for
regular users.
Doing this for every resource might make sense only if the visibility of an
attribute depends on the data in the resource itself. For instance a policy
that shows port binding attributes could be defined for all the ports whose
name is “ernest”.
This might appear as great flexibility, but however it does not make sense
at all. A list operation indeed should return the same set of attributes
for each resource in the response.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Policy checks should be used to determine the list of attributes to show only
once for every response; this attribute list should then be used for every
resource to be included in the response for the list operation.&lt;/p&gt;
&lt;p&gt;In order for this to work there should not be any attribute-level policy
which relies on the resource value; this limitation seems to be fair.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Alternative #1:
Move attribute-level checks back in the plugin.
This was how the software worked before the Havana release.
This does not feel right at all as this will allow, in theory, to have
deployments whose API behaviour differs according to the plugin they’re
running.
All the authZ work should be performed in the common API layer.&lt;/p&gt;
&lt;p&gt;Alternative #2:
Iterate over items and run policy check only if the attribute’s policy
is dependent on the resource data.
This will require a level of introspection in the policy engine that we
currently do not have and will probably never have.
Also, it does not feel right that different items in the same list
response might end up having different attributes. A list response is
like a table, with a fixed number of columns.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;No Data model change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;No API change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;This blueprint will not change the logic of authZ processing.
However, deployments that have defined custom policies for attributes
whose evaluation result depends on the value of the resource being
analyses might be affected.&lt;/p&gt;
&lt;p&gt;This should be documented as it might result in attributes being returned
in responses whereas the deployer’s wish was to hide them.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;No impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;No further interaction.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;An estimated 33% improvement on list responses.
Prototype code for this blueprint has been tested with list responses
to 4,000 items.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Deployers should be aware that attribute-level policies dependent on resurce
values (eg.: field checks) should not be performed anymore.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;No developer impact. Limited chance of merge conflicts.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;salvatore-orlando&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;This will be implemented with a single, relatively small, patch.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;No dependency.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The code being altered is already covered by existing unit and integration
tests.
New unit tests might be defined as needed.
New integration tests should not be needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Guidelines for managing Neutron authZ policies should be updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 24 Apr 2014 00:00:00 </pubDate></item><item><title>Extend management features of L3 metering API</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/l3-metering-mgnt-ext.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/l3-metering-mgnt-ext"&gt;https://blueprints.launchpad.net/neutron/+spec/l3-metering-mgnt-ext&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint aims to extend the current metering API in order to help
administrators to manage the metering labels/rules.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently the administrator has to associate metering label for each tenant
by the hand, there is no way to add a default metering label/rules which will
be automaticaly associated with all current tenants and also with the tenants
that will be created.&lt;/p&gt;
&lt;p&gt;Use cases:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The administrator wants to get traffic counters from the public for a billing
purpose for all current tenants and for the future tenants. Currently each
time a tenant is added the administrator has to create a new label for it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The administrator wants to get traffic counters from service networks for
monitoring purpose, for instance from a provider network which exposes
physical resources (ex: db, storage)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The goal is to extend the current API to add an extra parameter for the
labels creation which specifies whether the label will be shared by all tenants
or not. A such label will be shared by all current tenants and also by the
tenants which will be created.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative could be to add an extra configuration file which set some
metering labels/rules at the metering agent startup.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;An extra field will be added to the MeteringLabel data model to specify whether
a label is shared or not. By default a metering label will be not shared.
The current labels will be unchanged.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;A new shared attribute will be introduced to the current MeteringLabel model:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute
Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Access&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default
Value&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Validation/
Conversion&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;shared&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;bool&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;RW, admin&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;false&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;N/A&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;No change, only admin users are allowed to create/delete labels/rules.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The shared parameter will be exposed to the end user through the neutron
client, ex:&lt;/p&gt;
&lt;p&gt;neutron meter-label-create testlabel –shared&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Sylvain Afchain &amp;lt;sylvain-afchain&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The work is split up into two parts:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;API, Data model, Metering service plugin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron client update.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;For tempest test coverage, new API tests for the shared parameter will be
provided.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation and examples for the shared parameter will be provided.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 23 Apr 2014 00:00:00 </pubDate></item><item><title>ML2 Mechanism Driver for embedded switch SR-IOV NIC</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/ml2-sriov-nic-switch.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ml2-sriov-nic-switch"&gt;https://blueprints.launchpad.net/neutron/+spec/ml2-sriov-nic-switch&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint is to add ML2 Mechanism Driver for SR-IOV capable NIC based
switching (HW VEB), such as Mellanox ConnectX Family.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;SR-IOV capable NIC, such as Mellanox ConnectX Family cards, provide
embedded switching capability. As part of the both nova and neutron
enchacements to support SR-IOV ports, the mechanism driver proposed
by this blueprinht will initially support VLAN network type.
Nova VIF Driver will take care of setting VLAN ID via libvirt network
interface XML.
The mechanism driver will require L2 agent to make run time networking
setting updates on SR-IOV ports.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The Ml2 mechanism driver will be based on Simple Agent Mechanism Driver.
The Ml2 mechanism driver will be capable to bind ports that match supported
criteria listed below.
It will support DIRECT and MACVTAP vnic types.
It will support PCI VENDOR INFO initially matching Mellanox ConnectX Family.
There will be an option to load the list of supported PCI VENDOR INFO
from configuration file.
The mechanism driver will include vlan_id attribute in port vif_details
dictionary to provide nova vif driver with vlan id details.
The mechanism driver will expect to get port binding:profile populated with
physical_network and pci_vendor_info to identify if should bind the port and
on which physical network to bind.
To support L2 agent rpc calls, _device_to_port_id method of ml2 rpc module
should be modified to service devices that are not prefixed by tap.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative solution would be to develop a monolithic plugin.
Since SR-IOV resources are limited and support less flexible configuration
options as virtual ports, it makes sense to provide SR-IOV ports aside with
virtual ports.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Possible impact on performance may be due to pci_vendor_info match check during
the attemt to bind port.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The deployer must configure the following configuration variables:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;VLAN namespace and ranges to be used for OpenStack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Supported pci vendor info records if different from default list.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:
Irena Berezovsky &amp;lt;irenab&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Ml2 Mechanism Driver for NIC based switch&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ml2 Agent for NIC based switch&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ML2 RPC support for SR-IOV devices require by L2 agent&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Nova vif driver is required to support SR-IOV NIC based virtual interface.
This functionality is added following the nova blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/pci-passthrough-sriov"&gt;https://blueprints.launchpad.net/nova/+spec/pci-passthrough-sriov&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The code will be covered with unit tests.
For tempest test coverage, third party testing is provided.
The tests are run in devstack setup on physical server with SR-IOV
ConnectX Family card.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Configuration Reference guide will be updated from the code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;SR-IOV support discussion details are here:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Meetings/Passthrough"&gt;https://wiki.openstack.org/wiki/Meetings/Passthrough&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 23 Apr 2014 00:00:00 </pubDate></item><item><title>ofagent l2pop support</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/ofagent-l2pop.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ofagent-l2pop"&gt;https://blueprints.launchpad.net/neutron/+spec/ofagent-l2pop&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;implement l2pop support for ofagent agent.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;many packets sent to tunnels because of:&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;tenant unawareness; no need to forward a packet to nodes
which doesn’t run endpoints (typically VMs) belonging to the tenant.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;broadcasts, namely arp requests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;see &lt;a class="reference external" href="https://wiki.openstack.org/wiki/L2population_blueprint"&gt;L2population_blueprint&lt;/a&gt; for more discussions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;implement l2pop-based tunnel management as it’s done in ovs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;implement local arp responder by handling packet-ins&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;local arp responder part can be implemented differently.
for example, using nicira extensions as described in &lt;a class="reference external" href="https://wiki.openstack.org/wiki/Ovs-flow-logic#OVS_flows_logic_with_local_ARP_responder"&gt;Ovs-flow-logic&lt;/a&gt;.
however it isn’t a choice for ofagent as there’s no way to implement such
a flow-based arp responder without vendor extensions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;this would naturally improve performance.&lt;/p&gt;
&lt;p&gt;see &lt;a class="reference external" href="https://wiki.openstack.org/wiki/L2population_blueprint"&gt;L2population_blueprint&lt;/a&gt; for more discussions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;yamamoto&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;kakuma&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;implement l2pop-based tunnel management as it’s done in ovs.
the following is working implementation of this.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/87440/"&gt;https://review.openstack.org/#/c/87440/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;implement local arp respoder by handling packet-ins
the following is working implementation of this.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/94183/"&gt;https://review.openstack.org/#/c/94183/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;ryu/ofagent third party testing would find regressions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;none&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/l2-population"&gt;https://blueprints.launchpad.net/neutron/+spec/l2-population&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/L2population_blueprint"&gt;https://wiki.openstack.org/wiki/L2population_blueprint&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/OFAgent/Todo"&gt;https://wiki.openstack.org/wiki/Neutron/OFAgent/Todo&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/OFAgent/FlowTable"&gt;https://wiki.openstack.org/wiki/Neutron/OFAgent/FlowTable&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/yamt/ryu/blob/arp-proxy/ryu/app/arp_proxy.py"&gt;https://github.com/yamt/ryu/blob/arp-proxy/ryu/app/arp_proxy.py&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 22 Apr 2014 00:00:00 </pubDate></item><item><title>ML2 Mechanism Driver for the Cisco APIC</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/ml2-cisco-apic-mech-driver.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ml2-cisco-apic-mechanism-driver"&gt;https://blueprints.launchpad.net/neutron/+spec/ml2-cisco-apic-mechanism-driver&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint is to introduce the Cisco APIC to OpenStack
Neutron. The plugin is implemented as an ML2 mechanism driver.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The APIC (Application Policy Infrastructure Controller) together with
Cisco Nexus 9000 switches provides programmable, policy-driven network
control.&lt;/p&gt;
&lt;p&gt;The mechanism driver proposed here will interact with the APIC to
dynamically manage networking for OpenStack instances. The APIC will
intelligently configure the hardware layer and manage VXLAN overlays
for networks. VXLAN gateways will be implemented by the controller at
the top of rack layer to reduce encapsulation latency in the software
switch layer.&lt;/p&gt;
&lt;p&gt;Use Cases:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Application centric policy based networking&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;External controller managed network fabric&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VXLAN Overlay networks&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The diagram below provides a high level overview of how the APIC
plugin will integrate into a working environment consisting of
multiple hosts with virtual switches connected by a fabric of Nexus
9000 switches. The APIC Mechanism Driver for ML2 communicated with the
APIC via its REST API.&lt;/p&gt;
&lt;p&gt;Flows:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;        +–––––––––––––––––––––––––+
        |                         |
        | Neutron Server          |
        | with ML2 Plugin         |
        |                         |
        |          +–––––––––––+  |
+–––––––+          |   APIC    |  |
|       |          | Mechanism |  |                  +–––––––––––––––––+
|       |          |  Driver   |  |                  |                 |
|  +––––+       +––+–––––––––––+––+      REST API    |   Cisco         |
|  |    |       |   APIC Client   +––––––––––––––––––+   APIC          |
|  |    +–––––––+–––––––––––––––––+                  |                 |
|  |                                                 |                 |
|  |                                                 +–––+–––+–––––––––+
|  |    +–––––––––––+––––––––––––––+                     |   |
|  +––––+ L2 Agent  | Open vSwitch +–––––+               |   |
|       +–––––––––––+––––––––––––––+     |               |   |
|       |                          |     |               |   |
|       |        HOST 1            |     |               |   |
|       |                          |     |      +––––––––+–––|––––––+
|       +––––––––––––––––––––––––––+     |      |            |      |
|                                        +––––––+  +–––––––––+––––––+––+
|                                               |  |                   |
|       +––––––––––+–––––––––––––––+            |  |     Cisco         |
+–––––––+ L2 Agent | Open vSwitch  +––––––––––––+  |   Nexus 9000      |
        +––––––––––+–––––––––––––––+            |  |    Switches       |
        |                          |            +––+                   |
        |        HOST 2            |               |                   |
        |                          |               +–––––––––––––––––––+
        +––––––––––––––––––––––––––+
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The APIC mechanism driver updates the APIC with port, network and
subnet changes from Neutron. The APIC configures the physical switch
fabric.&lt;/p&gt;
&lt;p&gt;The APIC mechanism driver is designed to operate together with the OVS
mechanism driver for handling network operations and port binding on
the compute nodes.&lt;/p&gt;
&lt;p&gt;The APIC mechanism driver implements the following Neutron events:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Port create/update for compute instances. (Note: the driver does not
handle port binding – that is left to the OVS driver.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Network create/delete.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subnet create.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative solution would be to develop a monolithic plugin. The
biggest advantage of using the ML2 mechanism driver approach is that
it allows us to easily use the existing OVS agent for virtual
switching.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Three new models are created by this driver. These models are specific
to this driver and are used for keeping in sync with the APIC.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;NetworkEPG: Tracks network to End Point Group mapping in the APIC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PortProfile: Tracks hardware switch/module/port configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TenantContract: Tracks contracts and filters created on the APIC.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;A database migration is included to create the tables for these
models.&lt;/p&gt;
&lt;p&gt;No existing models are changed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The performance of ML2 when configured with the APIC driver will be
dependent on the performance of the link between Neutron and the APIC,
and on the responsiveness of the APIC itself.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The deployer must configure the installation to use the APIC with the
following configuration variables:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;IP address and port number of the APIC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Username and password to login as administrator to the APIC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VLAN namespace and ranges to be used for OpenStack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Node, entity and function profiles describing the switch fabric
infrastructure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Switch-to-host mappings for the compute nodes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additionally, the deployer must configure the ML2 plugin to include
the openvswitch mechanism driver before the APIC mechanism driver:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ml2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;mechanism_drivers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openvswitch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;cisco_apic&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Arvind Somya &amp;lt;asomya&amp;gt;&lt;/p&gt;
&lt;p&gt;Henry Gessau &amp;lt;gessau&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The work is split up into two parts:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;APIC Client, models, configuration, unit tests.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The APIC Client is a REST Client to the APIC. It maps requests
to the “Managed Object” model of the APIC. Only the subset of
the full APIC model needed by the driver is provided.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;APIC mechanism driver and supporting code.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The mechanism driver implements the port, network and subnet
methods that affect the APIC. It maps Neutron operations into
operations for the APIC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Supporting code consists of an APIC manager that ensures the
APIC state is in sync with Neutron.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;There are no new library requirements. The following third party
library is used:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;requests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Complete unit test coverage of the code is included.&lt;/p&gt;
&lt;p&gt;For tempest test coverage, third party testing is provided. The Cisco
CI reports on all changes affecting this driver. The testing is run in
a setup with an OpenStack deployment (devstack) connected to a live
APIC and a Cisco Nexus 9000 physical switch.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Configuration details.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.cisco.com/go/apic"&gt;http://www.cisco.com/go/apic&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 21 Apr 2014 00:00:00 </pubDate></item><item><title>Extraroute Extension support for Nuage Plugin</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/extraroute-ext-support-for-nuage-plugin.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/extraroute-ext-support-for-nuage-plugin"&gt;https://blueprints.launchpad.net/neutron/+spec/extraroute-ext-support-for-nuage-plugin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Adding extraroute extension support to existing nuage networks’ Plugin&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Current Nuage Plugin does not support Neutron’s extra-route extension.
Nuage’s VSP supports this feature and the support for extension needs
to be added in the plugin code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Adding extension support code in Nuage plugin.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;There are couple of extra tables which will be needed to support this.
One is routerroutes which already exist in neutron. No schema changes required
for that table.
Second table is Nuage plugin specific. This will be added as part of the new
code.&lt;/p&gt;
&lt;p&gt;It could look like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;RouterRoutesMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BASEV2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;models_v2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;__tablename__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'routerroutes_mapping'&lt;/span&gt;
    &lt;span class="n"&gt;router_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'routers.id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ondelete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"CASCADE"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;nuage_route_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;migration script will need to be generated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Nuage’s VSP supports adding static-route to L3 Domain which fits nicely
with extraroute extension supported by openstack’s neutron.&lt;/p&gt;
&lt;p&gt;Following is a mapping of the neutron’s work-flow for nuage plugin:&lt;/p&gt;
&lt;p&gt;Assume router1 exist.
STEP1:
neutron router-update router1 –routes type=dict list=true destination=15.0.0.0/24,nexthop=10.10.0.5
This will create a staticroute entry in l3-domain router1 in VSP&lt;/p&gt;
&lt;p&gt;STEP2:
neutron router-update router1 –routes type=dict list=true destination=15.0.0.0/24,nexthop=10.10.0.5 destination=25.0.0.0/24,nexthop=10.10.0.6
This will add one more staticroute to the same.&lt;/p&gt;
&lt;p&gt;STEP3:
neutron router-update router1 –routes type=dict list=true destination=15.0.0.0/24,nexthop=10.10.0.5
This will delete staticroute of STEP2.&lt;/p&gt;
&lt;p&gt;Basically everytime you specify routes option it treats it as a new set of value.
So sticking to that same behavior.&lt;/p&gt;
&lt;p&gt;STEP4:
neutron router-update router1 –routes action=clear
Cleans up all the staticroute.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Ronak Shah&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;ronak-malav-shah&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Extension code in Nuage plugin
Nuage Unit tests addition
Nuage CI coverage addition&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit Test coverage for extra-route extension within Nuage unit test
Nuage CI will be modified to start supporting this extension tests&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 18 Apr 2014 00:00:00 </pubDate></item><item><title>Provider Validation for L3 Plugins</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/l3-svcs-vendor-validation.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/l3-svcs-vendor-validation"&gt;https://blueprints.launchpad.net/neutron/+spec/l3-svcs-vendor-validation&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently, validation of end user selections is tightly bound to the
reference implementation. As a result, alternate providers cannot
validate end user configuration selections, until after they have
already been persisted.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;When an L3 service request is received by Neutron, it invokes the
corresponding service plugin, which &lt;em&gt;validates&lt;/em&gt; and &lt;em&gt;persists&lt;/em&gt; info
for the request (typically in one step). Finally, the plugin will
invoke the service driver to &lt;em&gt;apply&lt;/em&gt; the changes.&lt;/p&gt;
&lt;p&gt;It is at the &lt;em&gt;apply&lt;/em&gt; stage, when the provider’s service driver has
an opportunity to take action on the request. If the provider has
additional constraints, it can reject the request, but the
resource(s) will already have been persisted.&lt;/p&gt;
&lt;p&gt;For example, when creating a VPN IPsec site connection using an IKE
policy that selected v2, the connection will pass validation, be
persisted, and the service driver called. With the Cisco CSR,
which currently does not support v2 via its REST API, the service
driver can raise an exception during the &lt;em&gt;apply&lt;/em&gt;. However, the
connection will have already been created and persisted.&lt;/p&gt;
&lt;p&gt;In addition, if a service driver has persistence to perform, it
must do that during the &lt;em&gt;apply&lt;/em&gt; phase.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This proposal is to break out the validation into a separate
function, and provide a way for provider service drivers to
extend or override the validation logic, if desired.&lt;/p&gt;
&lt;p&gt;Research into the current validation shows that it must be
done during the persistence step, to handle the situation
where multiple clients may be making changes to the same
resources simultaneously. The transaction will enforce
consistency.&lt;/p&gt;
&lt;p&gt;The approach planned is to create default validation logic
in the service driver abstract base class, and during
persistance, select the active service driver and call it’s
validation method.&lt;/p&gt;
&lt;p&gt;The service driver can perform validation before, after, or
instead of the default logic, or not provide a validation
method and the default validation in the ABC will be performed.&lt;/p&gt;
&lt;p&gt;Goal is to roll out the same proposal for all L3 service plugins.&lt;/p&gt;
&lt;p&gt;This will be a structural change, and not a behavorial change.&lt;/p&gt;
&lt;p&gt;As part of the Juno summit there was a discussion of using
the TaskFlow package for managing the processing for validate,
persistence, and apply operations.&lt;/p&gt;
&lt;p&gt;More research will be needed on TaskFlow, but regardless, the
validation logic should be separated from the persistence logic
and can be done as preliminary work.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative is to mark the resource status/state as &lt;em&gt;ERROR&lt;/em&gt;, but
the database will still be inconsistent with the actual state of
the requested operation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;No changes to the database schema or operations is expected, other
that it would now accurately reflect the actual state of the
resources.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;No expected changes to REST APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None?&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There is no significant performance impact expected.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Providers will want to update their service drivers to take advantage
of the new ability to validate and reject requests, based on provider
capabilities.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;pmichali&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Anyone&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Given the scope and number of L3 services, additional contributers
would be greatly appreciated!&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;For each L3 service create and update API:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Refactor the database functionality
* Pull out validation logic and move to service driver ABC
* Add hook to call validation logic now in service driver&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add validation method to provider’s service driver, if needed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update unit tests based on structural changes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note: The separation of the validation logic can be done on
each L3 service independently (there are no dependencies), and
as needed (e.g. only on resources where multiple implementations
have different validation needs), if desired.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Since this is a structural change, it is expected that no additional
tempest tests will be needed.&lt;/p&gt;
&lt;p&gt;Unit tests will need modification, mostly due to method name changes,
but may also change due to better isolation of the logic. Tests that
were checking both validation and persistence (or were doing
persistence to check validation), can be split out into more isolated
test cases. This should reduce the amount of overlap in test cases
(possibly eliminating some tests), better isolation, and possibly
better performance (not having to do several tasks to test some
functionality).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None at this time.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 17 Apr 2014 00:00:00 </pubDate></item><item><title>Internal DNS Resolution</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/liberty/internal-dns-resolution.html</link><description>

&lt;dl class="field-list simple"&gt;
&lt;dt class="field-odd"&gt;Author&lt;span class="colon"&gt;:&lt;/span&gt;&lt;/dt&gt;
&lt;dd class="field-odd"&gt;&lt;p&gt;Carl Baldwin &amp;lt;&lt;a class="reference external" href="mailto:carl.baldwin%40hp.com"&gt;carl&lt;span&gt;.&lt;/span&gt;baldwin&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/internal-dns-resolution"&gt;https://blueprints.launchpad.net/neutron/+spec/internal-dns-resolution&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Users of an OpenStack cloud would like to look up their instances by name in an
intuitive way using the Domain Name System (DNS).  They boot an instance using
Nova and they give that instance an “Instance Name” as it is called in the
Horizon interface.  That name is used as the hostname from the perspective of
the operating system running in the instance.  It is reasonable to expect some
integration of this name with DNS.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Neutron already enables DNS lookup for instances using an internal dnsmasq
instance.  It generates a generic hostname based on the private IP address
assigned to the system.  For example, if the instance is booted with
&lt;em&gt;10.224.36.4&lt;/em&gt; then the hostname generated is &lt;em&gt;host-10-224-36-4.openstacklocal.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The first problem with this implementation is that the name used in DNS does
not match what the instance knows as its host name.  This creates problems with
sudo and other software that expect to be able to look up its own hostname
using DNS &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/nova/+bug/1175211"&gt;https://bugs.launchpad.net/nova/+bug/1175211&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;p&gt;The second problem with this implementation is that the end user does not know
this name without some special knowledge.  The generated name is not presented
anywhere in the API and therefore cannot be presented in any UI either.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="overview"&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
&lt;p&gt;This blueprint will reconcile the DNS name between Nova and Neutron.  Neutron
DHCP offers will use Nova’s instance &lt;em&gt;hostname&lt;/em&gt; value as its hostname instead
of the Neutron generated hostname.  Neutron DNS will reply to queries for the
new hostname.  See the corresponding Nova blueprint for more details about the
hostname that will be passed &lt;a class="footnote-reference brackets" href="#id4" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/internal-dns-resolution"&gt;https://blueprints.launchpad.net/nova/+spec/internal-dns-resolution&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;p&gt;The Neutron Port API will be extended to add a &lt;em&gt;dns_name&lt;/em&gt; field to the port.
This field will be used by Nova to pass an intance’s &lt;em&gt;hostname&lt;/em&gt; during port
creation or update. The valid values for this field are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A partially qualified domain name (PQDN).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A fully qualified domain name (FQDN).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To handle existing installations, Neutron will fall back completely to the
current behavior in the event that a &lt;em&gt;dns_name&lt;/em&gt; is not supplied with the port.&lt;/p&gt;
&lt;p&gt;Also, as another level of backwards compatibility, the DNS names formerly
created by Neutron will continue to be available for forward DNS lookups in
dnsmasq.&lt;/p&gt;
&lt;p&gt;The Neutron API will add the &lt;em&gt;dns_name&lt;/em&gt; field when showing port detail so that
users can see it.&lt;/p&gt;
&lt;p&gt;The following table shows how DNS will respond to various queries.  The table
uses &lt;em&gt;example.com.&lt;/em&gt; rather than &lt;em&gt;openstacklocal.&lt;/em&gt; to reflect that this will
only be enabled when a domain name is associated.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Rec. Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Query&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;dns_name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Response&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;name.example.com.&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;10.224.36.4&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;A&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;host-10-224-36-4.example.com.&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;(n/a)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;10.224.36.4&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;AAAA&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;name.example.com.&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;fd5d:19f:52e9::2&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;PTR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4.36.224.10.in-addr.arpa&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;(none)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;host-10-224-36-4.example.com.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;PTR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4.36.224.10.in-addr.arpa&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;name.example.com.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;PTR&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;fd5d:19f:52e9::2.ip6.arpa&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;name.example.com.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;When Neutron cannot accept a name from Nova because it does not validate,
Neutron will fail the port creation or update. See the  &lt;a class="reference internal" href="#data-model-impact"&gt;Data model impact&lt;/a&gt;
section for more details about this association.&lt;/p&gt;
&lt;p&gt;A second read-only attribute, &lt;em&gt;dns_fqdn&lt;/em&gt;, will be added to Neutron ports. The
API will add this &lt;em&gt;dns_fqdn&lt;/em&gt; attribute when showing the port details. This wiil
enable users to see the fully qualifed name generated by Neutron based on the
&lt;em&gt;dns_name&lt;/em&gt; passed during port creation or update. The following table shows how
FQDN’s will be generated from &lt;em&gt;dns_name&lt;/em&gt; with &lt;em&gt;example.com.&lt;/em&gt; as the configured
domain name:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;dns_name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;dns_fqdn&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;vm01&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;vm01.example.com.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;vm01.test1&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;vm01.test1.example.com.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;vm01.test1.example.com.&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;vm01.test1.example.com.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;vm01.test1.other.com.&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;API will fail port creation or update&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Not specified by user&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Null&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Based on above table, the rules for &lt;em&gt;dns_fqdn&lt;/em&gt; generation can be summarized as
follows:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If &lt;em&gt;dns_name&lt;/em&gt; is a FQDN, validate that the higher level labels match the
configured domain name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If &lt;em&gt;dns_name&lt;/em&gt; is a PQDN, append the configured domain name to form a FQDN.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If &lt;em&gt;dns_name&lt;/em&gt; is not specified by the user, &lt;em&gt;dns_fqdn&lt;/em&gt; will be null.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="is-not"&gt;
&lt;h4&gt;Is Not&lt;/h4&gt;
&lt;p&gt;This change does not propose a model that would allow driver implementations to
implement internal DNS using something other than dnsmasq.  That could be done
in a follow-on blueprint to this one.  Some things to consider for the future
are:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The port that DNS listens on currently is the same as DHCP.  This is how
dnsmasq does it but it may not be natural with other resolvers.  There are
problems inherent with sharing this port.  For example, there is little to
no need for the DHCP ports to have predictable IP addresses.  However, it is
essential for DNS to have a predictable IP address.  Problems have resulted
from this &lt;a class="footnote-reference brackets" href="#id6" id="id5" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.  It may be worth considering reserving IP addresses on the
local network for use by the DNS resolver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Coupling the DNS resolver with the gateway router and using its IP address
as the DNS IP address will not work on an isolated network where there is no
gateway.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For internal DNS, the resolver should provide both authoritative responses
for the local domain and either forward other queries to an upstream
resolver or provide recursive resolution.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id5"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/neutron/+bug/1288923"&gt;https://bugs.launchpad.net/neutron/+bug/1288923&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;This blueprint will add a dns_name field to the Port data model. Values will
be validated as legal partially qualified domain names (PQDN) or fully
qualified domain names (FQDN). Within these names, DNS labels will be validated
according to RFC 1035, which describes the valid format as:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;They must start with a letter, end with a letter or digit, and have as
interior characters only letters, digits, and hyphen.  There are also some
restrictions on the length.  Labels must be 63 characters or less. &lt;a class="footnote-reference brackets" href="#id8" id="id7" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;4&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id8" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id7"&gt;4&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://tools.ietf.org/html/rfc1035"&gt;http://tools.ietf.org/html/rfc1035&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;p&gt;A complication is that DNS labels are treated as case insensitive &lt;a class="footnote-reference brackets" href="#id10" id="id9" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;5&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;.
Neutron will convert upper case characters to lower case before recording the
name.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id10" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id9"&gt;5&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://tools.ietf.org/html/rfc4343"&gt;http://tools.ietf.org/html/rfc4343&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;p&gt;Validation will only be performed on the name when the user has enabled DNS for
the port’s network by associating a domain with the network.&lt;/p&gt;
&lt;p&gt;A second read-only attribute, &lt;em&gt;dns_fqdn&lt;/em&gt;, will be added to the Port data model.
The API will add this &lt;em&gt;dns_fqdn&lt;/em&gt; attribute when showing the port details and
will store the FQDN generated by Neutron, as described in the ‘&lt;a class="reference internal" href="#overview"&gt;Overview&lt;/a&gt;’
section.&lt;/p&gt;
&lt;p&gt;An appropriate database migration script will be provided along with the
implementation to add these fields to the ports table on upgrade.&lt;/p&gt;
&lt;p&gt;The default value for these fields will be null in order to maintain
compatibility with existing installations.  A null value corresponds to the
field being unspecified in the API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;The addition of the dns_name and dns_fqdn fields to the port object in the data
model will need correspending changes to the Ports API . These changes will be
done in a way that maintains compatibility with the existing API.&lt;/p&gt;
&lt;p&gt;Users will be able to specify the dns_name field for POST and PUT operations.
Leaving it unspecified in the API call will result in a null value in the
model.  Any non-null value passed in this field will be validated at the API
level as a PQDN or FQDN.  The format is described in the &lt;a class="reference internal" href="#data-model-impact"&gt;Data model impact&lt;/a&gt;
section.&lt;/p&gt;
&lt;p&gt;dns_fqdn is a read-only attribute and will be included by the API when
returning a port details as a result of POST, PUT or GET operations. This
attribute will have a null value when the user has not specified a value to
dns_name. The ‘&lt;a class="reference internal" href="#overview"&gt;Overview&lt;/a&gt;’ section describes how Neutron generates values for
this attributes.&lt;/p&gt;
&lt;p&gt;No policy changes are needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;This change will enable collection of user data in the dns_name field.  This
data will be validated as a legal PQDN or FQDN.  This user data will then be
used to enable DNS lookup using the name internally to Neutron.  I don’t expect
this to present any new security risks due to the design of this feature.  As
always, care should be taken in the code review to ensure that no risks creep
in inadvertently.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;The python-neutronclient may need modification to handle the new fields.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Database operations for creating and updating a port may be affected marginally
due to the addition of a new constraint on the dns_name field. No new database
locks are needed so the effect is expected to be minimal.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ipv6-impact"&gt;
&lt;h3&gt;IPv6 Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;This change was carefully designed to allow new Nova and Neutron code to be
deployed independently. The new feature will be available when both upgrades
are complete.&lt;/p&gt;
&lt;p&gt;If Neutron is upgraded before Nova, there is no problem because the
dns_name field is not required and behavior defaults to old behavior.&lt;/p&gt;
&lt;p&gt;If Nova is upgraded before Neutron then Nova will see errors from the Neutron
API when it tries passing the dns_name field.  Nova will recognize this error
and retry the operation without the dns_name.&lt;/p&gt;
&lt;p&gt;DNS names will only be passed for new instances after this feature is
enabled. Existing instances will use the old Neutron generated generic
names.&lt;/p&gt;
&lt;p&gt;No new configuration options are introduced with this change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="community-impact"&gt;
&lt;h3&gt;Community Impact&lt;/h3&gt;
&lt;p&gt;A number of folks in the community have complained about the lack of agreement
between the compute instance hostname and the DNS name in Neutron.  In addition
to the bug mentioned several times in this blueprint, there have been IRC
discussions &lt;a class="footnote-reference brackets" href="#id12" id="id11" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;6&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and face-to-face discussions at summit about this problem.  It
is not the biggest problem in Neutron but has been around a while and annoys a
number of people.&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id12" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id11"&gt;6&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://eavesdrop.openstack.org/irclogs/%23openstack-neutron/%23openstack-neutron.2014-02-21.log"&gt;http://eavesdrop.openstack.org/irclogs/%23openstack-neutron/%23openstack-neutron.2014-02-21.log&lt;/a&gt; (2014-02-21T00:19:20)&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative is to use the existing port &lt;em&gt;name&lt;/em&gt; field in the API to allow
Nova to pass the name to Neutron instead of adding a new field.  The reasons
for not doing this are:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;That field may be used by Neutron API consumers for other purposes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The field was not intended to carry a PQDN or FQDN and therefore does not
validate values as such.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~minsel"&gt;miguel-lavalle&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://launchpad.net/~zack-feldstein"&gt;zack-feldstein&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Database upgrade script.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API extension with validator.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change API to return dns_name or default generated name and dns_fqdn on GET.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Moves default hostname generation to API server.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Change to RPC to include dns names in the port section of network data
requested by DHCP agent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change to DHCP agent to write dns names to hosts file when updating dnsmasq.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;In order for this to work end to end, we need coordinated change in Nova.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/nova/+spec/internal-dns-resolution"&gt;https://blueprints.launchpad.net/nova/+spec/internal-dns-resolution&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;section id="tempest-tests"&gt;
&lt;h3&gt;Tempest Tests&lt;/h3&gt;
&lt;p&gt;Tempest tests should be added or modified for the following use cases&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;No name is specified in port create. DNS lookup should work using old method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A port create that duplicates a name on a network should fail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An instance created using the nova API can be looked up using the instance
name.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I believe that the validation of input can be tested using unit tests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="functional-tests"&gt;
&lt;h3&gt;Functional Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api-tests"&gt;
&lt;h3&gt;API Tests&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;section id="user-documentation"&gt;
&lt;h3&gt;User Documentation&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-documentation"&gt;
&lt;h3&gt;Developer Documentation&lt;/h3&gt;
&lt;p&gt;&lt;a class="reference internal" href="#rest-api-impact"&gt;REST api impact&lt;/a&gt; should be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/nova/+bug/1175211"&gt;https://bugs.launchpad.net/nova/+bug/1175211&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 03 Apr 2014 00:00:00 </pubDate></item><item><title>Neutron Plugin for Opencontrail</title><link>https://specs.openstack.org/openstack/neutron-specs/specs/juno/opencontrail-plugin.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/juniper-plugin-with-extensions"&gt;https://blueprints.launchpad.net/neutron/+spec/juniper-plugin-with-extensions&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint is for the Opencontrail-neutron-plugin to add support in Neutron
for Opencontrail based network virtualization. The list of core resources and
extensions supported are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subnet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security Group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L3 Extensions&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We will also support Extraroute extension&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Opencontrail is open source network virtualization solution. It uses standards
based BGP L3VPN closed user groups to implement virtual networks.
The link &lt;a class="reference external" href="http://opencontrail.org/opencontrail-architecture-documentation/"&gt;http://opencontrail.org/opencontrail-architecture-documentation/&lt;/a&gt;
explains the architecture of Opencontrail plugin&lt;/p&gt;
&lt;p&gt;The Neutron plugin code would interact with Opencontrail Rest-API to provide
the network virtualization functionality.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The Opencontrail Neutron plugin will implement the Neutron core and extension
APIs. It will receive the API request and pass it to the Opencontrail controller
for processing.
There are no changes to the Neutron common code. New files are addded to
implement the opencontrail-plugin.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Current support is for traditional Neutron plugin interface.
We will consider using ML2 interface in future.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.
There are no new API added to neutron. For above listed API all features
will be supported by the plugin.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;The communication channel to the backend is not secure.
We will support secure channel in the future.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Users will now be able to configure Opencontrail as one of the available plugin
from upstream.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Users will now be able to configure Opencontrail as one of the available plugin
from upstream. Following link explains setup of Opencontrail using devstack.
&lt;a class="reference external" href="http://pedrormarques.wordpress.com/2013/11/14/using-devstack-plus-opencontrail/"&gt;http://pedrormarques.wordpress.com/2013/11/14/using-devstack-plus-opencontrail/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.
Other Developers wont be effected by this change. Tempest thirdparty environment
will be provided.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Opencontrail plugin does not use the Neutron persistence layer and so avoid
the problems when the database goes out of sync. Opencontrail plugin uses
additional objects and attributes for objects that are defined by Neutron
APIs, that data is stored in the Opencontrail controller which does the
persistency. By being stateless, the Neutron service doesn’t have to deal
with its persistency layer getting out of sync with the implementation’s
persistence layer.&lt;/p&gt;
&lt;p&gt;A New Plugin ‘opencontrail’ has been created. A new file
‘contrail_plugin.py’ has been added to implement the core extension
RESTApi.&lt;/p&gt;
&lt;p&gt;The configuration file contrailplugin.ini will be added to configure the
Opencontrail plugin. The file will contain the following parameters.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;1 api_server_ip&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;The Opencontrail controller IP address&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;2 api_server_port&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;The Opencontrail controller IP port&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;3 multi-tenancy&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Multi-tenancy support&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;4 max_retries&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;The maximum number of tries to connect to the Opencontrail controller&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;5 retry_interval&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Retry interval to connect to the Opencontrail controller&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Example:
[API_SERVER]
api_server_ip = 10.10.10.10
api_server_port = 8082
multi_tenancy = False&lt;/p&gt;
&lt;p&gt;The Class ‘NeutronPluginContrailCoreV2’ is added to implement the core RESTApi.
It will implement the following extensions and their RESTApis&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Network&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create_network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update_network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete_network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_networks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_networks_count&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Subnet&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create_subnet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update_subnet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete_subnet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_subnet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_subnets&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_subnets_count&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Port&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create_port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update_port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete_port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_port&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_ports&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_ports_count&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Router&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create_router&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update_router&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete_router&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_router&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_routers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_routers_count&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Floatingip&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create_floatingip&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update_floatingip&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete_floatingip&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_floatingip&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_floatingips&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_floatingips_count&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;SecurityGroup&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create_security_group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update_security_group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete_security_group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_security_group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_security_groups&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_security_groups_count&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;praneetb&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;hajay&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Opencontrail plugin implementation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Opencontrail mocks for unit-tests&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Existing and new (added in Juno) Neutron unit tests will be used.
Existing and new tempest testing for neutron will be used.
Tempest CI environment will be provided.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Once the opencontrail neutron plugin is accepted, neutron documentation can
change to say opencontrail plugin as one of the supported plugin.&lt;/p&gt;
&lt;p&gt;The link below explains setup of Opencontrail using devstack.
&lt;a class="reference external" href="http://pedrormarques.wordpress.com/2013/11/14/using-devstack-plus-opencontrail/"&gt;http://pedrormarques.wordpress.com/2013/11/14/using-devstack-plus-opencontrail/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.opencontrail.org"&gt;http://www.opencontrail.org&lt;/a&gt;
&lt;a class="reference external" href="https://github.com/Juniper/contrail-controller"&gt;https://github.com/Juniper/contrail-controller&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 27 Mar 2014 00:00:00 </pubDate></item></channel></rss>