Darrell,

To aviod lengthy  response, i'll address the issues directly.


The code in ovs-vtep should not be Neutron L2 border gateway specific.
Please remove references to so-called relay and mesh ports.

The relay vteps are a second level of hierachy of vteps - I have more
detail

 --agreed

Do not link per tunnel tunnel keys to Neutron L2 border gateway relay vteps
in generic code, such as ovs-vtep.


--agreed.


Regarding vtep.ovsschema:


diff --git a/vtep/vtep.ovsschema b/vtep/vtep.ovsschema
index 3a24318..f41568f 100644
--- a/vtep/vtep.ovsschema
+++ b/vtep/vtep.ovsschema
@@ -1,6 +1,6 @@
 {
   "name": "hardware_vtep",
-  "cksum": "353943336 11434",
+  "cksum": "3167636278 11608",
   "tables": {
     "Global": {
       "columns": {
@@ -209,7 +209,12 @@
               "type": "string"}},
           "mutable": false},
         "dst_ip": {"type": "string", "mutable": false},
-        "tunnel_key": {"type": {"key": "integer", "min": 0, "max": 1}}},
+        "tunnel_key": {"type": {"key": "integer", "min": 0, "max": 1}},
+        "tunnel_level": {
+          "type": {
+            "key": {
+              "enum": ["set", ["level0", "level1"]],
+              "type": "string"},"min": 0, "max": 1}}},
       "indexes": [["encapsulation_type", "dst_ip", "tunnel_key"]]},
     "ACL_entry": {
       "columns": {


I have no issues with this: just  two notes the tunne_level should default to 
"level0"

and vtep-ctl should be changed accordingly.

-- I can suggest a patch for it.


In order to make sure the handling in ovs-vtep satisfies the l2gw I'd prefers 
having your suggested patch

and run tests with it applied.


Regards


Itamar

________________________________
From: dev <dev-boun...@openvswitch.org> on behalf of Darrell Ball 
<dlu...@gmail.com>
Sent: Saturday, August 13, 2016 4:05:07 AM
To: itamaro
Cc: ovs dev
Subject: Re: [ovs-dev] [PATCH V3] ovs-vtep: vtep-ctl and ovs-vtep support of 
adding explicit tunnel key

I tried simulating your use case since there is no real test case
at the moment and found a missed check in my suggested incremental
patch.

I added the additional 2 lines
+            if (tunnel_scope_key):
+                tunnel_key = tunnel_scope_key

in the following context
+        old_tunnel_ips = set(self.tunnels.keys())
+        tunnel_ips = set(tunnels.keys())
+        for tunnel_ip in tunnel_ips.difference(old_tunnel_ips):
+            tunnel_scope_key = tunnels[tunnel_ip]
+            if (tunnel_scope_key):
+                tunnel_key = tunnel_scope_key
+            self.add_tunnel(tunnel_ip, tunnel_key, tunnel_scope_key)





On Thu, Aug 11, 2016 at 2:12 PM, Darrell Ball <dlu...@gmail.com> wrote:

> I have various comments; I focused on the big picture mainly and
> did not review most details except ovs-vtep and one or two selected
> spots elsewhere, pending agreement on the big picture.
>
> Some comments are the same as I made in the first patch.
>
> Your patch did not apply cleanly due to previous change in
> vtep-ctl.c includes, I fixed it locally - please check.
>
>
> On Sun, Jul 24, 2016 at 5:01 AM, itamaro <itamar.o...@gmail.com> wrote:
>
>> From: itamaro <itamar.o...@gmail.com>
>>
>> This patch adds support for handeling a per-tunnel tunnel key in the
>> ovs-vtep and vtep-ctl to support the usage of neutron L2GW as an
>> inter-cloud gateway.
>>
>> The Neutron spec is available here:
>> https://review.openstack.org/#/c/270786/
>>
>> The aim of this patch is to support the usage of hardware vtep switch as
>> an inter-cloud gateway, which is used to connect two separated l2
>> broadcast
>> domains. This document will also explain the logic behind the addition of
>> the
>> new per-tunnel tunnel-key in the hardware_vtep schema.
>>
>> The introduction of the relay tunnel, does not change the current logic of
>> hardware_vtep, it does however introduce new logic related to iner-cloud
>> connectivity.
>>
>>
>> Network layout
>> ==============
>>
>>     virtual network 1                 shared  network         virtual
>> network 2
>>     +------------+
>> +------------+
>>     |Compute Host|   VNI=1                                    VNI=2
>> |Compute Host|
>>     |   +--+     <---------+                                +------->
>>  +--+     |
>>     |   |vm|     |         |                                |       |
>>  |vm|     |
>>     |   +--+     |         |           L3 network           |       |
>>  +--+     |
>>     +---^--------+         |                                |
>>  +---------^--+
>>         |          +-------v--------+      X     +----------v-----+
>>      |
>>         |      +---> hardware_vtep  |      X     | hardware_vtep  |
>>      |
>>         | VNI=1|   | logical switch |      X     | logical switch
>> <-----+     |
>>         |      |   | (tunnel_key 1) |==<<==X=>>==| (tunnel_key 2) |
>>  |VNI=2|
>>         |      |   |   +-+     +-+  |      X     |   +-+      +-+ |
>>  |     |
>>         |      |   |   |-|     |-|  |      X     |   |-|      |-| |
>>  |     |
>>     +---v------v-+ +----------------+      X     +----------------+
>>  |     |
>>     |Compute Host| vlan2|       |vlan5           vlan9|        |vlan21
>> |     |
>>     |   +--+     |      |       |    relay vxlan      |        |
>> +---v-----v--+
>>     |   |vm|     |      |       |      VNI=100        |        |
>> |Compute Host|
>>     |   +--+     |      |       |                     |        |    |
>>  +--+     |
>>     +------------+    +-v-+   +-v-+                 +-v-+    +-v-+  |
>>  |vm|     |
>>                       |   |   |   |                 |   |    |   |  |
>>  +--+     |
>>                       |   |   |   |                 |   |    |   |
>> +------------+
>>                       +---+   +---+                 +---+    +---+
>>                     Bare metal elements             Bare metal elements
>>
>> Logical switch
>> ===============
>> In a cloud architecture, there is sometimes need to connect virtual
>> machines
>> and physical machines to the same L2 broadcast domain.
>> A logical switch is an entity representing an l2 virtual overlay network,
>> identified by a shared tunnel key. This tunnel key (VxLAN VNI) is shared
>> among
>> all overlay virtual tunnel endpoints (VTEP) of the switch.
>> The logical switch binds physical ports with either identical or different
>> "VLAN" tags to the "VxLAN overlay" network.
>>
>> In a multi-cloud architecture, it may be useful to establish a cross-cloud
>> l2 broadcast domain. The extended hardware vtep uses a relay l2 tunnel,
>> which is a tunnel with an explicit tunnel-key property. The tunnel-key
>> propery
>> is used to map each overlay network (logical switch tunnel-key) in each
>> cloud to
>> the tunnel-key of the relay tunnel.
>>
>> The mapping to a remote logical switch is done by defining the same
>> tunnel key
>> in both ends of the the relay tunnel. This tunnel key (VxLAN VNI) is a
>> property of the relay tunnel itself.
>>
>> To support the above tunnel behevior, a new kind of VTEP port is logic is
>> introduced, defining two VTEP port groups. One group represents the
>> existing
>> VTEP ports of the local l2 overlay network, and another new group
>> represents the
>> individual l2 relay VTEPS.
>>
>> Multicast and Unknown unicast traffic
>> =====================================
>> Currently Broadcast, Unknown unicast, and Multicast,"BUM" traffic to the
>> overlay networks
>> is handled by two replication modes:
>>
>>   - "source_node" mode: The packets originated from physical port
>>     are replicated on all the VTEPs ports pointed by unknown-dst, and
>> flooded
>>     to all the physical bound ports.
>>
>>   - "service_node" mode: The packets originated from physical port are
>>     forwarded to only a selected single service node from the unknown-dst
>> ports
>>     (the service node responsible for "BUM" propagation to the overlay
>> network),
>>     and flooded to all the physical bound ports.
>>
>> In either of the replication modes BUM traffic originated from a VTEP
>> port is
>> flooded only to all physical ports.
>>
>
> A refresh of what is source_node and service_node replication does not
> belong here
> and adds to the already lengthy commit message.
>
>
>
>>
>> Considering the new l2-relay VTEPs ports group, relay related BUM traffic
>> is
>> handled as follows:
>>   - BUM packets from Physical Port and from local overlay network are
>> replicated
>>     to the unknown-dst l2-relay ports.
>>        The reason is that a relay VTEP is not a part of the local managed
>>        network and BUM traffic to the relay VTEPs cannot be suppressed by
>> a
>>        local service node.
>>   - BUM packets from relay VTEPs are handled according to the replicating
>> mode
>>     and not forwarded/replicated to the l2-relay ports.
>>        It is assumed that relay tunnels do not interconnect remote
>> networks.
>
>
>> To sum it up, the role of the l2-relay is merely to connect two distinct
>> broadcast domains, it will otherwise never be used as a switching fabric
>> among
>> the different remote l2 networks.
>>
>
> This statement looks misleading. The so called l2 relay ports support BUM
> traffic and
> hence its part of L2 switching logic in that sense.
>
>
>
>
>>
>> ovs-vtep manifested changes
>> ===========================
>>
>> 1. The code need to distinguish between overlay (mesh) VTEPs, and relay
>> VTEPs.
>> 2. BUM traffic
>>     * BUM traffic from either mesh or bare metal network is replicated on
>> all
>>       relay 'unknown-dst' VTEP.
>>     * BUM traffic from relay VTEP, is handled according to the
>> replicating mode
>>       and is not forwarded/replicated to the l2-relay ports.
>>
>
> The code in ovs-vtep should not be Neutron L2 border gateway specific.
> Please remove references to so-called relay and mesh ports.
>
> The relay vteps are a second level of hierachy of vteps - I have more
> detailed
> comments in the code.
>
> Do not link per tunnel tunnel keys to Neutron L2 border gateway relay vteps
> in generic code, such as ovs-vtep.
>
>
>>
>>
>> Requested-by: "Ofer Ben-Yacov" <ofer.benya...@gmail.com>
>> Signed-off-by: "Itamar Ofek" <itamar.o...@gmail.com>
>> ---
>>  tests/vtep-ctl.at | 145 ++++++++++++++++++++++++++++++
>> +++++++++++++++++-------
>>  vtep/ovs-vtep     | 102 +++++++++++++++++++++++++-------------
>>  vtep/vtep-ctl.c   | 138 ++++++++++++++++++++++++++++++
>> ++++-----------------
>>  3 files changed, 286 insertions(+), 99 deletions(-)
>>
>> diff --git a/tests/vtep-ctl.at b/tests/vtep-ctl.at
>> index f0511ad..4178309 100644
>> --- a/tests/vtep-ctl.at
>> +++ b/tests/vtep-ctl.at
>> @@ -433,12 +433,16 @@ AT_CHECK([RUN_VTEP_CTL(
>>  CHECK_LSWITCHES([ls1])
>>  AT_CHECK([RUN_VTEP_CTL(
>>     [add-ucast-local ls1 00:11:22:33:44:55 10.0.0.10],
>> -   [add-ucast-local ls1 00:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11])
>> +   [add-ucast-local ls1 00:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11],
>> +   [add-ucast-local ls1 00:11:22:33:55:66 10.0.0.12 100],
>> +   [add-ucast-local ls1 00:11:22:33:55:77 vxlan_over_ipv4 10.0.0.13 200])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>>     [ucast-mac-local
>>    00:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    00:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  00:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.12 [[100]]
>> +  00:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.13 [[200]]
>>
>>  mcast-mac-local
>>
>> @@ -460,11 +464,20 @@ AT_CHECK([RUN_VTEP_CTL(
>>  CHECK_LSWITCHES([ls1])
>>  AT_CHECK([RUN_VTEP_CTL(
>>     [add-ucast-local ls1 00:11:22:33:44:55 10.0.0.10],
>> -   [add-ucast-local ls1 00:11:22:33:44:55 10.0.0.11])
>> +   [add-ucast-local ls1 00:11:22:33:44:55 10.0.0.11],
>> +   [add-ucast-local ls1 00:11:22:33:55:66 10.0.0.12 100],
>> +   [add-ucast-local ls1 00:11:22:33:55:66 10.0.0.13 200],
>> +   [add-ucast-local ls1 00:11:22:33:55:77 10.0.0.14 300],
>> +   [add-ucast-local ls1 00:11:22:33:55:77 10.0.0.15],
>> +   [add-ucast-local ls1 00:11:22:33:55:88 10.0.0.16],
>> +   [add-ucast-local ls1 00:11:22:33:55:88 10.0.0.17 400])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>>     [ucast-mac-local
>>    00:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.11
>> +  00:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.13 [[200]]
>> +  00:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.15
>> +  00:11:22:33:55:88 -> vxlan_over_ipv4/10.0.0.17 [[400]]
>>
>>  mcast-mac-local
>>
>> @@ -480,22 +493,28 @@ AT_CHECK([RUN_VTEP_CTL(
>>  CHECK_LSWITCHES([ls1])
>>  AT_CHECK([RUN_VTEP_CTL(
>>     [add-ucast-local ls1 00:11:22:33:44:55 10.0.0.10],
>> -   [add-ucast-local ls1 00:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11])
>> +   [add-ucast-local ls1 00:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11],
>> +   [add-ucast-local ls1 00:11:22:33:55:66 10.0.0.12 100],
>> +   [add-ucast-local ls1 00:11:22:33:55:77 vxlan_over_ipv4 10.0.0.13 200])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>>     [ucast-mac-local
>>    00:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    00:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  00:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.12 [[100]]
>> +  00:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.13 [[200]]
>>
>>  mcast-mac-local
>>
>>  ], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL(
>> -   [del-ucast-local ls1 00:11:22:33:44:55])
>> +   [del-ucast-local ls1 00:11:22:33:44:55],
>> +   [del-ucast-local ls1 00:11:22:33:55:66])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>>     [ucast-mac-local
>>    00:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  00:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.13 [[200]]
>>
>>  mcast-mac-local
>>
>> @@ -511,12 +530,16 @@ AT_CHECK([RUN_VTEP_CTL(
>>  CHECK_LSWITCHES([ls1])
>>  AT_CHECK([RUN_VTEP_CTL(
>>     [add-ucast-remote ls1 00:11:22:33:44:55 10.0.0.10],
>> -   [add-ucast-remote ls1 00:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11])
>> +   [add-ucast-remote ls1 00:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11],
>> +   [add-ucast-remote ls1 00:11:22:33:55:66 10.0.0.12 100],
>> +   [add-ucast-remote ls1 00:11:22:33:55:77 10.0.0.13 200])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
>>     [ucast-mac-remote
>>    00:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    00:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  00:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.12 [[100]]
>> +  00:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.13 [[200]]
>>
>>  mcast-mac-remote
>>
>> @@ -538,11 +561,14 @@ AT_CHECK([RUN_VTEP_CTL(
>>  CHECK_LSWITCHES([ls1])
>>  AT_CHECK([RUN_VTEP_CTL(
>>     [add-ucast-remote ls1 00:11:22:33:44:55 10.0.0.10],
>> -   [add-ucast-remote ls1 00:11:22:33:44:55 10.0.0.11])
>> +   [add-ucast-remote ls1 00:11:22:33:44:55 10.0.0.11],
>> +   [add-ucast-remote ls1 00:11:22:33:55:66 10.0.0.12 100],
>> +   [add-ucast-remote ls1 00:11:22:33:55:66 10.0.0.13 200])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
>>     [ucast-mac-remote
>>    00:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.11
>> +  00:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.13 [[200]]
>>
>>  mcast-mac-remote
>>
>> @@ -558,22 +584,28 @@ AT_CHECK([RUN_VTEP_CTL(
>>  CHECK_LSWITCHES([ls1])
>>  AT_CHECK([RUN_VTEP_CTL(
>>     [add-ucast-remote ls1 00:11:22:33:44:55 10.0.0.10],
>> -   [add-ucast-remote ls1 00:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11])
>> +   [add-ucast-remote ls1 00:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11],
>> +   [add-ucast-remote ls1 00:11:22:33:55:66 10.0.0.12 100],
>> +   [add-ucast-remote ls1 00:11:22:33:55:77 vxlan_over_ipv4 10.0.0.13
>> 200])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
>>     [ucast-mac-remote
>>    00:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    00:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  00:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.12 [[100]]
>> +  00:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.13 [[200]]
>>
>>  mcast-mac-remote
>>
>>  ], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL(
>> -   [del-ucast-remote ls1 00:11:22:33:44:55])
>> +   [del-ucast-remote ls1 00:11:22:33:44:55],
>> +   [del-ucast-remote ls1 00:11:22:33:55:66])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
>>     [ucast-mac-remote
>>    00:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  00:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.13 [[200]]
>>
>>  mcast-mac-remote
>>
>> @@ -590,13 +622,19 @@ CHECK_LSWITCHES([ls1])
>>  AT_CHECK([RUN_VTEP_CTL(
>>     [add-ucast-local ls1 00:11:22:33:44:55 10.0.0.10],
>>     [add-ucast-local ls1 00:11:22:33:44:66 10.0.0.11],
>> +   [add-ucast-local ls1 00:11:22:33:55:66 10.0.0.12 100],
>> +   [add-ucast-local ls1 00:11:22:33:55:77 vxlan_over_ipv4 10.0.0.13 200],
>>     [add-ucast-remote ls1 02:11:22:33:44:55 10.0.0.10],
>> -   [add-ucast-remote ls1 02:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11])
>> +   [add-ucast-remote ls1 02:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11],
>> +   [add-ucast-remote ls1 02:11:22:33:55:66 10.0.0.12 100],
>> +   [add-ucast-remote ls1 02:11:22:33:55:77 vxlan_over_ipv4 10.0.0.13
>> 200])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>>     [ucast-mac-local
>>    00:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    00:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  00:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.12 [[100]]
>> +  00:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.13 [[200]]
>>
>>  mcast-mac-local
>>
>> @@ -605,6 +643,8 @@ AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
>>     [ucast-mac-remote
>>    02:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    02:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  02:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.12 [[100]]
>> +  02:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.13 [[200]]
>>
>>  mcast-mac-remote
>>
>> @@ -621,7 +661,9 @@ CHECK_LSWITCHES([ls1])
>>  AT_CHECK([RUN_VTEP_CTL(
>>     [add-mcast-local ls1 01:11:22:33:44:55 10.0.0.10],
>>     [add-mcast-local ls1 01:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11],
>> -   [add-mcast-local ls1 01:11:22:33:44:55 10.0.0.12])
>> +   [add-mcast-local ls1 01:11:22:33:44:55 10.0.0.12],
>> +   [add-mcast-local ls1 01:11:22:33:55:66 10.0.0.13 100],
>> +   [add-mcast-local ls1 01:11:22:33:55:77 vxlan_over_ipv4 10.0.0.14 200])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>>     [ucast-mac-local
>> @@ -630,6 +672,8 @@ mcast-mac-local
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.12
>>    01:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  01:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.13 [[100]]
>> +  01:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.14 [[200]]
>>
>>  ], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
>> @@ -651,7 +695,9 @@ AT_CHECK([RUN_VTEP_CTL(
>>     [add-mcast-local ls1 01:11:22:33:44:55 10.0.0.10],
>>     [add-mcast-local ls1 01:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11],
>>     [add-mcast-local ls1 01:11:22:33:44:55 10.0.0.12],
>> -   [add-mcast-local ls1 01:11:22:33:44:55 10.0.0.13])
>> +   [add-mcast-local ls1 01:11:22:33:44:55 10.0.0.13],
>> +   [add-mcast-local ls1 01:11:22:33:55:66 10.0.0.14 100],
>> +   [add-mcast-local ls1 01:11:22:33:55:77 vxlan_over_ipv4 10.0.0.15 200])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>>     [ucast-mac-local
>> @@ -661,10 +707,13 @@ mcast-mac-local
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.12
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.13
>>    01:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  01:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.14 [[100]]
>> +  01:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.15 [[200]]
>>
>>  ], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL(
>> -   [del-mcast-local ls1 01:11:22:33:44:55 10.0.0.12])
>> +   [del-mcast-local ls1 01:11:22:33:44:55 10.0.0.12],
>> +   [del-mcast-local ls1 01:11:22:33:55:66 10.0.0.14])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>>     [ucast-mac-local
>> @@ -673,6 +722,7 @@ mcast-mac-local
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.13
>>    01:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  01:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.15 [[200]]
>>
>>  ], [], [VTEP_CTL_CLEANUP])
>>  VTEP_CTL_CLEANUP
>> @@ -687,7 +737,10 @@ CHECK_LSWITCHES([ls1])
>>  AT_CHECK([RUN_VTEP_CTL(
>>     [add-mcast-remote ls1 01:11:22:33:44:55 10.0.0.10],
>>     [add-mcast-remote ls1 01:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11],
>> -   [add-mcast-remote ls1 01:11:22:33:44:55 10.0.0.12])
>> +   [add-mcast-remote ls1 01:11:22:33:44:55 10.0.0.12],
>> +   [add-mcast-remote ls1 01:11:22:33:55:66 10.0.0.13 100],
>> +   [add-mcast-remote ls1 01:11:22:33:55:77 vxlan_over_ipv4 10.0.0.14
>> 300],
>> +   [add-mcast-remote ls1 01:11:22:33:55:66 10.0.0.15 200])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
>>     [ucast-mac-remote
>> @@ -696,6 +749,9 @@ mcast-mac-remote
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.12
>>    01:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  01:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.13 [[100]]
>> +  01:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.15 [[200]]
>> +  01:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.14 [[300]]
>>
>>  ], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>> @@ -717,7 +773,10 @@ AT_CHECK([RUN_VTEP_CTL(
>>     [add-mcast-remote ls1 01:11:22:33:44:55 10.0.0.10],
>>     [add-mcast-remote ls1 01:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11],
>>     [add-mcast-remote ls1 01:11:22:33:44:55 10.0.0.12],
>> -   [add-mcast-remote ls1 01:11:22:33:44:55 10.0.0.13])
>> +   [add-mcast-remote ls1 01:11:22:33:44:55 10.0.0.13],
>> +   [add-mcast-remote ls1 01:11:22:33:55:66 10.0.0.14 100],
>> +   [add-mcast-remote ls1 01:11:22:33:55:77 vxlan_over_ipv4 10.0.0.15
>> 300],
>> +   [add-mcast-remote ls1 01:11:22:33:55:66 10.0.0.16 200])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
>>     [ucast-mac-remote
>> @@ -727,10 +786,14 @@ mcast-mac-remote
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.12
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.13
>>    01:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  01:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.14 [[100]]
>> +  01:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.16 [[200]]
>> +  01:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.15 [[300]]
>>
>>  ], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL(
>> -   [del-mcast-remote ls1 01:11:22:33:44:55 10.0.0.12])
>> +   [del-mcast-remote ls1 01:11:22:33:44:55 10.0.0.12],
>> +   [del-mcast-remote ls1 01:11:22:33:55:66 10.0.0.14])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
>>     [ucast-mac-remote
>> @@ -739,6 +802,8 @@ mcast-mac-remote
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.13
>>    01:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  01:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.16 [[200]]
>> +  01:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.15 [[300]]
>>
>>  ], [], [VTEP_CTL_CLEANUP])
>>  VTEP_CTL_CLEANUP
>> @@ -756,7 +821,13 @@ AT_CHECK([RUN_VTEP_CTL(
>>     [add-mcast-local ls1 01:11:22:33:44:55 10.0.0.12],
>>     [add-mcast-remote ls1 03:11:22:33:44:55 10.0.0.10],
>>     [add-mcast-remote ls1 03:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11],
>> -   [add-mcast-remote ls1 03:11:22:33:44:55 10.0.0.12])
>> +   [add-mcast-remote ls1 03:11:22:33:44:55 10.0.0.12],
>> +   [add-mcast-local ls1 01:11:22:33:55:66 10.0.0.14 100],
>> +   [add-mcast-local ls1 01:11:22:33:55:77 vxlan_over_ipv4 10.0.0.15 300],
>> +   [add-mcast-local ls1 01:11:22:33:55:66 10.0.0.16 200],
>> +   [add-mcast-remote ls1 03:11:22:33:55:66 10.0.0.14 100],
>> +   [add-mcast-remote ls1 03:11:22:33:55:77 vxlan_over_ipv4 10.0.0.15
>> 300],
>> +   [add-mcast-remote ls1 03:11:22:33:55:66 10.0.0.16 200])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>>     [ucast-mac-local
>> @@ -765,6 +836,9 @@ mcast-mac-local
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.12
>>    01:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  01:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.14 [[100]]
>> +  01:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.16 [[200]]
>> +  01:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.15 [[300]]
>>
>>  ], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
>> @@ -774,7 +848,10 @@ mcast-mac-remote
>>    03:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    03:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.12
>>    03:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> -
>> +  03:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.14 [[100]]
>> +  03:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.16 [[200]]
>> +  03:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.15 [[300]]
>> +
>>  ], [], [VTEP_CTL_CLEANUP])
>>  VTEP_CTL_CLEANUP
>>  AT_CLEANUP
>> @@ -793,7 +870,13 @@ AT_CHECK([RUN_VTEP_CTL(
>>     [add-ucast-remote ls1 00:11:22:33:44:55 10.0.0.10],
>>     [add-mcast-remote ls1 01:11:22:33:44:55 10.0.0.10],
>>     [add-mcast-remote ls1 01:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11],
>> -   [add-mcast-remote ls1 01:11:22:33:44:55 10.0.0.12])
>> +   [add-mcast-remote ls1 01:11:22:33:44:55 10.0.0.12],
>> +   [add-mcast-local ls1 01:11:22:33:55:66 10.0.0.14 100],
>> +   [add-mcast-local ls1 01:11:22:33:55:77 vxlan_over_ipv4 10.0.0.15 300],
>> +   [add-mcast-local ls1 01:11:22:33:55:66 10.0.0.16 200],
>> +   [add-mcast-remote ls1 03:11:22:33:55:66 10.0.0.14 100],
>> +   [add-mcast-remote ls1 03:11:22:33:55:77 vxlan_over_ipv4 10.0.0.15
>> 300],
>> +   [add-mcast-remote ls1 03:11:22:33:55:66 10.0.0.16 200])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>>     [ucast-mac-local
>> @@ -803,6 +886,9 @@ mcast-mac-local
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.12
>>    01:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  01:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.14 [[100]]
>> +  01:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.16 [[200]]
>> +  01:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.15 [[300]]
>>
>>  ], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
>> @@ -813,6 +899,9 @@ mcast-mac-remote
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.12
>>    01:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  03:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.14 [[100]]
>> +  03:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.16 [[200]]
>> +  03:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.15 [[300]]
>>
>>  ], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL(
>> @@ -831,6 +920,9 @@ mcast-mac-remote
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.12
>>    01:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  03:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.14 [[100]]
>> +  03:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.16 [[200]]
>> +  03:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.15 [[300]]
>>
>>  ], [], [VTEP_CTL_CLEANUP])
>>  VTEP_CTL_CLEANUP
>> @@ -850,7 +942,13 @@ AT_CHECK([RUN_VTEP_CTL(
>>     [add-ucast-remote ls1 00:11:22:33:44:55 10.0.0.10],
>>     [add-mcast-remote ls1 01:11:22:33:44:55 10.0.0.10],
>>     [add-mcast-remote ls1 01:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11],
>> -   [add-mcast-remote ls1 01:11:22:33:44:55 10.0.0.12])
>> +   [add-mcast-remote ls1 01:11:22:33:44:55 10.0.0.12],
>> +   [add-mcast-local ls1 01:11:22:33:55:66 10.0.0.14 100],
>> +   [add-mcast-local ls1 01:11:22:33:55:77 vxlan_over_ipv4 10.0.0.15 300],
>> +   [add-mcast-local ls1 01:11:22:33:55:66 10.0.0.16 200],
>> +   [add-mcast-remote ls1 03:11:22:33:55:66 10.0.0.14 100],
>> +   [add-mcast-remote ls1 03:11:22:33:55:77 vxlan_over_ipv4 10.0.0.15
>> 300],
>> +   [add-mcast-remote ls1 03:11:22:33:55:66 10.0.0.16 200])
>>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>>     [ucast-mac-local
>> @@ -860,6 +958,9 @@ mcast-mac-local
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.12
>>    01:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  01:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.14 [[100]]
>> +  01:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.16 [[200]]
>> +  01:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.15 [[300]]
>>
>>  ], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
>> @@ -870,6 +971,9 @@ mcast-mac-remote
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.12
>>    01:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  03:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.14 [[100]]
>> +  03:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.16 [[200]]
>> +  03:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.15 [[300]]
>>
>>  ], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL(
>> @@ -882,6 +986,9 @@ mcast-mac-local
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
>>    01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.12
>>    01:11:22:33:44:66 -> vxlan_over_ipv4/10.0.0.11
>> +  01:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.14 [[100]]
>> +  01:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.16 [[200]]
>> +  01:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.15 [[300]]
>>
>>  ], [], [VTEP_CTL_CLEANUP])
>>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
>> diff --git a/vtep/ovs-vtep b/vtep/ovs-vtep
>> index b32a82a..360f9fd 100755
>> --- a/vtep/ovs-vtep
>> +++ b/vtep/ovs-vtep
>> @@ -120,30 +120,52 @@ class Logical_Switch(object):
>>          for port_no, tun_name, remote_ip in six.itervalues(self.tunnels):
>>              del_bfd(remote_ip)
>>
>> -    def update_flood(self):
>> -        flood_ports = list(self.ports.values())
>> +    def vtep_ports(self, tunnel_list):
>
> +        relay_ports, mesh_ports = list(), list()
>> +        for tunnel in tunnel_list:
>> +            if self.tunnels[tunnel][3]:
>> +                relay_ports.append(self.tunnels[tunnel][0])
>> +                continue
>> +            mesh_ports.append(self.tunnels[tunnel][0])
>> +        return relay_ports, mesh_ports
>>
>
> Please remove references to Neutron L2 border gateway
> relay and mesh and treat the relay ports as a second level of vtep
> hierarchy.
>
> Per tunnel tunnel key should not linked to "relay vteps" or Neutron L2
> border
> gateway design.
>
>
>
>>
>> -        # Traffic flowing from one 'unknown-dst' should not be flooded to
>> -        # port belonging to another 'unknown-dst'.
>> -        for tunnel in self.unknown_dsts:
>> -            port_no = self.tunnels[tunnel][0]
>> -            ovs_ofctl("add-flow %s table=1,priority=1,in_port=%s,
>> action=%s"
>> -                      % (self.short_name, port_no,
>> ",".join(flood_ports)))
>> +    def update_flood(self):
>> +        phy_ports = list(self.ports.values())
>> +        relay_ports, mesh_ports = self.vtep_ports(self.tunnels.keys())
>> +        relay_unknown, mesh_unknown = self.vtep_ports(self.unknown_dsts)
>>
>>          # Traffic coming from a VTEP physical port should always be
>> flooded to
>>          # all the other physical ports that belong to that VTEP device
>> and
>> -        # this logical switch.  If the replication mode is service node
>> then
>> +        # this logical switch and all relay VTEP ports.
>> +        # If the replication mode is service node then
>>          # send to one unknown_dst node (the first one here); else we
>> assume the
>>          # replication mode is source node and we send the packet to all
>>          # unknown_dst nodes.
>> -        for tunnel in self.unknown_dsts:
>> -            port_no = self.tunnels[tunnel][0]
>> -            flood_ports.append(port_no)
>> +
>> +        phy_flood_ports = phy_ports + relay_unknown
>> +        if len(mesh_unknown) > 0:
>>              if self.replication_mode == "service_node":
>> -                break
>> +                phy_flood_ports += mesh_unknown[0]
>> +            else:
>> +                phy_flood_ports += mesh_unknown
>> +        for port_no in phy_ports:
>> +            ovs_ofctl("add-flow %s table=1,priority=1,in_port=%s,
>> action=%s"
>> +                      % (self.short_name, port_no,
>> ",".join(phy_flood_ports)))
>> +
>> +        # Traffic flowing from a mesh VTEP should not be flooded to mesh
>> +        # unknown-dst ports
>> +        mesh_flood_ports = phy_ports + relay_unknown
>> +        for port_no in mesh_ports:
>> +            ovs_ofctl("add-flow %s table=1,priority=1,in_port=%s,
>> action=%s"
>> +                      % (self.short_name, port_no,
>> ",".join(mesh_flood_ports)))
>>
>> -        ovs_ofctl("add-flow %s table=1,priority=0,action=%s"
>> -                  % (self.short_name, ",".join(flood_ports)))
>> +        # Traffic flowing from a relay VTEP should not be flooded to
>> relay
>> +        # unknown-dst ports
>> +        relay_flood_ports = phy_ports + mesh_unknown
>> +        for port_no in relay_ports:
>> +            ovs_ofctl("add-flow %s table=1,priority=1,in_port=%s,
>> action=%s"
>> +                      % (self.short_name,
>> +                          port_no, ",".join(relay_flood_ports)))
>>
>
>
> Packets received from second level vteps are not flooded to same level but
> are flooded at other levels - i.e. first level of vteps and physical ports.
>
> Packets received from first level of vteps is flooded to second level vteps
> and physical ports.
>
> To have multi-level vtep support, I was thinking going in the below
> direction.
> Let me know if it satisfies your use case for Neutron L2 border gateways.
>
> diff --git a/vtep/vtep.ovsschema b/vtep/vtep.ovsschema
> index 3a24318..f41568f 100644
> --- a/vtep/vtep.ovsschema
> +++ b/vtep/vtep.ovsschema
> @@ -1,6 +1,6 @@
>  {
>    "name": "hardware_vtep",
> -  "cksum": "353943336 11434",
> +  "cksum": "3167636278 11608",
>    "tables": {
>      "Global": {
>        "columns": {
> @@ -209,7 +209,12 @@
>                "type": "string"}},
>            "mutable": false},
>          "dst_ip": {"type": "string", "mutable": false},
> -        "tunnel_key": {"type": {"key": "integer", "min": 0, "max": 1}}},
> +        "tunnel_key": {"type": {"key": "integer", "min": 0, "max": 1}},
> +        "tunnel_level": {
> +          "type": {
> +            "key": {
> +              "enum": ["set", ["level0", "level1"]],
> +              "type": "string"},"min": 0, "max": 1}}},
>        "indexes": [["encapsulation_type", "dst_ip", "tunnel_key"]]},
>      "ACL_entry": {
>        "columns": {
>
> diff --git a/vtep/vtep.xml b/vtep/vtep.xml
> index 62075ca..6a6c7c6 100644
> --- a/vtep/vtep.xml
> +++ b/vtep/vtep.xml
> @@ -1174,6 +1174,19 @@
>        </p>
>      </column>
>
> +    <column name="tunnel_level">
> +      <p>
> +      <p>
> +        For <code>vxlan_over_ipv4</code> encapsulation, represents the
> +        hierarchy level of the <ref table="Physical_Locator"/>.
> Broadcast,
> +        unknown unicast and multicast (BUM) traffic received at one level
> is
> +        never sent to another <ref table="Physical_Locator"/> of the same
> +        level.  The only valid values supported are level0 and level1;
>  this
> +        column is optional and the default value if not configured is
> level0.
> +      </p>
> +      </p>
> +    </column>
> +
>    </table>
>    <table name="ACL_entry">
>      <p>
>
>
>
>>      def add_lbinding(self, lbinding):
>>          vlog.info("adding %s binding to %s" % (lbinding, self.name))
>> @@ -164,11 +186,22 @@ class Logical_Switch(object):
>>          del self.ports[lbinding]
>>          self.update_flood()
>>
>
>
> I suggest this is unnecessary and make the code harder to read
> and inconsistent with other code here - I am suggesting an incremental
> patch below, after this section of code.
>
>
>>
>> +    def tunnel_dict(self, entry):
>> +        return {
>> +                'tunnel_type': entry[2],
>> +                'dest_ip': entry[3],
>> +                'tunnel_key': entry[5],
>> +               }
>> +
>
>      def add_tunnel(self, tunnel, tunnel_key):
>>          global tun_id
>> -        vlog.info("adding tunnel %s" % tunnel)
>> -        encap, ip = tunnel.split("/")
>> +        if tunnel['tunnel_key']:
>> +            tunnel_key = tunnel['tunnel_key']
>> +        vlog.info("adding tunnel %s key %s" % (tunnel['dest_ip'],
>> +                   tunnel_key))
>>
>> +        encap = tunnel['tunnel_type']
>> +        ip = tunnel['dest_ip']
>>          if encap != "vxlan_over_ipv4":
>>              vlog.warn("unsupported tunnel format %s" % encap)
>>              return
>> @@ -192,7 +225,7 @@ class Logical_Switch(object):
>>              # Give the system a moment to allocate the port number
>>              time.sleep(0.5)
>>
>> -        self.tunnels[tunnel] = (port_no, tun_name, ip)
>> +        self.tunnels[ip] = (port_no, tun_name, ip, tunnel['tunnel_key'])
>>
>>          add_bfd(ip)
>>
>> @@ -200,17 +233,17 @@ class Logical_Switch(object):
>>                    "actions=resubmit(,1)"
>>                    % (self.short_name, port_no))
>>
>> -    def del_tunnel(self, tunnel):
>> -        vlog.info("removing tunnel %s" % tunnel)
>> +    def del_tunnel(self, tunnel_ip):
>> +        vlog.info("removing tunnel %s" % tunnel_ip)
>>
>> -        port_no, tun_name, remote_ip = self.tunnels[tunnel]
>> +        port_no, tun_name, remote_ip, tunnel_key =
>> self.tunnels[tunnel_ip]
>>          ovs_ofctl("del-flows %s table=0,in_port=%s"
>>                    % (self.short_name, port_no))
>>          ovs_vsctl("del-port %s %s" % (self.short_name, tun_name))
>>
>>          del_bfd(remote_ip)
>>
>> -        del self.tunnels[tunnel]
>> +        del self.tunnels[tunnel_ip]
>>
>>      def update_local_macs(self):
>>          flows = ovs_ofctl("dump-flows %s cookie=0x5000/-1,table=1"
>> @@ -231,8 +264,8 @@ class Logical_Switch(object):
>>
>>          self.local_macs = macs
>>
>> -    def add_remote_mac(self, mac, tunnel):
>> -        port_no = self.tunnels.get(tunnel, (0, ""))[0]
>> +    def add_remote_mac(self, mac, tunnel_ip):
>> +        port_no = self.tunnels.get(tunnel_ip, (0, ""))[0]
>>          if not port_no:
>>              return
>>
>> @@ -245,7 +278,7 @@ class Logical_Switch(object):
>>      def update_remote_macs(self):
>>          remote_macs = {}
>>          unknown_dsts = set()
>> -        tunnels = set()
>> +        tunnels = {}
>>          parse_ucast = True
>>
>>          column = vtep_ctl("--columns=tunnel_key find logical_switch "
>> @@ -264,27 +297,26 @@ class Logical_Switch(object):
>>              if (line.find("mcast-mac-remote") != -1):
>>                  parse_ucast = False
>>                  continue
>> -
>> -            entry = re.split(r'  (.*) -> (.*)', line)
>> -            if len(entry) != 4:
>> +            entry = re.split(r'  (.*) -> ([^/]*)/(\S*)( \[(.*)\])?',
>> line)
>> +            if len(entry) != 7:
>>                  continue
>>
>>              if parse_ucast:
>> -                remote_macs[entry[1]] = entry[2]
>> +                remote_macs[entry[1]] = self.tunnel_dict(entry)['tunne
>> l_type']
>>              else:
>>                  if entry[1] != "unknown-dst":
>>                      continue
>>
>> -                unknown_dsts.add(entry[2])
>> +                unknown_dsts.add(entry[3])
>>
>> -            tunnels.add(entry[2])
>> +            tunnels[entry[3]] = self.tunnel_dict(entry)
>>
>>          old_tunnels = set(self.tunnels.keys())
>> +        tunnels_keys = set(tunnels.keys())
>> +        for tunnel in tunnels_keys.difference(old_tunnels):
>> +            self.add_tunnel(tunnels[tunnel], tunnel_key)
>>
>> -        for tunnel in tunnels.difference(old_tunnels):
>> -            self.add_tunnel(tunnel, tunnel_key)
>> -
>> -        for tunnel in old_tunnels.difference(tunnels):
>> +        for tunnel in old_tunnels.difference(tunnels_keys):
>>              self.del_tunnel(tunnel)
>>
>
>
> I am suggesting the following incremental; let me know if it makes sense.
>
> diff --git a/vtep/ovs-vtep b/vtep/ovs-vtep
> index 360f9fd..f1a0b49 100755
> --- a/vtep/ovs-vtep
> +++ b/vtep/ovs-vtep
> @@ -186,25 +186,11 @@ class Logical_Switch(object):
>          del self.ports[lbinding]
>          self.update_flood()
>
> -    def tunnel_dict(self, entry):
> -        return {
> -                'tunnel_type': entry[2],
> -                'dest_ip': entry[3],
> -                'tunnel_key': entry[5],
> -               }
> -
> -    def add_tunnel(self, tunnel, tunnel_key):
> +    def add_tunnel(self, ip, tunnel_key, tunnel_scope_key):
>          global tun_id
> -        if tunnel['tunnel_key']:
> -            tunnel_key = tunnel['tunnel_key']
> -        vlog.info("adding tunnel %s key %s" % (tunnel['dest_ip'],
> -                   tunnel_key))
> -
> -        encap = tunnel['tunnel_type']
> -        ip = tunnel['dest_ip']
> -        if encap != "vxlan_over_ipv4":
> -            vlog.warn("unsupported tunnel format %s" % encap)
> -            return
> +
> +        vlog.info("adding tunnel: ip %s key %s tunnel_scope_key %s" %
> +                  (ip, tunnel_key, tunnel_scope_key))
>
>          tun_id += 1
>          tun_name = "vx" + str(tun_id)
> @@ -218,14 +204,14 @@ class Logical_Switch(object):
>              if port_no != "-1":
>                  break
>              elif i == 9:
> -                vlog.warn("couldn't create tunnel %s" % tunnel)
> +                vlog.warn("couldn't create tunnel %s" % ip)
>                  ovs_vsctl("del-port %s %s" % (self.short_name, tun_name))
>                  return
>
>              # Give the system a moment to allocate the port number
>              time.sleep(0.5)
>
> -        self.tunnels[ip] = (port_no, tun_name, ip, tunnel['tunnel_key'])
> +        self.tunnels[ip] = (port_no, tun_name, ip, tunnel_scope_key)
>
>          add_bfd(ip)
>
> @@ -278,6 +264,7 @@ class Logical_Switch(object):
>      def update_remote_macs(self):
>          remote_macs = {}
>          unknown_dsts = set()
> +        # A map of tunnel ip address to tunnel key
>          tunnels = {}
>          parse_ucast = True
>
> @@ -302,22 +289,23 @@ class Logical_Switch(object):
>                  continue
>
>              if parse_ucast:
> -                remote_macs[entry[1]] = self.tunnel_dict(entry)['
> tunnel_type']
> +                remote_macs[entry[1]] = entry[2]
>              else:
>                  if entry[1] != "unknown-dst":
>                      continue
>
>                  unknown_dsts.add(entry[3])
>
> -            tunnels[entry[3]] = self.tunnel_dict(entry)
> +            tunnels[entry[3]] = entry[5]
>
> -        old_tunnels = set(self.tunnels.keys())
> -        tunnels_keys = set(tunnels.keys())
> -        for tunnel in tunnels_keys.difference(old_tunnels):
> -            self.add_tunnel(tunnels[tunnel], tunnel_key)
> +        old_tunnel_ips = set(self.tunnels.keys())
> +        tunnel_ips = set(tunnels.keys())
> +        for tunnel_ip in tunnel_ips.difference(old_tunnel_ips):
> +            tunnel_scope_key = tunnels[tunnel_ip]
> +            self.add_tunnel(tunnel_ip, tunnel_key, tunnel_scope_key)
>
> -        for tunnel in old_tunnels.difference(tunnels_keys):
> -            self.del_tunnel(tunnel)
> +        for tunnel_ip in old_tunnel_ips.difference(tunnel_ips):
> +            self.del_tunnel(tunnel_ip)
>
>          for mac in six.iterkeys(remote_macs):
>              if (self.remote_macs.get(mac) != remote_macs[mac]):
>
>
>
>>
>>          for mac in six.iterkeys(remote_macs):
>> diff --git a/vtep/vtep-ctl.c b/vtep/vtep-ctl.c
>> index 759150f..1904a71 100644
>> --- a/vtep/vtep-ctl.c
>> +++ b/vtep/vtep-ctl.c
>> @@ -37,6 +37,7 @@
>>  #include "json.h"
>>  #include "ovsdb-data.h"
>>  #include "ovsdb-idl.h"
>> +#include "lib/packets.h"
>>  #include "poll-loop.h"
>>  #include "process.h"
>>  #include "stream.h"
>> @@ -345,18 +346,18 @@ Logical Router commands:\n\
>>    lr-exists LR                exit 2 if LR does not exist\n\
>>  \n\
>>  MAC binding commands:\n\
>> -  add-ucast-local LS MAC [ENCAP] IP   add ucast local entry in LS\n\
>> -  del-ucast-local LS MAC              del ucast local entry from LS\n\
>> -  add-mcast-local LS MAC [ENCAP] IP   add mcast local entry in LS\n\
>> -  del-mcast-local LS MAC [ENCAP] IP   del mcast local entry from LS\n\
>> -  clear-local-macs LS                 clear local mac entries\n\
>> -  list-local-macs LS                  list local mac entries\n\
>> -  add-ucast-remote LS MAC [ENCAP] IP  add ucast remote entry in LS\n\
>> -  del-ucast-remote LS MAC             del ucast remote entry from LS\n\
>> -  add-mcast-remote LS MAC [ENCAP] IP  add mcast remote entry in LS\n\
>> -  del-mcast-remote LS MAC [ENCAP] IP  del mcast remote entry from LS\n\
>> -  clear-remote-macs LS                clear remote mac entries\n\
>> -  list-remote-macs LS                 list remote mac entries\n\
>> +  add-ucast-local LS MAC [ENCAP] IP [KEY]   add ucast local entry in
>> LS\n\
>> +  del-ucast-local LS MAC                    del ucast local entry from
>> LS\n\
>> +  add-mcast-local LS MAC [ENCAP] IP [KEY]   add mcast local entry in
>> LS\n\
>> +  del-mcast-local LS MAC [ENCAP] IP         del mcast local entry from
>> LS\n\
>> +  clear-local-macs LS                       clear local mac entries\n\
>> +  list-local-macs LS                        list local mac entries\n\
>> +  add-ucast-remote LS MAC [ENCAP] IP [KEY]  add ucast remote entry in
>> LS\n\
>> +  del-ucast-remote LS MAC                   del ucast remote entry from
>> LS\n\
>> +  add-mcast-remote LS MAC [ENCAP] IP [KEY]  add mcast remote entry in
>> LS\n\
>> +  del-mcast-remote LS MAC [ENCAP] IP        del mcast remote entry from
>> LS\n\
>> +  clear-remote-macs LS                      clear remote mac entries\n\
>> +  list-remote-macs LS                       list remote mac entries\n\
>>  \n\
>>  %s\
>>  \n\
>> @@ -887,7 +888,8 @@ pre_get_info(struct ctl_context *ctx)
>>                           &vteprec_physical_locator_col_dst_ip);
>>      ovsdb_idl_add_column(ctx->idl,
>>                           &vteprec_physical_locator_col_
>> encapsulation_type);
>> -
>> +    ovsdb_idl_add_column(ctx->idl,
>> +                         &vteprec_physical_locator_col_tunnel_key);
>>      ovsdb_idl_add_column(ctx->idl, &vteprec_tunnel_col_local);
>>      ovsdb_idl_add_column(ctx->idl, &vteprec_tunnel_col_remote);
>>  }
>> @@ -1653,27 +1655,46 @@ add_ucast_entry(struct ctl_context *ctx, bool
>> local)
>>  {
>>      struct vtep_ctl_context *vtepctl_ctx = vtep_ctl_context_cast(ctx);
>>      struct vtep_ctl_lswitch *ls;
>> -    const char *mac;
>> -    const char *encap;
>> -    const char *dst_ip;
>> +    const char *mac = 0;
>> +    const char *encap = 0;
>> +    const char *dst_ip = 0;
>> +    const char *tunnel_key = 0;
>>      struct vteprec_physical_locator *ploc_cfg;
>> +    ovs_be32 ip = 0;
>>
>>      vtep_ctl_context_populate_cache(ctx);
>>
>>      ls = find_lswitch(vtepctl_ctx, ctx->argv[1], true);
>>      mac = ctx->argv[2];
>> -
>> -    if (ctx->argc == 4) {
>> -        encap = "vxlan_over_ipv4";
>> -        dst_ip = ctx->argv[3];
>> -    } else {
>> -        encap = ctx->argv[3];
>> -        dst_ip = ctx->argv[4];
>> +    switch (ctx->argc)
>> +    {
>> +        case 6:
>> +            tunnel_key = ctx->argv[5];
>> +        case 5:
>> +            if (ip_parse(ctx->argv[4],&ip)){
>> +                dst_ip = ctx->argv[4];
>> +                encap = ctx->argv[3];
>> +                break;
>> +            }
>> +            tunnel_key = ctx->argv[4];
>> +        case 4:
>> +            if (ip_parse(ctx->argv[3],&ip)){
>> +                dst_ip = ctx->argv[3];
>> +                encap = "vxlan_over_ipv4";
>> +            }
>> +            break;
>> +        default:
>> +            break;
>>      }
>>
>>      ploc_cfg = find_ploc(vtepctl_ctx, encap, dst_ip);
>>      if (!ploc_cfg) {
>>          ploc_cfg = vteprec_physical_locator_insert(ctx->txn);
>> +        if (tunnel_key) {
>> +            int64_t segement_value = 0;
>> +            ovs_scan(tunnel_key,"%ld",&segement_value);
>> +            vteprec_physical_locator_set_tunnel_key(ploc_cfg,&segement_v
>> alue,1);
>>
>
>
> Please don't use "segment" or the Neutron spelling variant "segement" in
> this case.
> Use generic language such as tunnel_scope_key or per_tunnel_key.
>
> I mentioned this comment in the earlier patch as well.
>
> I did not review most of the code here, pending agreement on the big
> picture.
>
>
>
>
>> +        }
>>          vteprec_physical_locator_set_dst_ip(ploc_cfg, dst_ip);
>>          vteprec_physical_locator_set_encapsulation_type(ploc_cfg,
>> encap);
>>
>> @@ -1790,7 +1811,7 @@ commit_mcast_entries(struct vtep_ctl_mcast_mac
>> *mcast_mac)
>>  static void
>>  add_mcast_entry(struct ctl_context *ctx,
>>                  struct vtep_ctl_lswitch *ls, const char *mac,
>> -                const char *encap, const char *dst_ip, bool local)
>> +                const char *encap, const char *dst_ip, const char*
>> tunnel_key,bool local)
>>  {
>>      struct vtep_ctl_context *vtepctl_ctx = vtep_ctl_context_cast(ctx);
>>      struct shash *mcast_shash;
>> @@ -1839,6 +1860,11 @@ add_mcast_entry(struct ctl_context *ctx,
>>      ploc_cfg = find_ploc(vtepctl_ctx, encap, dst_ip);
>>      if (!ploc_cfg) {
>>          ploc_cfg = vteprec_physical_locator_insert(ctx->txn);
>> +        if (tunnel_key) {
>> +            int64_t tunnel_id = 0;
>> +            ovs_scan(tunnel_key,"%ld",&tunnel_id);
>> +            vteprec_physical_locator_set_tunnel_key(ploc_cfg,&tunnel_id,
>> 1);
>> +        }
>>          vteprec_physical_locator_set_dst_ip(ploc_cfg, dst_ip);
>>          vteprec_physical_locator_set_encapsulation_type(ploc_cfg,
>> encap);
>>
>> @@ -1908,25 +1934,39 @@ add_del_mcast_entry(struct ctl_context *ctx, bool
>> add, bool local)
>>  {
>>      struct vtep_ctl_context *vtepctl_ctx = vtep_ctl_context_cast(ctx);
>>      struct vtep_ctl_lswitch *ls;
>> -    const char *mac;
>> -    const char *encap;
>> -    const char *dst_ip;
>> -
>> +    const char *mac = 0;
>> +    const char *encap = 0;
>> +    const char *dst_ip = 0;
>> +    const char *tunnel_key = 0;
>> +    ovs_be32 ip = 0;
>>      vtep_ctl_context_populate_cache(ctx);
>>
>>      ls = find_lswitch(vtepctl_ctx, ctx->argv[1], true);
>>      mac = ctx->argv[2];
>>
>> -    if (ctx->argc == 4) {
>> -        encap = "vxlan_over_ipv4";
>> -        dst_ip = ctx->argv[3];
>> -    } else {
>> -        encap = ctx->argv[3];
>> -        dst_ip = ctx->argv[4];
>> +    switch (ctx->argc)
>> +    {
>> +        case 6:
>> +            tunnel_key = ctx->argv[5];
>> +        case 5:
>> +            if (ip_parse(ctx->argv[4],&ip)){
>> +                dst_ip = ctx->argv[4];
>> +                encap = ctx->argv[3];
>> +                break;
>> +            }
>> +            tunnel_key = ctx->argv[4];
>> +        case 4:
>> +            if (ip_parse(ctx->argv[3],&ip)){
>> +                dst_ip = ctx->argv[3];
>> +                encap = "vxlan_over_ipv4";
>> +            }
>> +            break;
>> +        default:
>> +            break;
>>      }
>>
>>      if (add) {
>> -        add_mcast_entry(ctx, ls, mac, encap, dst_ip, local);
>> +        add_mcast_entry(ctx, ls, mac, encap, dst_ip, tunnel_key, local);
>>      } else {
>>          del_mcast_entry(ctx, ls, mac, encap, dst_ip, local);
>>      }
>> @@ -2017,7 +2057,7 @@ list_macs(struct ctl_context *ctx, bool local)
>>      struct svec ucast_macs;
>>      struct shash *mcast_shash;
>>      struct svec mcast_macs;
>> -
>> +    char tunnel_key[8];
>>      vtep_ctl_context_populate_cache(ctx);
>>      ls = find_lswitch(vtepctl_ctx, ctx->argv[1], true);
>>
>> @@ -2032,9 +2072,13 @@ list_macs(struct ctl_context *ctx, bool local)
>>          char *entry;
>>
>>          ploc_cfg = local ? ucast_local->locator : ucast_remote->locator;
>> -
>> -        entry = xasprintf("  %s -> %s/%s", node->name,
>> -                          ploc_cfg->encapsulation_type,
>> ploc_cfg->dst_ip);
>> +        tunnel_key[0] = 0;
>> +        if (ploc_cfg->tunnel_key)
>> +            snprintf(&tunnel_key[0],8," [%d]",(uint32_t)(*ploc_cfg->tu
>> nnel_key));
>> +        entry = xasprintf("  %s -> %s/%s%s", node->name,
>> +                          ploc_cfg->encapsulation_type,
>> +                          ploc_cfg->dst_ip,
>> +                          tunnel_key );
>>          svec_add_nocopy(&ucast_macs, entry);
>>      }
>>      ds_put_format(&ctx->output, "ucast-mac-%s\n", local ? "local" :
>> "remote");
>> @@ -2049,9 +2093,13 @@ list_macs(struct ctl_context *ctx, bool local)
>>          char *entry;
>>
>>          LIST_FOR_EACH (ploc, locators_node, &mcast_mac->locators) {
>> -            entry = xasprintf("  %s -> %s/%s", node->name,
>> +            tunnel_key[0] = 0;
>> +            if (ploc->ploc_cfg->tunnel_key)
>> +                snprintf(tunnel_key,8," [%d]",(uint32_t)(*ploc->ploc_c
>> fg->tunnel_key));
>> +            entry = xasprintf("  %s -> %s/%s%s", node->name,
>>                                ploc->ploc_cfg->encapsulation_type,
>> -                              ploc->ploc_cfg->dst_ip);
>> +                              ploc->ploc_cfg->dst_ip,
>> +                              tunnel_key);
>>              svec_add_nocopy(&mcast_macs, entry);
>>          }
>>      }
>> @@ -2508,11 +2556,11 @@ static const struct ctl_command_syntax
>> vtep_commands[] = {
>>      {"lr-exists", 1, 1, NULL, pre_get_info, cmd_lr_exists, NULL, "", RO},
>>
>>      /* MAC binding commands. */
>> -    {"add-ucast-local", 3, 4, NULL, pre_get_info, cmd_add_ucast_local,
>> NULL,
>> +    {"add-ucast-local", 3, 5, NULL, pre_get_info, cmd_add_ucast_local,
>> NULL,
>>       "", RW},
>>      {"del-ucast-local", 2, 2, NULL, pre_get_info, cmd_del_ucast_local,
>> NULL,
>>       "", RW},
>> -    {"add-mcast-local", 3, 4, NULL, pre_get_info, cmd_add_mcast_local,
>> NULL,
>> +    {"add-mcast-local", 3, 5, NULL, pre_get_info, cmd_add_mcast_local,
>> NULL,
>>       "", RW},
>>      {"del-mcast-local", 3, 4, NULL, pre_get_info, cmd_del_mcast_local,
>> NULL,
>>       "", RW},
>> @@ -2520,11 +2568,11 @@ static const struct ctl_command_syntax
>> vtep_commands[] = {
>>       "", RO},
>>      {"list-local-macs", 1, 1, NULL, pre_get_info, cmd_list_local_macs,
>> NULL,
>>       "", RO},
>> -    {"add-ucast-remote", 3, 4, NULL, pre_get_info, cmd_add_ucast_remote,
>> NULL,
>> +    {"add-ucast-remote", 3, 5, NULL, pre_get_info, cmd_add_ucast_remote,
>> NULL,
>>       "", RW},
>>      {"del-ucast-remote", 2, 2, NULL, pre_get_info, cmd_del_ucast_remote,
>> NULL,
>>       "", RW},
>> -    {"add-mcast-remote", 3, 4, NULL, pre_get_info, cmd_add_mcast_remote,
>> NULL,
>> +    {"add-mcast-remote", 3, 5, NULL, pre_get_info, cmd_add_mcast_remote,
>> NULL,
>>       "", RW},
>>      {"del-mcast-remote", 3, 4, NULL, pre_get_info, cmd_del_mcast_remote,
>> NULL,
>>       "", RW},
>> --
>> 1.9.1
>>
>> _______________________________________________
>> dev mailing list
>> dev@openvswitch.org
>> http://openvswitch.org/mailman/listinfo/dev
>>
>
>
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev
-------------------------------------------------------------------------------------------------------------------------------------------------
This email and any files transmitted and/or attachments with it are 
confidential and proprietary information of
Toga Networks Ltd., and intended solely for the use of the individual or entity 
to whom they are addressed.
If you have received this email in error please notify the system manager. This 
message contains confidential
information of Toga Networks Ltd., and is intended only for the individual 
named. If you are not the named
addressee you should not disseminate, distribute or copy this e-mail. Please 
notify the sender immediately
by e-mail if you have received this e-mail by mistake and delete this e-mail 
from your system. If you are not
the intended recipient you are notified that disclosing, copying, distributing 
or taking any action in reliance on
the contents of this information is strictly prohibited.
------------------------------------------------------------------------------------------------------------------------------------------------

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to