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

Ben Pfaff blp at ovn.org
Mon Oct 30 21:06:22 UTC 2017


Justin, I don't think there's been a review of this yet.  It's been
almost 8 months.  Are you planning to take a look?

On Wed, Mar 08, 2017 at 03:58:28PM -0800, Ben Pfaff wrote:
> Justin, you've reviewed previous versions of this patch.  Will you look
> at this one?
> 
> On Sun, Feb 19, 2017 at 01:45:15PM +0200, 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.8.in  |  25 ++++--
> >  vtep/vtep-ctl.c     | 252 ++++++++++++++++++++++++++++++++++++----------------
> >  vtep/vtep.ovsschema |   9 +-
> >  vtep/vtep.xml       |  13 +++
> >  6 files changed, 488 insertions(+), 150 deletions(-)
> > 
> > diff --git a/tests/vtep-ctl.at b/tests/vtep-ctl.at
> > index 2b0df67..4290025 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 fd652d4..e73343b 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 = ""
> >  
> > @@ -124,30 +130,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))
> > @@ -168,14 +198,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)
> > @@ -189,14 +217,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)
> >  
> > @@ -204,17 +232,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"
> > @@ -235,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
> >  
> > @@ -249,7 +278,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 "
> > @@ -268,28 +298,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.8.in b/vtep/vtep-ctl.8.in
> > index 1901356..eca795c 100644
> > --- a/vtep/vtep-ctl.8.in
> > +++ b/vtep/vtep-ctl.8.in
> > @@ -263,12 +263,16 @@ Remove the local unicast Ethernet address \fImac\fR map from
> >  \fIlswitch\fR.  The local mappings are used by the VTEP to refer to MACs
> >  learned on its physical ports.
> >  .
> > -.IP "\fBadd\-mcast\-local \fIlswitch mac\fR [\fIencap\fR] \fIip\fR"
> > +.IP "\fBadd\-mcast\-local \fIlswitch mac\fR [\fIencap\fR] \fIip\fR [\fIkey\fR
> > +[\fIlevel\fR]]"
> >  Add physical location \fIip\fR using encapsulation \fIencap\fR to the
> >  local mac binding table for multicast Ethernet address \fImac\fR on
> > -\fIlswitch\fR.  If \fIencap\fR is not specified, the default is
> > -"vxlan_over_ipv4".  The local mappings are used by the VTEP to refer to
> > -MACs learned on its physical ports.
> > +\fIlswitch\fR with tunnel identifier equals to \fIkey\fR at BUM 
> > +unknown unicast and multicast distribution level [\fIlevel\fR. If \fIencap\fR
> > +is not specified, the default is "vxlan_over_ipv4". If \fIkey\fR is not
> > +specified the default is \fIlswitch\fR tunnel key. If [\fIlevel\fR is not
> > +specified the default is "level0". The local mappings are used by the VTEP
> > +to refer to MACs learned on its physical ports.
> >  .
> >  .IP "\fBdel\-mcast\-local \fIlswitch mac\fR [\fIencap\fR] \fIip\fR"
> >  Remove physical location \fIip\fR using encapsulation \fIencap\fR from
> > @@ -288,12 +292,15 @@ These commands examine and manipulate local and remote MAC bindings for
> >  the logical switch.  The remote maps are written by the network
> >  virtualization controller to refer to MACs that it has learned.
> >  .
> > -.IP "\fBadd\-ucast\-remote \fIlswitch mac\fR [\fIencap\fR] \fIip\fR"
> > +.IP "\fBadd\-ucast\-remote \fIlswitch mac\fR [\fIencap\fR] \fIip\fR [\fIkey\fR
> > +[\fIlevel\fR]]"
> >  Map the unicast Ethernet address \fImac\fR to the physical location
> > -\fIip\fR using encapsulation \fIencap\fR on \fIlswitch\fR.  If
> > -\fIencap\fR is not specified, the default is "vxlan_over_ipv4".  The
> > -remote mappings are used by the network virtualization platform to refer
> > -to MACs that it has learned.
> > +\fIip\fR using encapsulation \fIencap\fR on \fIlswitch\fR with tunnel
> > +identifier equals to \fIkey\fR at distribution level [\fIlevel\fR. 
> > +If \fIencap\fR is not specified, the default is "vxlan_over_ipv4". If \fIkey\fR
> > +is not specified the default is \fIlswitch\fR tunnel key. If [\fIlevel\fR is not
> > +specified the default is "level0". The remote mappings are used by the network
> > +virtualization platform to refer to MACs that it has learned.
> >  .
> >  .IP "\fBdel\-ucast\-remote \fIlswitch mac\fR"
> >  Remove the remote unicast Ethernet address \fImac\fR map from
> > diff --git a/vtep/vtep-ctl.c b/vtep/vtep-ctl.c
> > index e23c987..712a9d0 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"
> > @@ -344,18 +345,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\
> > @@ -450,6 +451,7 @@ struct vtep_ctl_context {
> >                               * struct vtep_ctl_lrouter. */
> >  };
> >  
> > +
> >  /* Casts 'base' into 'struct vtep_ctl_context'. */
> >  static struct vtep_ctl_context *
> >  vtep_ctl_context_cast(struct ctl_context *base)
> > @@ -886,7 +888,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);
> >  }
> > @@ -1647,34 +1652,88 @@ cmd_lr_exists(struct ctl_context *ctx)
> >      }
> >  }
> >  
> > +struct add_mac_args {
> > +    const char *mac;
> > +    const char *encap;
> > +    const char *dst_ip;
> > +    const char *tunnel_key;
> > +    const char *tunnel_level;
> > +};
> > +
> > +inline static void
> > +parse_add_mac_args(struct ctl_context *ctx, struct add_mac_args* args)
> > +{
> > +    /* This code is assumes a specific location for each "arg" argument,
> > +     * with a minumim argument list of 4 according to the following format.
> > +     * arg[0]: Command, arg[1]:LogicalSwitch, arg[2]: MAC 
> > +     * arg[3] optionally tunnel ENCAP or peer IP.
> > +     * When there are 5 arguments,If arg[3] is ENCAP  arg[4] must be IP,
> > +     * else arg[4] is tunnel key.
> > +     * When there are 6 arguments, if arg[4] is ip, arg[5] is the tunnel key,
> > +     * else it is the tunnel level.
> > +     * When there are 7 arguments, arg[6] is the tunnel level. */ 
> > +    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 */
> > +    ovs_be32 ip = 0;
> > +    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 parsing 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 = {0};
> > +   /* memset(&args,0,sizeof args);*/
> > +
> >      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) {
> > +            int64_t tunnel_scope_key = 0;
> > +            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);
> >      }
> > @@ -1682,23 +1741,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);
> >      }
> > @@ -1788,8 +1847,11 @@ 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)
> > +                struct vtep_ctl_lswitch *ls, 
> > +                /*
> > +                const char *mac,
> > +                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;
> > @@ -1801,15 +1863,17 @@ add_mcast_entry(struct ctl_context *ctx,
> >  
> >      /* Physical locator sets are immutable, so allocate a new one. */
> >      ploc_set_cfg = vteprec_physical_locator_set_insert(ctx->txn);
> > -
> > -    mcast_mac = shash_find_data(mcast_shash, mac);
> > +    struct add_mac_args args = {0};
> > +    /* memset(&args,0,sizeof args); */
> > +    parse_add_mac_args(ctx,&args);
> > +    mcast_mac = shash_find_data(mcast_shash, args.mac);
> >      if (!mcast_mac) {
> > -        mcast_mac = add_mcast_mac_to_cache(vtepctl_ctx, ls, mac, ploc_set_cfg,
> > -                                           local);
> > +        mcast_mac = add_mcast_mac_to_cache(vtepctl_ctx, ls, args.mac,
> > +                                           ploc_set_cfg, local);
> >  
> >          if (local) {
> >              mcast_mac->local_cfg = vteprec_mcast_macs_local_insert(ctx->txn);
> > -            vteprec_mcast_macs_local_set_MAC(mcast_mac->local_cfg, mac);
> > +            vteprec_mcast_macs_local_set_MAC(mcast_mac->local_cfg, args.mac);
> >              vteprec_mcast_macs_local_set_locator_set(mcast_mac->local_cfg,
> >                                                       ploc_set_cfg);
> >              vteprec_mcast_macs_local_set_logical_switch(mcast_mac->local_cfg,
> > @@ -1817,7 +1881,7 @@ add_mcast_entry(struct ctl_context *ctx,
> >              mcast_mac->remote_cfg = NULL;
> >          } else {
> >              mcast_mac->remote_cfg = vteprec_mcast_macs_remote_insert(ctx->txn);
> > -            vteprec_mcast_macs_remote_set_MAC(mcast_mac->remote_cfg, mac);
> > +            vteprec_mcast_macs_remote_set_MAC(mcast_mac->remote_cfg,args.mac);
> >              vteprec_mcast_macs_remote_set_locator_set(mcast_mac->remote_cfg,
> >                                                        ploc_set_cfg);
> >              vteprec_mcast_macs_remote_set_logical_switch(mcast_mac->remote_cfg,
> > @@ -1835,11 +1899,21 @@ add_mcast_entry(struct ctl_context *ctx,
> >          }
> >      }
> >  
> > -    ploc_cfg = find_ploc(vtepctl_ctx, encap, dst_ip);
> > +    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) {
> > +            int64_t tunnel_scope_key = 0;
> > +            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);
> >      }
> > @@ -1850,23 +1924,29 @@ add_mcast_entry(struct ctl_context *ctx,
> >  
> >  static void
> >  del_mcast_entry(struct ctl_context *ctx,
> > -                struct vtep_ctl_lswitch *ls, const char *mac,
> > -                const char *encap, const char *dst_ip, bool local)
> > +                struct vtep_ctl_lswitch *ls,
> > +                /*
> > +                const char *mac,
> > +                const char *encap, const char *dst_ip,
> > +                */
> > +                bool local)
> >  {
> >      struct vtep_ctl_context *vtepctl_ctx = vtep_ctl_context_cast(ctx);
> >      struct vtep_ctl_mcast_mac *mcast_mac;
> >      struct shash *mcast_shash;
> >      struct vteprec_physical_locator *ploc_cfg;
> >      struct vteprec_physical_locator_set *ploc_set_cfg;
> > +    struct add_mac_args args = {0};
> >  
> >      mcast_shash = local ? &ls->mcast_local : &ls->mcast_remote;
> > -
> > -    mcast_mac = shash_find_data(mcast_shash, mac);
> > +    
> > +    parse_add_mac_args(ctx,&args);
> > +    mcast_mac = shash_find_data(mcast_shash, args.mac);
> >      if (!mcast_mac) {
> >          return;
> >      }
> >  
> > -    ploc_cfg = find_ploc(vtepctl_ctx, encap, dst_ip);
> > +    ploc_cfg = find_ploc(vtepctl_ctx, args.encap, args.dst_ip);
> >      if (!ploc_cfg) {
> >          /* Couldn't find the physical locator, so just ignore. */
> >          return;
> > @@ -1878,7 +1958,7 @@ del_mcast_entry(struct ctl_context *ctx,
> >  
> >      del_ploc_from_mcast_mac(mcast_mac, ploc_cfg);
> >      if (ovs_list_is_empty(&mcast_mac->locators)) {
> > -        struct shash_node *node = shash_find(mcast_shash, mac);
> > +        struct shash_node *node = shash_find(mcast_shash, args.mac);
> >  
> >          vteprec_physical_locator_set_delete(ploc_set_cfg);
> >  
> > @@ -1907,27 +1987,19 @@ 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);
> > @@ -2016,7 +2088,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);
> >  
> > @@ -2031,9 +2104,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");
> > @@ -2048,9 +2133,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);
> >          }
> >      }
> > @@ -2457,11 +2555,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},
> > @@ -2469,11 +2567,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..b450838 100644
> > --- a/vtep/vtep.xml
> > +++ b/vtep/vtep.xml
> > @@ -1174,6 +1174,19 @@
> >        </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 <code>level0
> > +	</code> and <code> level1 </code>;
> > +	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
> > https://mail.openvswitch.org/mailman/listinfo/ovs-dev


More information about the dev mailing list