On Sun, Aug 14, 2016 at 3:59 AM, Itamar Ofek <itamar.o...@toganetworks.com>
wrote:

>
> 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"
>

I mentioned the default of level0 in the vtep.xml file and its also
explicit in the
ovs-vtep code.
Note, however vtep-ctl.c should not set this as explicit default in the
VTEP DB if
not supplied by the user.





> and vtep-ctl should be changed accordingly.
>
-- I can suggest a patch for it.
>

Yes, please add this parsing for tunnel_level; see below for more comments.

>
> 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.
>

I am including a more comprehensive incremental patch as a suggestion
and to speed the process along.
It includes:
1) my tunnel_level suggestion and some related documentation
2) ovs-vtep support for tunnel_level and tunnel_scope_key including
   parsing changes for "list-remote-macs".
   I added tunnel_level flood set changes which follows what you did
   for "relay" and "mesh" tunnels, but I made it generic using tunnel_level.

3) Other ovs-vtep suggested changes.
4) vtep-ctl.c changes for parsing tunnel_scope_key and general parsing
handling for modified code paths.
  I removed the "[[]]" formatting for tunnel_scope_key here and in ovs-vtep.
5) Coding standard suggestions.
6) vtep-ctl.at format changes after removing the [[]]

It does NOT include vtep-ctl.c changes to parse tunnel_level and the various
cases for optional arguments (there are 3 optional arguments now) - that
needs to be added. I am assuming you will add that parsing for different
cases.
vtep-ctl.at should be updated for tunnel_level as well.

I think you should be primary owner for the patches and I can help as
needed.

diff --git a/tests/vtep-ctl.at b/tests/vtep-ctl.at
index 4178309..239560b 100644
--- a/tests/vtep-ctl.at
+++ b/tests/vtep-ctl.at
@@ -441,8 +441,8 @@ 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]]
+  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

@@ -475,9 +475,9 @@ AT_CHECK([RUN_VTEP_CTL(
 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: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]]
+  00:11:22:33:55:88 -> vxlan_over_ipv4/10.0.0.17 400

 mcast-mac-local

@@ -501,8 +501,8 @@ 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]]
+  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

@@ -514,7 +514,7 @@ AT_CHECK([RUN_VTEP_CTL(
 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]]
+  00:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.13 200

 mcast-mac-local

@@ -538,8 +538,8 @@ 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]]
+  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

@@ -568,7 +568,7 @@ AT_CHECK([RUN_VTEP_CTL(
 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]]
+  00:11:22:33:55:66 -> vxlan_over_ipv4/10.0.0.13 200

 mcast-mac-remote

@@ -592,8 +592,8 @@ 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]]
+  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

@@ -605,7 +605,7 @@ AT_CHECK([RUN_VTEP_CTL(
 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]]
+  00:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.13 200

 mcast-mac-remote

@@ -633,8 +633,8 @@ 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]]
+  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

@@ -643,8 +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]]
+  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

@@ -672,8 +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]]
+  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],
@@ -707,8 +707,8 @@ 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]]
+  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(
@@ -722,7 +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]]
+  01:11:22:33:55:77 -> vxlan_over_ipv4/10.0.0.15 200

 ], [], [VTEP_CTL_CLEANUP])
 VTEP_CTL_CLEANUP
@@ -749,9 +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]]
+  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],
@@ -786,9 +786,9 @@ 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]]
+  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(
@@ -802,8 +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]]
+  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
@@ -836,9 +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]]
+  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],
@@ -848,9 +848,9 @@ 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]]
+  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
@@ -886,9 +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]]
+  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],
@@ -899,9 +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]]
+  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(
@@ -920,9 +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]]
+  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
@@ -958,9 +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]]
+  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],
@@ -971,9 +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]]
+  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(
@@ -986,9 +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]]
+  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 360f9fd..3b1e52e 100755
--- a/vtep/ovs-vtep
+++ b/vtep/ovs-vtep
@@ -121,51 +121,53 @@ class Logical_Switch(object):
             del_bfd(remote_ip)

     def vtep_ports(self, tunnel_list):
-        relay_ports, mesh_ports = list(), list()
+        level0_ports = list()
+        level1_ports = 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
+            if self.tunnels[tunnel][4] is 'level1':
+                level1_ports.append(self.tunnels[tunnel][0])
+            else:
+                level0_ports.append(self.tunnels[tunnel][0])
+        return level1_ports, level0_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)
+        level1_ports, level0_ports = self.vtep_ports(self.tunnels.keys())
+        level1_unknown, level0_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 and all relay VTEP ports.
-        # If the replication mode is service node then
+        # this logical switch and all level1 VTEP ports.
+        # If the level0 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.

-        phy_flood_ports = phy_ports + relay_unknown
-        if len(mesh_unknown) > 0:
+        phy_flood_ports = phy_ports + level1_unknown
+        if len(level0_unknown) > 0:
             if self.replication_mode == "service_node":
-                phy_flood_ports += mesh_unknown[0]
+                phy_flood_ports += level0_unknown[0]
             else:
-                phy_flood_ports += mesh_unknown
+                phy_flood_ports += level0_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
+        # Traffic flowing from a level0 VTEP should not be flooded to
level0
         # unknown-dst ports
-        mesh_flood_ports = phy_ports + relay_unknown
-        for port_no in mesh_ports:
+        level0_flood_ports = phy_ports + level1_unknown
+        for port_no in level0_ports:
             ovs_ofctl("add-flow %s table=1,priority=1,in_port=%s,action=%s"
-                      % (self.short_name, port_no,
",".join(mesh_flood_ports)))
+                      % (self.short_name, port_no,
+                         ",".join(level0_flood_ports)))

-        # Traffic flowing from a relay VTEP should not be flooded to relay
+        # Traffic flowing from a level1 VTEP should not be flooded to
level1
         # unknown-dst ports
-        relay_flood_ports = phy_ports + mesh_unknown
-        for port_no in relay_ports:
+        level1_flood_ports = phy_ports + level0_unknown
+        for port_no in level1_ports:
             ovs_ofctl("add-flow %s table=1,priority=1,in_port=%s,action=%s"
                       % (self.short_name,
-                          port_no, ",".join(relay_flood_ports)))
+                          port_no, ",".join(level1_flood_ports)))

     def add_lbinding(self, lbinding):
         vlog.info("adding %s binding to %s" % (lbinding, self.name))
@@ -186,25 +188,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, tunnel_level):
         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 +206,15 @@ 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,
+                            tunnel_level)

         add_bfd(ip)

@@ -278,6 +267,7 @@ class Logical_Switch(object):
     def update_remote_macs(self):
         remote_macs = {}
         unknown_dsts = set()
+        # A map of tunnel ip address to tunnel key and tunnel level
         tunnels = {}
         parse_ucast = True

@@ -297,27 +287,32 @@ class Logical_Switch(object):
             if (line.find("mcast-mac-remote") != -1):
                 parse_ucast = False
                 continue
-            entry = re.split(r'  (.*) -> ([^/]*)/(\S*)( \[(.*)\])?', line)
+            entry = re.split(r'  (.*) -> ([^/]*)/(\S*)\s?([0-9]?)\s?(.*)?',
+                             line)
             if len(entry) != 7:
                 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[4], 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][0]
+            if (tunnel_scope_key):
+                tunnel_key = tunnel_scope_key
+            self.add_tunnel(tunnel_ip, tunnel_key, tunnel_scope_key,
+                            tunnels[tunnel_ip][1])

-        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]):
diff --git a/vtep/vtep-ctl.c b/vtep/vtep-ctl.c
index 1869d3f..948463d 100644
--- a/vtep/vtep-ctl.c
+++ b/vtep/vtep-ctl.c
@@ -1655,9 +1655,9 @@ 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 = 0;
-    const char *encap = 0;
-    const char *dst_ip = 0;
+    const char *mac;
+    const char *encap;
+    const char *dst_ip;
     const char *tunnel_key = 0;
     struct vteprec_physical_locator *ploc_cfg;
     ovs_be32 ip = 0;
@@ -1669,31 +1669,40 @@ add_ucast_entry(struct ctl_context *ctx, bool local)
     switch (ctx->argc)
     {
         case 6:
+            encap = ctx->argv[3];
+            dst_ip = ctx->argv[4];
             tunnel_key = ctx->argv[5];
+            break;
         case 5:
             if (ip_parse(ctx->argv[4],&ip)){
-                dst_ip = ctx->argv[4];
                 encap = ctx->argv[3];
-                break;
+                dst_ip = ctx->argv[4];
+            } else {
+                encap = "vxlan_over_ipv4";
+                dst_ip = ctx->argv[3];
+                tunnel_key = ctx->argv[4];
             }
-            tunnel_key = ctx->argv[4];
+            break;
         case 4:
             if (ip_parse(ctx->argv[3],&ip)){
                 dst_ip = ctx->argv[3];
                 encap = "vxlan_over_ipv4";
+                break;
+            } else {
+                ctl_fatal("bad ip address %s", ctx->argv[3]);
             }
-            break;
         default:
-            break;
+            ctl_fatal("invalid argument set");
     }

     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_value,1);
+            int64_t tunnel_scope_key = 0;
+            ovs_scan(tunnel_key,"%ld",&tunnel_scope_key);
+            vteprec_physical_locator_set_tunnel_key(ploc_cfg,
+                                                    &tunnel_scope_key,1);
         }
         vteprec_physical_locator_set_dst_ip(ploc_cfg, dst_ip);
         vteprec_physical_locator_set_encapsulation_type(ploc_cfg, encap);
@@ -1811,7 +1820,8 @@ 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, const char*
tunnel_key,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;
@@ -1861,9 +1871,10 @@ add_mcast_entry(struct ctl_context *ctx,
     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);
+            int64_t tunnel_scope_key = 0;
+            ovs_scan(tunnel_key,"%ld",&tunnel_scope_key);
+            vteprec_physical_locator_set_tunnel_key(ploc_cfg,
+                                                    &tunnel_scope_key,1);
         }
         vteprec_physical_locator_set_dst_ip(ploc_cfg, dst_ip);
         vteprec_physical_locator_set_encapsulation_type(ploc_cfg, encap);
@@ -1934,9 +1945,9 @@ 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 = 0;
-    const char *encap = 0;
-    const char *dst_ip = 0;
+    const char *mac;
+    const char *encap;
+    const char *dst_ip;
     const char *tunnel_key = 0;
     ovs_be32 ip = 0;
     vtep_ctl_context_populate_cache(ctx);
@@ -1947,22 +1958,30 @@ add_del_mcast_entry(struct ctl_context *ctx, bool
add, bool local)
     switch (ctx->argc)
     {
         case 6:
+            encap = ctx->argv[3];
+            dst_ip = ctx->argv[4];
             tunnel_key = ctx->argv[5];
+            break;
         case 5:
             if (ip_parse(ctx->argv[4],&ip)){
-                dst_ip = ctx->argv[4];
                 encap = ctx->argv[3];
-                break;
+                dst_ip = ctx->argv[4];
+            } else {
+                encap = "vxlan_over_ipv4";
+                dst_ip = ctx->argv[3];
+                tunnel_key = ctx->argv[4];
             }
-            tunnel_key = ctx->argv[4];
+            break;
         case 4:
             if (ip_parse(ctx->argv[3],&ip)){
                 dst_ip = ctx->argv[3];
                 encap = "vxlan_over_ipv4";
+                break;
+            } else {
+                ctl_fatal("bad ip address %s", ctx->argv[3]);
             }
-            break;
         default:
-            break;
+            ctl_fatal("invalid argument set");
     }

     if (add) {
@@ -2057,7 +2076,8 @@ list_macs(struct ctl_context *ctx, bool local)
     struct svec ucast_macs;
     struct shash *mcast_shash;
     struct svec mcast_macs;
-    char tunnel_key[8];
+    char tunnel_key[10];
+    char tunnel_level[10];
     vtep_ctl_context_populate_cache(ctx);
     ls = find_lswitch(vtepctl_ctx, ctx->argv[1], true);

@@ -2072,13 +2092,21 @@ list_macs(struct ctl_context *ctx, bool local)
         char *entry;

         ploc_cfg = local ? ucast_local->locator : ucast_remote->locator;
-        tunnel_key[0] = 0;
-        if (ploc_cfg->tunnel_key)
-            snprintf(&tunnel_key[0],8,"
[%d]",(uint32_t)(*ploc_cfg->tunnel_key));
-        entry = xasprintf("  %s -> %s/%s%s", node->name,
+        tunnel_key[0] = '\0';
+        if (ploc_cfg->tunnel_key) {
+            snprintf(&tunnel_key[0], 10, " %d",
+                     (uint32_t)(*ploc_cfg->tunnel_key));
+        }
+        if (ploc_cfg->tunnel_level) {
+            snprintf(tunnel_level, 10, " %s", ploc_cfg->tunnel_level);
+        } else {
+            tunnel_level[0] = '\0';
+        }
+        entry = xasprintf("  %s -> %s/%s%s%s", node->name,
                           ploc_cfg->encapsulation_type,
                           ploc_cfg->dst_ip,
-                          tunnel_key );
+                          tunnel_key,
+                                                 tunnel_level);
         svec_add_nocopy(&ucast_macs, entry);
     }
     ds_put_format(&ctx->output, "ucast-mac-%s\n", local ? "local" :
"remote");
@@ -2093,13 +2121,22 @@ list_macs(struct ctl_context *ctx, bool local)
         char *entry;

         LIST_FOR_EACH (ploc, locators_node, &mcast_mac->locators) {
-            tunnel_key[0] = 0;
-            if (ploc->ploc_cfg->tunnel_key)
-                snprintf(tunnel_key,8,"
[%d]",(uint32_t)(*ploc->ploc_cfg->tunnel_key));
-            entry = xasprintf("  %s -> %s/%s%s", node->name,
+            tunnel_key[0] = '\0';
+            if (ploc->ploc_cfg->tunnel_key) {
+                snprintf(tunnel_key, 10, " %d",
+                         (uint32_t)(*ploc->ploc_cfg->tunnel_key));
+            }
+            if (ploc->ploc_cfg->tunnel_level) {
+                snprintf(tunnel_level, 10, " %s",
+                         ploc->ploc_cfg->tunnel_level);
+            } else {
+                tunnel_level[0] = '\0';
+            }
+            entry = xasprintf("  %s -> %s/%s%s%s", node->name,
                               ploc->ploc_cfg->encapsulation_type,
                               ploc->ploc_cfg->dst_ip,
-                              tunnel_key);
+                              tunnel_key,
+                                                         tunnel_level);
             svec_add_nocopy(&mcast_macs, entry);
         }
     }
@@ -2556,11 +2593,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, 5, NULL, pre_get_info, cmd_add_ucast_local,
NULL,
+    {"add-ucast-local", 3, 6, 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, 5, NULL, pre_get_info, cmd_add_mcast_local,
NULL,
+    {"add-mcast-local", 3, 6, 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},
@@ -2568,11 +2605,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, 5, NULL, pre_get_info, cmd_add_ucast_remote,
NULL,
+    {"add-ucast-remote", 3, 6, 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, 5, NULL, pre_get_info, cmd_add_mcast_remote,
NULL,
+    {"add-mcast-remote", 3, 6, 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},
diff --git a/vtep/vtep.ovsschema b/vtep/vtep.ovsschema
index 3a24318..35c3fd2 100644
--- a/vtep/vtep.ovsschema
+++ b/vtep/vtep.ovsschema
@@ -1,6 +1,6 @@
 {
   "name": "hardware_vtep",
-  "cksum": "353943336 11434",
+  "cksum": "2728111540 11603",
   "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..0d255e7 100644
--- a/vtep/vtep.xml
+++ b/vtep/vtep.xml
@@ -1174,6 +1174,18 @@
       </p>
     </column>

+    <column name="tunnel_level">
+      <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>
+    </column>
+
   </table>
   <table name="ACL_entry">
     <p>




>
> 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