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

Reply via email to