diff mbox

[ovs-dev,v3] Add VxLAN-GBP support for user space data path

Message ID 1461221026-14900-1-git-send-email-johnson.li@intel.com
State Changes Requested
Headers show

Commit Message

Johnson.Li April 21, 2016, 6:43 a.m. UTC
From: Johnson Li <johnson.li@intel.com>

In user space, only standard VxLAN was support. This patch will
add the VxLAN-GBP support for the user space data path.

How to use:
1> Create VxLAN port with GBP extension
  $ovs-vsctl add-port br-int vxlan0 -- set interface vxlan0 \
           type=vxlan options:dst_port=4789 \
           options:remote_ip=192.168.60.22 \
           options:key=1000 options:exts=gbp
2> Add flow for transmitting
  $ovs-ofctl add-flow br-int "table=0, priority=260, \
             in_port=LOCAL actions=load:0x100->NXM_NX_TUN_GBP_ID[], \
             output:1"
3> Add flow for receiving
  $ovs-ofctl add-flow br-int "table=0, priority=260, \
             in_port=1,tun_gbp_id=0x100 actions=output:LOCAL"

Check data path flow rules:
$ovs-appctl dpif/dump-flows br-int
  recirc_id(0),in_port(1),eth_type(0x0800),ipv4(tos=0/0x3,frag=no),
  packets:0, bytes:0, used:never, actions:tnl_push(tnl_port(2),
  header(size=50,type=4,eth(dst=90:e2:ba:48:7f:a4,src=90:e2:ba:48:7e:1c,
  dl_type=0x0800),ipv4(src=192.168.60.21,dst=192.168.60.22,proto=17,
  tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),
  vxlan(flags=0x88000100,vni=0x3e8)),out_port(3))
  tunnel(tun_id=0x3e8,src=192.168.60.22,dst=192.168.60.21,
  vxlan(gbp(id=256)),flags(-df-csum+key)),skb_mark(0),recirc_id(0),
  in_port(2),eth(dst=ae:1b:ed:1e:e3:4e),eth_type(0x0800),
  ipv4(dst=172.168.60.21,proto=1/0x10,frag=no), packets:0, bytes:0,
  used:never, actions:1

---
Change Log:
  v3: Change Macro definition, add more comments, add unit test.
  v2: Set Each enabled bit for the VxLAN-GBP.

Signed-off-by: Johnson Li <johnson.li@intel.com>

Comments

Jesse Gross April 21, 2016, 4:44 p.m. UTC | #1
On Wed, Apr 20, 2016 at 11:43 PM, Johnson.Li <johnson.li@intel.com> wrote:
> From: Johnson Li <johnson.li@intel.com>
>
> In user space, only standard VxLAN was support. This patch will
> add the VxLAN-GBP support for the user space data path.
>
> How to use:
> 1> Create VxLAN port with GBP extension
>   $ovs-vsctl add-port br-int vxlan0 -- set interface vxlan0 \
>            type=vxlan options:dst_port=4789 \
>            options:remote_ip=192.168.60.22 \
>            options:key=1000 options:exts=gbp
> 2> Add flow for transmitting
>   $ovs-ofctl add-flow br-int "table=0, priority=260, \
>              in_port=LOCAL actions=load:0x100->NXM_NX_TUN_GBP_ID[], \
>              output:1"
> 3> Add flow for receiving
>   $ovs-ofctl add-flow br-int "table=0, priority=260, \
>              in_port=1,tun_gbp_id=0x100 actions=output:LOCAL"
>
> Check data path flow rules:
> $ovs-appctl dpif/dump-flows br-int
>   recirc_id(0),in_port(1),eth_type(0x0800),ipv4(tos=0/0x3,frag=no),
>   packets:0, bytes:0, used:never, actions:tnl_push(tnl_port(2),
>   header(size=50,type=4,eth(dst=90:e2:ba:48:7f:a4,src=90:e2:ba:48:7e:1c,
>   dl_type=0x0800),ipv4(src=192.168.60.21,dst=192.168.60.22,proto=17,
>   tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),
>   vxlan(flags=0x88000100,vni=0x3e8)),out_port(3))
>   tunnel(tun_id=0x3e8,src=192.168.60.22,dst=192.168.60.21,
>   vxlan(gbp(id=256)),flags(-df-csum+key)),skb_mark(0),recirc_id(0),
>   in_port(2),eth(dst=ae:1b:ed:1e:e3:4e),eth_type(0x0800),
>   ipv4(dst=172.168.60.21,proto=1/0x10,frag=no), packets:0, bytes:0,
>   used:never, actions:1
>
> ---
> Change Log:
>   v3: Change Macro definition, add more comments, add unit test.
>   v2: Set Each enabled bit for the VxLAN-GBP.
>
> Signed-off-by: Johnson Li <johnson.li@intel.com>

Please do not submit a new version of a patch without addressing the
existing comments. I have asked you several times to not interpret
bits from an extension without checking whether that extension has
explicitly been enabled.

In addition, it appears that you are copying code from the Linux
kernel. You cannot do this as the licenses are not compatible.
Johnson.Li April 22, 2016, 1:03 a.m. UTC | #2
> -----Original Message-----

> From: Jesse Gross [mailto:jesse@kernel.org]

> Sent: Friday, April 22, 2016 12:44 AM

> To: Li, Johnson <johnson.li@intel.com>

> Cc: ovs dev <dev@openvswitch.org>

> Subject: Re: [ovs-dev] [PATCH v3] Add VxLAN-GBP support for user space

> data path

> 

> On Wed, Apr 20, 2016 at 11:43 PM, Johnson.Li <johnson.li@intel.com> wrote:

> > From: Johnson Li <johnson.li@intel.com>

> >

> > In user space, only standard VxLAN was support. This patch will add

> > the VxLAN-GBP support for the user space data path.

> >

> > How to use:

> > 1> Create VxLAN port with GBP extension

> >   $ovs-vsctl add-port br-int vxlan0 -- set interface vxlan0 \

> >            type=vxlan options:dst_port=4789 \

> >            options:remote_ip=192.168.60.22 \

> >            options:key=1000 options:exts=gbp

> > 2> Add flow for transmitting

> >   $ovs-ofctl add-flow br-int "table=0, priority=260, \

> >              in_port=LOCAL actions=load:0x100->NXM_NX_TUN_GBP_ID[], \

> >              output:1"

> > 3> Add flow for receiving

> >   $ovs-ofctl add-flow br-int "table=0, priority=260, \

> >              in_port=1,tun_gbp_id=0x100 actions=output:LOCAL"

> >

> > Check data path flow rules:

> > $ovs-appctl dpif/dump-flows br-int

> >   recirc_id(0),in_port(1),eth_type(0x0800),ipv4(tos=0/0x3,frag=no),

> >   packets:0, bytes:0, used:never, actions:tnl_push(tnl_port(2),

> >   header(size=50,type=4,eth(dst=90:e2:ba:48:7f:a4,src=90:e2:ba:48:7e:1c,

> >   dl_type=0x0800),ipv4(src=192.168.60.21,dst=192.168.60.22,proto=17,

> >   tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),

> >   vxlan(flags=0x88000100,vni=0x3e8)),out_port(3))

> >   tunnel(tun_id=0x3e8,src=192.168.60.22,dst=192.168.60.21,

> >   vxlan(gbp(id=256)),flags(-df-csum+key)),skb_mark(0),recirc_id(0),

> >   in_port(2),eth(dst=ae:1b:ed:1e:e3:4e),eth_type(0x0800),

> >   ipv4(dst=172.168.60.21,proto=1/0x10,frag=no), packets:0, bytes:0,

> >   used:never, actions:1

> >

> > ---

> > Change Log:

> >   v3: Change Macro definition, add more comments, add unit test.

> >   v2: Set Each enabled bit for the VxLAN-GBP.

> >

> > Signed-off-by: Johnson Li <johnson.li@intel.com>

> 

> Please do not submit a new version of a patch without addressing the

> existing comments. I have asked you several times to not interpret bits from

> an extension without checking whether that extension has explicitly been

> enabled.

> 

The code in the kernel data path checks the vxlan_sock.flags:
(vs->flags & VXLAN_F_GBP).
It could do this because kernel space implementation has the basis of UDP socket. 
But for the userspace, no such socket exists,  and the codes are in tunnel's pop_header
Callback, no other flags is set to indicate that the tunnel is GBP is enable. 
So from my understanding, in the user space, we must trust the flags in the packets.
And from my understanding, G bit is only used in the GBP from the drafts I have read,
Other drafts keep this bit as Reserved, so it must set 0. 
The codes are in the tunnel's pop_header callback, the only parameter is 
struct dp_packet *packet
we cannot get additional flags from this input. 
That why I don't check additional flags. 
> In addition, it appears that you are copying code from the Linux kernel. You

> cannot do this as the licenses are not compatible.

No codes are copied from kernel, but I copied the comment which is VxLAN-GBP header
Definition from the vxlan.h
Jesse Gross April 22, 2016, 1:29 a.m. UTC | #3
On Thu, Apr 21, 2016 at 6:03 PM, Li, Johnson <johnson.li@intel.com> wrote:
>> -----Original Message-----
>> From: Jesse Gross [mailto:jesse@kernel.org]
>> Sent: Friday, April 22, 2016 12:44 AM
>> To: Li, Johnson <johnson.li@intel.com>
>> Cc: ovs dev <dev@openvswitch.org>
>> Subject: Re: [ovs-dev] [PATCH v3] Add VxLAN-GBP support for user space
>> data path
>>
>> On Wed, Apr 20, 2016 at 11:43 PM, Johnson.Li <johnson.li@intel.com> wrote:
>> > From: Johnson Li <johnson.li@intel.com>
>> >
>> > In user space, only standard VxLAN was support. This patch will add
>> > the VxLAN-GBP support for the user space data path.
>> >
>> > How to use:
>> > 1> Create VxLAN port with GBP extension
>> >   $ovs-vsctl add-port br-int vxlan0 -- set interface vxlan0 \
>> >            type=vxlan options:dst_port=4789 \
>> >            options:remote_ip=192.168.60.22 \
>> >            options:key=1000 options:exts=gbp
>> > 2> Add flow for transmitting
>> >   $ovs-ofctl add-flow br-int "table=0, priority=260, \
>> >              in_port=LOCAL actions=load:0x100->NXM_NX_TUN_GBP_ID[], \
>> >              output:1"
>> > 3> Add flow for receiving
>> >   $ovs-ofctl add-flow br-int "table=0, priority=260, \
>> >              in_port=1,tun_gbp_id=0x100 actions=output:LOCAL"
>> >
>> > Check data path flow rules:
>> > $ovs-appctl dpif/dump-flows br-int
>> >   recirc_id(0),in_port(1),eth_type(0x0800),ipv4(tos=0/0x3,frag=no),
>> >   packets:0, bytes:0, used:never, actions:tnl_push(tnl_port(2),
>> >   header(size=50,type=4,eth(dst=90:e2:ba:48:7f:a4,src=90:e2:ba:48:7e:1c,
>> >   dl_type=0x0800),ipv4(src=192.168.60.21,dst=192.168.60.22,proto=17,
>> >   tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),
>> >   vxlan(flags=0x88000100,vni=0x3e8)),out_port(3))
>> >   tunnel(tun_id=0x3e8,src=192.168.60.22,dst=192.168.60.21,
>> >   vxlan(gbp(id=256)),flags(-df-csum+key)),skb_mark(0),recirc_id(0),
>> >   in_port(2),eth(dst=ae:1b:ed:1e:e3:4e),eth_type(0x0800),
>> >   ipv4(dst=172.168.60.21,proto=1/0x10,frag=no), packets:0, bytes:0,
>> >   used:never, actions:1
>> >
>> > ---
>> > Change Log:
>> >   v3: Change Macro definition, add more comments, add unit test.
>> >   v2: Set Each enabled bit for the VxLAN-GBP.
>> >
>> > Signed-off-by: Johnson Li <johnson.li@intel.com>
>>
>> Please do not submit a new version of a patch without addressing the
>> existing comments. I have asked you several times to not interpret bits from
>> an extension without checking whether that extension has explicitly been
>> enabled.
>>
> The code in the kernel data path checks the vxlan_sock.flags:
> (vs->flags & VXLAN_F_GBP).
> It could do this because kernel space implementation has the basis of UDP socket.
> But for the userspace, no such socket exists,  and the codes are in tunnel's pop_header
> Callback, no other flags is set to indicate that the tunnel is GBP is enable.
> So from my understanding, in the user space, we must trust the flags in the packets.
> And from my understanding, G bit is only used in the GBP from the drafts I have read,
> Other drafts keep this bit as Reserved, so it must set 0.
> The codes are in the tunnel's pop_header callback, the only parameter is
> struct dp_packet *packet
> we cannot get additional flags from this input.
> That why I don't check additional flags.

It is true that the code is structured differently between OVS and Linux.

However, that does not mean that you can ignore correctness simply
because it isn't convenient. If you need to restructure things in
order for your changes to work, then you must do that. There are many,
many changes in both OVS and Linux that require this type of
infrastructure work before patches can go in. In neither case are
patches applied before this is done.

>> In addition, it appears that you are copying code from the Linux kernel. You
>> cannot do this as the licenses are not compatible.
> No codes are copied from kernel, but I copied the comment which is VxLAN-GBP header
> Definition from the vxlan.h

Comments are copyrighted too. Please do not copy anything from the
Linux kernel into OVS.

In addition, the way that I could tell that this is from Linux you
copied references to things that only exist in Linux and don't make
sense in the context of OVS.
diff mbox

Patch

diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
index e398562..a7b5923 100644
--- a/lib/netdev-vport.c
+++ b/lib/netdev-vport.c
@@ -1286,6 +1286,7 @@  netdev_vxlan_pop_header(struct dp_packet *packet)
     struct flow_tnl *tnl = &md->tunnel;
     struct vxlanhdr *vxh;
     unsigned int hlen;
+    uint32_t vxh_flags;
 
     pkt_metadata_init_tnl(md);
     if (VXLAN_HLEN > dp_packet_l4_size(packet)) {
@@ -1297,7 +1298,22 @@  netdev_vxlan_pop_header(struct dp_packet *packet)
         return EINVAL;
     }
 
-    if (get_16aligned_be32(&vxh->vx_flags) != htonl(VXLAN_FLAGS) ||
+    /* VXLAN protocol header:
+     * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     * |G|R|R|R|I|R|R|C|               Reserved                        |
+     * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     *
+     * G = 1	Group Policy (VXLAN-GBP)
+     * I = 1	VXLAN Network Identifier (VNI) present
+     */
+    vxh_flags = htonl(get_16aligned_be32(&vxh->vx_flags));
+    if (vxh_flags & VXLAN_HF_GBP) {
+        tnl->gbp_id = ntohs(vxh_flags & VXLAN_GBP_ID_MASK);
+        vxh_flags &= (VXLAN_GBP_DONT_LEARN | VXLAN_GBP_POLICY_APPLIED);
+        tnl->gbp_flags = vxh_flags >> 16;
+    }
+
+    if (!(get_16aligned_be32(&vxh->vx_flags) & htonl(VXLAN_HF_VNI)) ||
        (get_16aligned_be32(&vxh->vx_vni) & htonl(0xff))) {
         VLOG_WARN_RL(&err_rl, "invalid vxlan flags=%#x vni=%#x\n",
                      ntohl(get_16aligned_be32(&vxh->vx_flags)),
@@ -1312,6 +1328,27 @@  netdev_vxlan_pop_header(struct dp_packet *packet)
     return 0;
 }
 
+static void
+netdev_vxlan_build_gbp_header(struct vxlanhdr *vxh,
+                              const struct flow *tnl_flow)
+{
+    /* VNI must be valid, so I bit should be set. */
+    uint32_t vxh_flags = VXLAN_HF_VNI;
+
+    /* G bit to indicates that the source TSI Group membership is being
+     * carried within the Group Policy ID field. */
+    vxh_flags |= VXLAN_HF_GBP;
+
+    /* Only D bit and A bit are valid in gbp_flags. Other bits which are
+     * set should be ignored. */
+    vxh_flags |= (tnl_flow->tunnel.gbp_flags << 16)
+              & (VXLAN_GBP_DONT_LEARN | VXLAN_GBP_POLICY_APPLIED);
+
+    vxh_flags |= ntohs(tnl_flow->tunnel.gbp_id);
+
+    put_16aligned_be32(&vxh->vx_flags, htonl(vxh_flags));
+}
+
 static int
 netdev_vxlan_build_header(const struct netdev *netdev,
                           struct ovs_action_push_tnl *data,
@@ -1328,7 +1365,11 @@  netdev_vxlan_build_header(const struct netdev *netdev,
 
     vxh = udp_build_header(tnl_cfg, tnl_flow, data, &hlen);
 
-    put_16aligned_be32(&vxh->vx_flags, htonl(VXLAN_FLAGS));
+    if (tnl_cfg->exts & (1 << OVS_VXLAN_EXT_GBP)) {
+        netdev_vxlan_build_gbp_header(vxh, tnl_flow);
+    } else {
+        put_16aligned_be32(&vxh->vx_flags, htonl(VXLAN_HF_VNI));
+    }
     put_16aligned_be32(&vxh->vx_vni, htonl(ntohll(tnl_flow->tunnel.tun_id) << 8));
 
     ovs_mutex_unlock(&dev->mutex);
diff --git a/lib/packets.h b/lib/packets.h
index 8139a6b..23e964d 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -995,13 +995,49 @@  struct gre_base_hdr {
 #define GRE_FLAGS       0x00F8
 #define GRE_VERSION     0x0007
 
-/* VXLAN protocol header */
+/*
+ * VXLAN Group Based Policy Extension (VXLAN_F_GBP):
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |G|R|R|R|I|R|R|R|R|D|R|R|A|R|R|R|        Group Policy ID        |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                VXLAN Network Identifier (VNI) |   Reserved    |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * G = Group Policy ID present.
+ *
+ * D = Don't Learn bit. When set, this bit indicates that the egress
+ *     VTEP MUST NOT learn the source address of the encapsulated frame.
+ *
+ * A = Indicates that the group policy has already been applied to
+ *     this packet. Policies MUST NOT be applied by devices when the
+ *     A bit is set.
+ *
+ * https://tools.ietf.org/html/draft-smith-vxlan-group-policy
+ */
+#define VXLAN_GBP_DONT_LEARN		(1 << 22)
+#define VXLAN_GBP_POLICY_APPLIED	(1 << 19)
+#define VXLAN_GBP_ID_MASK		(0xFFFF)
+
+/* VXLAN protocol header:
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |G|R|R|R|I|R|R|C|               Reserved                        |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                VXLAN Network Identifier (VNI) |   Reserved    |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * G = 1	Group Policy (VXLAN-GBP)
+ * I = 1	VXLAN Network Identifier (VNI) present
+ * C = 1	Remote checksum offload (RCO)
+ */
 struct vxlanhdr {
     ovs_16aligned_be32 vx_flags;
     ovs_16aligned_be32 vx_vni;
 };
 
-#define VXLAN_FLAGS 0x08000000  /* struct vxlanhdr.vx_flags required value. */
+/* VXLAN header flags. */
+#define VXLAN_HF_RCO (1 << 21)
+#define VXLAN_HF_VNI (1 << 27)
+#define VXLAN_HF_GBP (1 << 31)
 
 void ipv6_format_addr(const struct in6_addr *addr, struct ds *);
 void ipv6_format_addr_bracket(const struct in6_addr *addr, struct ds *,
diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at
index a7909d3..5bd7096 100644
--- a/tests/tunnel-push-pop.at
+++ b/tests/tunnel-push-pop.at
@@ -12,6 +12,8 @@  AT_CHECK([ovs-vsctl add-port int-br t2 -- set Interface t2 type=vxlan \
                        options:remote_ip=1.1.2.93 options:out_key=flow options:csum=true ofport_request=4\
                     -- add-port int-br t4 -- set Interface t4 type=geneve \
                        options:remote_ip=flow options:key=123 ofport_request=5\
+                    -- add-port int-br t5 -- set Interface t5 type=vxlan \
+                       options:remote_ip=1.1.2.94 options:key=456 options:exts=gbp ofport_request=6\
                        ], [0])
 
 AT_CHECK([ovs-appctl dpif/show], [0], [dnl
@@ -25,6 +27,7 @@  dummy@ovs-dummy: hit:0 missed:0
 		t2 2/4789: (vxlan: key=123, remote_ip=1.1.2.92)
 		t3 4/4789: (vxlan: csum=true, out_key=flow, remote_ip=1.1.2.93)
 		t4 5/6081: (geneve: key=123, remote_ip=flow)
+		t5 6/4789: (vxlan: key=456, remote_ip=1.1.2.94)
 ])
 
 dnl First setup dummy interface IP address, then add the route
@@ -55,12 +58,14 @@  ffffffffffffaa55aa55000008060001080006040001aa55aa550000010102580000000000000101
 dnl Check ARP Snoop
 AT_CHECK([ovs-appctl netdev-dummy/receive br0 'recirc_id(0),in_port(100),eth(src=f8:bc:12:44:34:b6,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b6,tha=00:00:00:00:00:00)'])
 AT_CHECK([ovs-appctl netdev-dummy/receive br0 'recirc_id(0),in_port(100),eth(src=f8:bc:12:44:34:b7,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.93,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b7,tha=00:00:00:00:00:00)'])
+AT_CHECK([ovs-appctl netdev-dummy/receive br0 'recirc_id(0),in_port(100),eth(src=f8:bc:12:44:34:b8,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.94,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b8,tha=00:00:00:00:00:00)'])
 
 AT_CHECK([ovs-appctl tnl/neigh/show], [0], [dnl
 IP                                            MAC                 Bridge
 ==========================================================================
 1.1.2.92                                      f8:bc:12:44:34:b6   br0
 1.1.2.93                                      f8:bc:12:44:34:b7   br0
+1.1.2.94                                      f8:bc:12:44:34:b8   br0
 ])
 
 AT_CHECK([ovs-appctl tnl/ports/show |sort], [0], [dnl
@@ -102,6 +107,13 @@  AT_CHECK([tail -1 stdout], [0],
   [Datapath actions: tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=f8:bc:12:44:34:b7,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.93,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0xffff),vxlan(flags=0x8000000,vni=0x7c)),out_port(100))
 ])
 
+dnl Check VXLAN-GBP tunnel push
+AT_CHECK([ovs-ofctl add-flow int-br "actions=load:0x100->NXM_NX_TUN_GBP_ID[[]],output:6"])
+AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0,ttl=64,frag=no)'], [0], [stdout])
+AT_CHECK([tail -1 stdout], [0],
+  [Datapath actions: tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=f8:bc:12:44:34:b8,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.94,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0x88000100,vni=0x1c8)),out_port(100))
+])
+
 dnl Check GRE tunnel push
 AT_CHECK([ovs-ofctl add-flow int-br action=3])
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0,ttl=64,frag=no)'], [0], [stdout])