[ovs-dev] [PATCH V4 1/1] ovs-vtep: vtep-ctl and ovs-vtep support of adding explicit tunnel key

Ben Pfaff blp at ovn.org
Mon Oct 3 21:55:11 UTC 2016


Justin, are you the right person to review this?

Itamar: sorry about the very long review cycle.  Aug. 29 was in the
middle of a feature freeze for the OVS 2.6 release.  The release went
out last week, so it's time to start reviewing new features again.

I see some style violations here; for example, there should be a space
after each comma.  Please consult CodingStyle.md.

Here's a fix for a mistaken scanf format specifier:

diff --git a/vtep/vtep-ctl.c b/vtep/vtep-ctl.c
index 88b8823..08d0641 100644
--- a/vtep/vtep-ctl.c
+++ b/vtep/vtep-ctl.c
@@ -1718,7 +1718,7 @@ add_ucast_entry(struct ctl_context *ctx, bool local)
     if (!ploc_cfg) {
         ploc_cfg = vteprec_physical_locator_insert(ctx->txn);
         if (args.tunnel_key) {
-            ovs_scan(args.tunnel_key,"%ld",&tunnel_scope_key);
+            ovs_scan(args.tunnel_key,"%"SCNd64,&tunnel_scope_key);
             vteprec_physical_locator_set_tunnel_key(ploc_cfg,
                                                     &tunnel_scope_key,1);
             if (args.tunnel_level){
@@ -1895,7 +1895,7 @@ add_mcast_entry(struct ctl_context *ctx,
         ploc_cfg = vteprec_physical_locator_insert(ctx->txn);
         if (tunnel_key) {
             int64_t tunnel_scope_key = 0;
-            ovs_scan(tunnel_key,"%ld",&tunnel_scope_key);
+            ovs_scan(tunnel_key,"%"SCNd64,&tunnel_scope_key);
             vteprec_physical_locator_set_tunnel_key(ploc_cfg,
                                                     &tunnel_scope_key,1);
             if (tunnel_scope){

With that fixed, though, I get linker errors, though I don't know if
that's due to bit rot since it's been so long:

/home/blp/nicira/ovs/_build/../vtep/vtep-ctl.c:1981: undefined reference to `parse_add_mac_args'
/home/blp/nicira/ovs/_build/../vtep/vtep-ctl.c:1696: undefined reference to `parse_add_mac_args'
/home/blp/nicira/ovs/_build/../vtep/vtep-ctl.c:1715: undefined reference to `parse_add_mac_args'
/home/blp/nicira/ovs/_build/../vtep/vtep-ctl.c:1696: undefined reference to `parse_add_mac_args'

On Mon, Aug 29, 2016 at 07:16:05PM +0300, itamaro wrote:
> From: itamarofek <itamar.ofeq at gmail.com>
> 
> This patch adds support for handeling a per-tunnel tunnel key in the
> ovs-vtep and vtep-ctl.
> 
> 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
> 
> Requested-by: "Ofer Ben-Yacov" <ofer.benyacov at gmail.com>
> Signed-off-by: "Itamar Ofek" <itamar.ofeq at gmail.com>
> Co-authored-by: "Darrell Ball" <dlu998 at gmail.com>
> ---
>  tests/vtep-ctl.at   | 217 +++++++++++++++++++++++++++++++++++++++++++++++-----
>  vtep/ovs-vtep       | 122 ++++++++++++++++++-----------
>  vtep/vtep-ctl.c     | 203 +++++++++++++++++++++++++++++++++---------------
>  vtep/vtep.ovsschema |   9 ++-
>  vtep/vtep.xml       |  12 +++
>  5 files changed, 438 insertions(+), 125 deletions(-)
> 
> diff --git a/tests/vtep-ctl.at b/tests/vtep-ctl.at
> index f0511ad..35a0359 100644
> --- a/tests/vtep-ctl.at
> +++ b/tests/vtep-ctl.at
> @@ -433,12 +433,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: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],
> +   [add-ucast-local ls1 00:11:22:33:55:88 10.0.0.14 300 level0],
> +   [add-ucast-local ls1 00:11:22:33:55:99 vxlan_over_ipv4 10.0.0.15 400 level1])
>  ], [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
> +  00:11:22:33:55:88 -> vxlan_over_ipv4/10.0.0.14 300 level0
> +  00:11:22:33:55:99 -> vxlan_over_ipv4/10.0.0.15 400 level1
>  
>  mcast-mac-local
>  
> @@ -460,11 +468,26 @@ 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],
> +   [add-ucast-local ls1 00:11:22:33:55:99 10.0.0.18 500 level0],
> +   [add-ucast-local ls1 00:11:22:33:55:99 10.0.0.19 600 level1],
> +   [add-ucast-local ls1 00:11:22:33:56:11 10.0.0.20 700 level1],
> +   [add-ucast-local ls1 00:11:22:33:56:11 10.0.0.21])
>  ], [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
> +  00:11:22:33:55:99 -> vxlan_over_ipv4/10.0.0.19 600 level1
> +  00:11:22:33:56:11 -> vxlan_over_ipv4/10.0.0.21
>  
>  mcast-mac-local
>  
> @@ -480,22 +503,34 @@ 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],
> +   [add-ucast-local ls1 00:11:22:33:55:88 10.0.0.14 300 level0],
> +   [add-ucast-local ls1 00:11:22:33:55:99 vxlan_over_ipv4 10.0.0.15 400 level1])
>  ], [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
> +  00:11:22:33:55:88 -> vxlan_over_ipv4/10.0.0.14 300 level0
> +  00:11:22:33:55:99 -> vxlan_over_ipv4/10.0.0.15 400 level1
>  
>  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],
> +   [del-ucast-local ls1 00:11:22:33:55:88],
> +   [del-ucast-local ls1 00:11:22:33:55:99])
>  ], [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 +546,20 @@ 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],
> +   [add-ucast-remote ls1 00:11:22:33:55:88 10.0.0.14 300 level0],
> +   [add-ucast-remote ls1 00:11:22:33:55:99 vxlan_over_ipv4 10.0.0.15 400 level1])
>  ], [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
> +  00:11:22:33:55:88 -> vxlan_over_ipv4/10.0.0.14 300 level0
> +  00:11:22:33:55:99 -> vxlan_over_ipv4/10.0.0.15 400 level1
>  
>  mcast-mac-remote
>  
> @@ -538,11 +581,20 @@ 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],
> +   [add-ucast-remote ls1 00:11:22:33:55:99 10.0.0.18 500 level0],
> +   [add-ucast-remote ls1 00:11:22:33:55:99 10.0.0.19 600 level1],
> +   [add-ucast-remote ls1 00:11:22:33:56:11 10.0.0.20 700 level1],
> +   [add-ucast-remote ls1 00:11:22:33:56:11 10.0.0.21])
>  ], [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
> +  00:11:22:33:55:99 -> vxlan_over_ipv4/10.0.0.19 600 level1
> +  00:11:22:33:56:11 -> vxlan_over_ipv4/10.0.0.21
>  
>  mcast-mac-remote
>  
> @@ -558,22 +610,34 @@ 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],
> +   [add-ucast-remote ls1 00:11:22:33:55:88 10.0.0.14 300 level0],
> +   [add-ucast-remote ls1 00:11:22:33:55:99 vxlan_over_ipv4 10.0.0.15 400 level1])
>  ], [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
> +  00:11:22:33:55:88 -> vxlan_over_ipv4/10.0.0.14 300 level0
> +  00:11:22:33:55:99 -> vxlan_over_ipv4/10.0.0.15 400 level1
>  
>  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],
> +   [del-ucast-remote ls1 00:11:22:33:55:88],
> +   [del-ucast-remote ls1 00:11:22:33:55:99])
>  ], [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 +654,25 @@ 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-local ls1 00:11:22:33:55:88 10.0.0.14 300 level0],
> +   [add-ucast-local ls1 00:11:22:33:55:99 vxlan_over_ipv4 10.0.0.15 400 level1],
>     [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],
> +   [add-ucast-remote ls1 02:11:22:33:55:88 10.0.0.14 300 level0],
> +   [add-ucast-remote ls1 02:11:22:33:55:99 vxlan_over_ipv4 10.0.0.15 400 level1])
>  ], [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
> +  00:11:22:33:55:88 -> vxlan_over_ipv4/10.0.0.14 300 level0
> +  00:11:22:33:55:99 -> vxlan_over_ipv4/10.0.0.15 400 level1
>  
>  mcast-mac-local
>  
> @@ -605,6 +681,10 @@ 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:88 -> vxlan_over_ipv4/10.0.0.14 300 level0
> +  02:11:22:33:55:99 -> vxlan_over_ipv4/10.0.0.15 400 level1
>  
>  mcast-mac-remote
>  
> @@ -621,7 +701,11 @@ 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],
> +   [add-mcast-local ls1 01:11:22:33:55:88 10.0.0.15 300 level0],
> +   [add-mcast-local ls1 01:11:22:33:55:99 vxlan_over_ipv4 10.0.0.16 400 level1])
>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>     [ucast-mac-local
> @@ -630,6 +714,10 @@ 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:88 -> vxlan_over_ipv4/10.0.0.15 300 level0
> +  01:11:22:33:55:99 -> vxlan_over_ipv4/10.0.0.16 400 level1
>  
>  ], [], [VTEP_CTL_CLEANUP])
>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
> @@ -651,7 +739,11 @@ 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],
> +   [add-mcast-local ls1 01:11:22:33:55:88 10.0.0.16 300 level0],
> +   [add-mcast-local ls1 01:11:22:33:55:99 vxlan_over_ipv4 10.0.0.17 400 level1])
>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>     [ucast-mac-local
> @@ -661,10 +753,16 @@ 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:88 -> vxlan_over_ipv4/10.0.0.16 300 level0
> +  01:11:22:33:55:99 -> vxlan_over_ipv4/10.0.0.17 400 level1
>  
>  ], [], [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],
> +   [del-mcast-local ls1 01:11:22:33:55:88 10.0.0.16])
>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>     [ucast-mac-local
> @@ -673,6 +771,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.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:99 -> vxlan_over_ipv4/10.0.0.17 400 level1
>  
>  ], [], [VTEP_CTL_CLEANUP])
>  VTEP_CTL_CLEANUP
> @@ -687,7 +787,12 @@ 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],
> +   [add-mcast-remote ls1 01:11:22:33:55:88 10.0.0.16 300 level0],
> +   [add-mcast-remote ls1 01:11:22:33:55:99 vxlan_over_ipv4 10.0.0.17 400 level1])
>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
>     [ucast-mac-remote
> @@ -696,6 +801,11 @@ 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:88 -> vxlan_over_ipv4/10.0.0.16 300 level0
> +  01:11:22:33:55:99 -> vxlan_over_ipv4/10.0.0.17 400 level1
>  
>  ], [], [VTEP_CTL_CLEANUP])
>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
> @@ -717,7 +827,12 @@ 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],
> +   [add-mcast-remote ls1 01:11:22:33:55:88 10.0.0.17 300 level0],
> +   [add-mcast-remote ls1 01:11:22:33:55:99 vxlan_over_ipv4 10.0.0.18 400 level1])
>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
>     [ucast-mac-remote
> @@ -727,10 +842,17 @@ 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:88 -> vxlan_over_ipv4/10.0.0.17 300 level0
> +  01:11:22:33:55:99 -> vxlan_over_ipv4/10.0.0.18 400 level1
>  
>  ], [], [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],
> +   [del-mcast-remote ls1 01:11:22:33:55:88 10.0.0.17])		
>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
>     [ucast-mac-remote
> @@ -739,6 +861,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.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:99 -> vxlan_over_ipv4/10.0.0.18 400 level1
>  
>  ], [], [VTEP_CTL_CLEANUP])
>  VTEP_CTL_CLEANUP
> @@ -756,7 +881,15 @@ 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],
> +   [add-mcast-local ls1 01:11:22:33:55:88 10.0.0.17 300 level0],
> +   [add-mcast-remote ls1 01:11:22:33:55:99 vxlan_over_ipv4 10.0.0.18 400 level1])
>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>     [ucast-mac-local
> @@ -765,15 +898,23 @@ 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:88 -> vxlan_over_ipv4/10.0.0.17 300 level0
>  
>  ], [], [VTEP_CTL_CLEANUP])
>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
>     [ucast-mac-remote
>  
>  mcast-mac-remote
> +  01:11:22:33:55:99 -> vxlan_over_ipv4/10.0.0.18 400 level1
>    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
> @@ -793,7 +934,15 @@ 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],
> +   [add-mcast-local ls1 01:11:22:33:55:88 10.0.0.17 300 level0],
> +   [add-mcast-remote ls1 03:11:22:33:55:99 vxlan_over_ipv4 10.0.0.18 400 level1])
>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>     [ucast-mac-local
> @@ -803,6 +952,10 @@ 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:88 -> vxlan_over_ipv4/10.0.0.17 300 level0
>  
>  ], [], [VTEP_CTL_CLEANUP])
>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
> @@ -813,6 +966,10 @@ 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:99 -> vxlan_over_ipv4/10.0.0.18 400 level1
>  
>  ], [], [VTEP_CTL_CLEANUP])
>  AT_CHECK([RUN_VTEP_CTL(
> @@ -831,6 +988,10 @@ 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:99 -> vxlan_over_ipv4/10.0.0.18 400 level1
>  
>  ], [], [VTEP_CTL_CLEANUP])
>  VTEP_CTL_CLEANUP
> @@ -850,7 +1011,15 @@ 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],
> +   [add-mcast-local ls1 01:11:22:33:55:88 10.0.0.17 300 level0],
> +   [add-mcast-remote ls1 03:11:22:33:55:99 vxlan_over_ipv4 10.0.0.18 400 level1])
>  ], [0], [], [], [VTEP_CTL_CLEANUP])
>  AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
>     [ucast-mac-local
> @@ -860,6 +1029,10 @@ 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:88 -> vxlan_over_ipv4/10.0.0.17 300 level0
>  
>  ], [], [VTEP_CTL_CLEANUP])
>  AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
> @@ -870,6 +1043,10 @@ 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:99 -> vxlan_over_ipv4/10.0.0.18 400 level1
>  
>  ], [], [VTEP_CTL_CLEANUP])
>  AT_CHECK([RUN_VTEP_CTL(
> @@ -882,6 +1059,10 @@ 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:88 -> vxlan_over_ipv4/10.0.0.17 300 level0
>  
>  ], [], [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..dfb94e6 100755
> --- a/vtep/ovs-vtep
> +++ b/vtep/ovs-vtep
> @@ -33,6 +33,12 @@ import six
>  
>  
>  VERSION = "0.99"
> +MACS_MAC_INDEX = 1
> +MACS_ENCAP_INDEX = 2
> +MACS_DEST_IP_INDEX = 3
> +MACS_KEY_INDEX = 4
> +MACS_LEVEL_INDEX = 5
> +MACS_NUM_OF_FIELDS = 7
>  
>  root_prefix = ""
>  
> @@ -120,30 +126,54 @@ 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):
> +        level0_ports = []
> +        level1_ports = []
> +        for tunnel in tunnel_list:
> +            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
>  
> -        # 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())
> +        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.  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.
> -        for tunnel in self.unknown_dsts:
> -            port_no = self.tunnels[tunnel][0]
> -            flood_ports.append(port_no)
> +
> +        phy_flood_ports = phy_ports + level1_unknown
> +        if len(level0_unknown) > 0:
>              if self.replication_mode == "service_node":
> -                break
> +                phy_flood_ports += level0_unknown[0]
> +            else:
> +                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)))
>  
> -        ovs_ofctl("add-flow %s table=1,priority=0,action=%s"
> -                  % (self.short_name, ",".join(flood_ports)))
> +        # Traffic flowing from a level0 VTEP should not be flooded to level0
> +        # unknown-dst 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(level0_flood_ports)))
> +
> +        # Traffic flowing from a level1 VTEP should not be flooded to level1
> +        # unknown-dst 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(level1_flood_ports)))
>  
>      def add_lbinding(self, lbinding):
>          vlog.info("adding %s binding to %s" % (lbinding, self.name))
> @@ -164,14 +194,12 @@ class Logical_Switch(object):
>          del self.ports[lbinding]
>          self.update_flood()
>  
> -    def add_tunnel(self, tunnel, tunnel_key):
> +    def add_tunnel(self, ip, tunnel_key, tunnel_level):
>          global tun_id
> -        vlog.info("adding tunnel %s" % tunnel)
> -        encap, ip = tunnel.split("/")
>  
> -        if encap != "vxlan_over_ipv4":
> -            vlog.warn("unsupported tunnel format %s" % encap)
> -            return
> +        vlog.info("adding tunnel: ip %s key %s %s" %
> +                  (ip, tunnel_key,
> +                   'level1' if tunnel_level is 'level1' else 'level0'))
>  
>          tun_id += 1
>          tun_name = "vx" + str(tun_id)
> @@ -185,14 +213,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[tunnel] = (port_no, tun_name, ip)
> +        self.tunnels[ip] = (port_no, tun_name, ip, tunnel_key, tunnel_level)
>  
>          add_bfd(ip)
>  
> @@ -200,17 +228,18 @@ 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, tunnel_level) = 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 +260,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 +274,8 @@ class Logical_Switch(object):
>      def update_remote_macs(self):
>          remote_macs = {}
>          unknown_dsts = set()
> -        tunnels = set()
> +        # A map of tunnel ip address to tunnel key and tunnel level
> +        tunnels = {}
>          parse_ucast = True
>  
>          column = vtep_ctl("--columns=tunnel_key find logical_switch "
> @@ -264,28 +294,32 @@ 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*)\s?(\d+)?\s?(.*)?',
> +                             line)
> +            if len(entry) != MACS_NUM_OF_FIELDS:
>                  continue
>  
>              if parse_ucast:
> -                remote_macs[entry[1]] = entry[2]
> +                remote_macs[entry[MACS_MAC_INDEX]] = entry[MACS_ENCAP_INDEX]
>              else:
> -                if entry[1] != "unknown-dst":
> +                if entry[MACS_MAC_INDEX] != "unknown-dst":
>                      continue
>  
> -                unknown_dsts.add(entry[2])
> -
> -            tunnels.add(entry[2])
> +                unknown_dsts.add(entry[MACS_DEST_IP_INDEX])
>  
> -        old_tunnels = set(self.tunnels.keys())
> -
> -        for tunnel in tunnels.difference(old_tunnels):
> -            self.add_tunnel(tunnel, tunnel_key)
> +            tunnels[entry[MACS_DEST_IP_INDEX]] = (entry[MACS_KEY_INDEX],
> +                                                  entry[MACS_LEVEL_INDEX])
> +        old_tunnel_ips = set(self.tunnels.keys())
> +        tunnel_ips = set(tunnels.keys())
> +        for tunnel_ip in tunnel_ips.difference(old_tunnel_ips):
> +            if tunnels[tunnel_ip][0]:
> +                tunnel_scope_key = tunnels[tunnel_ip][0]
> +            else:
> +                tunnel_scope_key = tunnel_key
> +            self.add_tunnel(tunnel_ip, tunnel_scope_key, tunnels[tunnel_ip][1])
>  
> -        for tunnel in old_tunnels.difference(tunnels):
> -            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 245ba0d..88b8823 100644
> --- a/vtep/vtep-ctl.c
> +++ b/vtep/vtep-ctl.c
> @@ -37,6 +37,7 @@
>  #include "openvswitch/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 [LEVEL]]  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 [LEVEL]]  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 [LEVEL]] 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 [LEVEL]] 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\
> @@ -451,6 +452,14 @@ struct vtep_ctl_context {
>                               * struct vtep_ctl_lrouter. */
>  };
>  
> +struct add_mac_args {
> +    const char *mac;
> +    const char *encap;
> +    const char *dst_ip;
> +    const char *tunnel_key;
> +    const char *tunnel_level;
> +};
> +
>  /* Casts 'base' into 'struct vtep_ctl_context'. */
>  static struct vtep_ctl_context *
>  vtep_ctl_context_cast(struct ctl_context *base)
> @@ -887,7 +896,10 @@ 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_physical_locator_col_tunnel_level);
>      ovsdb_idl_add_column(ctx->idl, &vteprec_tunnel_col_local);
>      ovsdb_idl_add_column(ctx->idl, &vteprec_tunnel_col_remote);
>  }
> @@ -1648,34 +1660,75 @@ cmd_lr_exists(struct ctl_context *ctx)
>      }
>  }
>  
> +inline void
> +parse_add_mac_args(struct ctl_context *ctx, struct add_mac_args* args)
> +{
> +    ovs_be32 ip = 0;
> +    if (ctx->argc < 4 ) {
> +      ctl_fatal("invalid argument set only %d args supplied",ctx->argc);
> +  
> +    }
> +    int index = 2;
> +    args->mac = ctx->argv[index];
> +    /* check 3rd argument if its ip assume vxlan_over_ipv4
> +     * else take the encapsulation from supplied argument
> +     */
> +    if (!ip_parse(ctx->argv[++index], &ip)) {
> +        args->encap = ctx->argv[index++];
> +    } else {
> +        args->encap = "vxlan_over_ipv4";
> +    }
> +    args->dst_ip = ctx->argv[index];
> +    /* if no more arguments supplied prsing is done
> +     */
> +    if (ctx->argc == ++index) {
> +        return;
> +    }
> +    /* check for optional tunnel_key
> +     */
> +    args->tunnel_key = ctx->argv[index];
> +    if (ctx->argc == ++index) {
> +        return;
> +    }
> +    /* tunnel level can be given only if tunnel key is provided
> +     */
> +    args->tunnel_level = ctx->argv[index];
> +    if (ctx->argc == ++index) {
> +        return;
> +    }
> +    ctl_fatal("Unexpected number of argument %d", index);
> +}
> +
>  static void
>  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;
> +    struct add_mac_args args;
> +    memset(&args,0,sizeof(args));
> +    int64_t tunnel_scope_key = 0;
> +
>      struct vteprec_physical_locator *ploc_cfg;
>  
>      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];
> -    }
> -
> -    ploc_cfg = find_ploc(vtepctl_ctx, encap, dst_ip);
> +    parse_add_mac_args(ctx,&args);
> +    ploc_cfg = find_ploc(vtepctl_ctx, args.encap, args.dst_ip);
>      if (!ploc_cfg) {
>          ploc_cfg = vteprec_physical_locator_insert(ctx->txn);
> -        vteprec_physical_locator_set_dst_ip(ploc_cfg, dst_ip);
> -        vteprec_physical_locator_set_encapsulation_type(ploc_cfg, encap);
> +        if (args.tunnel_key) {
> +            ovs_scan(args.tunnel_key,"%ld",&tunnel_scope_key);
> +            vteprec_physical_locator_set_tunnel_key(ploc_cfg,
> +                                                    &tunnel_scope_key,1);
> +            if (args.tunnel_level){
> +                vteprec_physical_locator_set_tunnel_level(ploc_cfg,
> +                                                          args.tunnel_level);
> +            }
> +
> +        }
> +        vteprec_physical_locator_set_dst_ip(ploc_cfg,args.dst_ip);
> +        vteprec_physical_locator_set_encapsulation_type(ploc_cfg, args.encap);
>  
>          add_ploc_to_cache(vtepctl_ctx, ploc_cfg);
>      }
> @@ -1683,23 +1736,23 @@ add_ucast_entry(struct ctl_context *ctx, bool local)
>      if (local) {
>          struct vteprec_ucast_macs_local *ucast_cfg;
>  
> -        ucast_cfg = shash_find_data(&ls->ucast_local, mac);
> +        ucast_cfg = shash_find_data(&ls->ucast_local, args.mac);
>          if (!ucast_cfg) {
>              ucast_cfg = vteprec_ucast_macs_local_insert(ctx->txn);
> -            vteprec_ucast_macs_local_set_MAC(ucast_cfg, mac);
> +            vteprec_ucast_macs_local_set_MAC(ucast_cfg, args.mac);
>              vteprec_ucast_macs_local_set_logical_switch(ucast_cfg, ls->ls_cfg);
> -            shash_add(&ls->ucast_local, mac, ucast_cfg);
> +            shash_add(&ls->ucast_local, args.mac, ucast_cfg);
>          }
>          vteprec_ucast_macs_local_set_locator(ucast_cfg, ploc_cfg);
>      } else {
>          struct vteprec_ucast_macs_remote *ucast_cfg;
>  
> -        ucast_cfg = shash_find_data(&ls->ucast_remote, mac);
> +        ucast_cfg = shash_find_data(&ls->ucast_remote, args.mac);
>          if (!ucast_cfg) {
>              ucast_cfg = vteprec_ucast_macs_remote_insert(ctx->txn);
> -            vteprec_ucast_macs_remote_set_MAC(ucast_cfg, mac);
> +            vteprec_ucast_macs_remote_set_MAC(ucast_cfg, args.mac);
>              vteprec_ucast_macs_remote_set_logical_switch(ucast_cfg, ls->ls_cfg);
> -            shash_add(&ls->ucast_remote, mac, ucast_cfg);
> +            shash_add(&ls->ucast_remote, args.mac, ucast_cfg);
>          }
>          vteprec_ucast_macs_remote_set_locator(ucast_cfg, ploc_cfg);
>      }
> @@ -1790,7 +1843,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, bool local)
> +                const char *encap, const char *dst_ip, const char* tunnel_key,
> +                const char* tunnel_scope, bool local)
>  {
>      struct vtep_ctl_context *vtepctl_ctx = vtep_ctl_context_cast(ctx);
>      struct shash *mcast_shash;
> @@ -1839,6 +1893,16 @@ 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_scope_key = 0;
> +            ovs_scan(tunnel_key,"%ld",&tunnel_scope_key);
> +            vteprec_physical_locator_set_tunnel_key(ploc_cfg,
> +                                                    &tunnel_scope_key,1);
> +            if (tunnel_scope){
> +                vteprec_physical_locator_set_tunnel_level(ploc_cfg,
> +                                                          tunnel_scope);
> +            }
> +        }
>          vteprec_physical_locator_set_dst_ip(ploc_cfg, dst_ip);
>          vteprec_physical_locator_set_encapsulation_type(ploc_cfg, encap);
>  
> @@ -1908,27 +1972,18 @@ 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;
> +    struct add_mac_args args;
> +    memset(&args,0,sizeof(args));
> +    
>  
>      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];
> -    }
> -
> +    parse_add_mac_args(ctx,&args);
>      if (add) {
> -        add_mcast_entry(ctx, ls, mac, encap, dst_ip, local);
> +        add_mcast_entry(ctx, ls, args.mac, args.encap, args.dst_ip, args.tunnel_key,args.tunnel_level, local);
>      } else {
> -        del_mcast_entry(ctx, ls, mac, encap, dst_ip, local);
> +        del_mcast_entry(ctx, ls, args.mac, args.encap, args.dst_ip, local);
>      }
>  
>      vtep_ctl_context_invalidate_cache(ctx);
> @@ -2017,7 +2072,8 @@ list_macs(struct ctl_context *ctx, bool local)
>      struct svec ucast_macs;
>      struct shash *mcast_shash;
>      struct svec mcast_macs;
> -
> +    char tunnel_key[10];
> +    char tunnel_level[10];
>      vtep_ctl_context_populate_cache(ctx);
>      ls = find_lswitch(vtepctl_ctx, ctx->argv[1], true);
>  
> @@ -2032,9 +2088,21 @@ 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], 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_level);
>          svec_add_nocopy(&ucast_macs, entry);
>      }
>      ds_put_format(&ctx->output, "ucast-mac-%s\n", local ? "local" : "remote");
> @@ -2049,9 +2117,22 @@ 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, 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);
> +                              ploc->ploc_cfg->dst_ip,
> +                              tunnel_key,
> +                              tunnel_level);
>              svec_add_nocopy(&mcast_macs, entry);
>          }
>      }
> @@ -2508,11 +2589,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, 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, 4, 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},
> @@ -2520,11 +2601,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, 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, 4, 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>
> -- 
> 1.9.1
> 
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev



More information about the dev mailing list