Hi, Please have a look at v8: https://mail.openvswitch.org/pipermail/ovs-dev/2017-May/332898.html
Best regards, Zoltan > -----Original Message----- > From: ovs-dev-boun...@openvswitch.org > [mailto:ovs-dev-boun...@openvswitch.org] On Behalf Of Zoltán Balogh > Sent: Thursday, May 25, 2017 5:38 PM > To: 'd...@openvswitch.org' <d...@openvswitch.org> > Subject: [ovs-dev] [PATCH v7 3/3] userspace: add vxlan gpe support to vport > > From: Georg Schmuecking <georg.schmueck...@ericsson.com> > > This patch is based on the "datapath: enable vxlangpe creation in compat mode" > from Yi Yang. It introduces an extension option "gpe" to the vxlan port in the > netdev-dpdk datapath. Description of vxlan gpe protocoll was added to header > file lib/packets.h. In the vxlan specific methods the different packet are > introduced and handled. > > Added VXLAN GPE tunnel push test. > > Signed-off-by: Yi Yang <yi.y.yang at intel.com> > Signed-off-by: Georg Schmuecking <georg.schmueck...@ericsson.com> > --- > datapath/linux/compat/include/linux/openvswitch.h | 1 + > include/openvswitch/automake.mk | 1 - > lib/netdev-native-tnl.c | 59 > +++++++++++++++++++++-- > lib/netdev-vport.c | 22 +++++++-- > lib/packets.h | 54 ++++++++++++++++++++- > tests/tunnel-push-pop.at | 10 ++++ > 6 files changed, 135 insertions(+), 12 deletions(-) > > diff --git a/datapath/linux/compat/include/linux/openvswitch.h > b/datapath/linux/compat/include/linux/openvswitch.h > index 7990638..2ae1797 100644 > --- a/datapath/linux/compat/include/linux/openvswitch.h > +++ b/datapath/linux/compat/include/linux/openvswitch.h > @@ -291,6 +291,7 @@ enum ovs_vport_attr { > enum { > OVS_VXLAN_EXT_UNSPEC, > OVS_VXLAN_EXT_GBP, /* Flag or __u32 */ > + OVS_VXLAN_EXT_GPE = 8, /* Flag or __u32 */ > __OVS_VXLAN_EXT_MAX, > }; > > diff --git a/include/openvswitch/automake.mk b/include/openvswitch/automake.mk > index c0e276f..699d9d7 100644 > --- a/include/openvswitch/automake.mk > +++ b/include/openvswitch/automake.mk > @@ -30,4 +30,3 @@ openvswitchinclude_HEADERS = \ > include/openvswitch/version.h \ > include/openvswitch/vconn.h \ > include/openvswitch/vlog.h > - > diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c > index 0651322..8ae8893 100644 > --- a/lib/netdev-native-tnl.c > +++ b/lib/netdev-native-tnl.c > @@ -499,6 +499,8 @@ netdev_vxlan_pop_header(struct dp_packet *packet) > struct flow_tnl *tnl = &md->tunnel; > struct vxlanhdr *vxh; > unsigned int hlen; > + ovs_be32 vx_flags; > + enum packet_type next_pt = PT_ETH; > > pkt_metadata_init_tnl(md); > if (VXLAN_HLEN > dp_packet_l4_size(packet)) { > @@ -510,18 +512,43 @@ netdev_vxlan_pop_header(struct dp_packet *packet) > goto err; > } > > - if (get_16aligned_be32(&vxh->vx_flags) != htonl(VXLAN_FLAGS) || > + vx_flags = get_16aligned_be32(&vxh->vx_flags); > + if (vx_flags & htonl(VXLAN_HF_GPE)) { > + vx_flags &= htonl(~VXLAN_GPE_USED_BITS); > + /* Drop the OAM packets */ > + if (vxh->vx_pge.flags & VXLAN_GPE_FLAGS_O) { > + goto err; > + } > + switch (vxh->vx_pge.next_protocol) { > + case VXLAN_GPE_NP_IPV4: > + next_pt = PT_IPV4; > + break; > + case VXLAN_GPE_NP_IPV6: > + next_pt = PT_IPV6; > + break; > + case VXLAN_GPE_NP_ETHERNET: > + next_pt = PT_ETH; > + break; > + default: > + goto err; > + } > + } > + > + if (vx_flags != htonl(VXLAN_FLAGS) || > (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)), > + ntohl(vx_flags), > ntohl(get_16aligned_be32(&vxh->vx_vni))); > goto err; > } > tnl->tun_id = htonll(ntohl(get_16aligned_be32(&vxh->vx_vni)) >> 8); > tnl->flags |= FLOW_TNL_F_KEY; > > - packet->packet_type = htonl(PT_ETH); > + packet->packet_type = htonl(next_pt); > dp_packet_reset_packet(packet, hlen + VXLAN_HLEN); > + if (next_pt != PT_ETH) { > + packet->l3_ofs = 0; > + } > > return packet; > err: > @@ -544,8 +571,30 @@ netdev_vxlan_build_header(const struct netdev *netdev, > > vxh = udp_build_header(tnl_cfg, data, params); > > - put_16aligned_be32(&vxh->vx_flags, htonl(VXLAN_FLAGS)); > - put_16aligned_be32(&vxh->vx_vni, > htonl(ntohll(params->flow->tunnel.tun_id) << 8)); > + if (tnl_cfg->exts & (1 << OVS_VXLAN_EXT_GPE)) { > + put_16aligned_be32(&vxh->vx_flags, htonl(VXLAN_FLAGS | > VXLAN_HF_GPE)); > + put_16aligned_be32(&vxh->vx_vni, > + htonl(ntohll(params->flow->tunnel.tun_id) << 8)); > + if (tnl_cfg->is_layer3) { > + switch (ntohs(params->flow->dl_type)) { > + case ETH_TYPE_IP: > + vxh->vx_pge.next_protocol = VXLAN_GPE_NP_IPV4; > + break; > + case ETH_TYPE_IPV6: > + vxh->vx_pge.next_protocol = VXLAN_GPE_NP_IPV6; > + break; > + case ETH_TYPE_TEB: > + vxh->vx_pge.next_protocol = VXLAN_GPE_NP_ETHERNET; > + break; > + } > + } else { > + vxh->vx_pge.next_protocol = VXLAN_GPE_NP_ETHERNET; > + } > + } else { > + put_16aligned_be32(&vxh->vx_flags, htonl(VXLAN_FLAGS)); > + put_16aligned_be32(&vxh->vx_vni, > + htonl(ntohll(params->flow->tunnel.tun_id) << 8)); > + } > > ovs_mutex_unlock(&dev->mutex); > data->header_len += sizeof *vxh; > diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c > index ba69461..d390f37 100644 > --- a/lib/netdev-vport.c > +++ b/lib/netdev-vport.c > @@ -414,6 +414,7 @@ set_tunnel_config(struct netdev *dev_, const struct smap > *args, char **errp) > uint16_t dst_proto = 0, src_proto = 0; > struct netdev_tunnel_config tnl_cfg; > struct smap_node *node; > + bool is_layer3 = false; > int err; > > has_csum = strstr(type, "gre") || strstr(type, "geneve") || > @@ -508,6 +509,9 @@ set_tunnel_config(struct netdev *dev_, const struct smap > *args, char **errp) > while (ext) { > if (!strcmp(type, "vxlan") && !strcmp(ext, "gbp")) { > tnl_cfg.exts |= (1 << OVS_VXLAN_EXT_GBP); > + } else if (!strcmp(type, "vxlan") && !strcmp(ext, "gpe")) { > + tnl_cfg.exts |= (1 << OVS_VXLAN_EXT_GPE); > + optional_layer3 = true; > } else { > ds_put_format(&errors, "%s: unknown extension '%s'\n", > name, ext); > @@ -520,16 +524,23 @@ set_tunnel_config(struct netdev *dev_, const struct > smap *args, char **errp) > } else if (!strcmp(node->key, "egress_pkt_mark")) { > tnl_cfg.egress_pkt_mark = strtoul(node->value, NULL, 10); > tnl_cfg.set_egress_pkt_mark = true; > - } else if (!strcmp(node->key, "layer3") && optional_layer3) { > + } else if (!strcmp(node->key, "layer3")) { > if (!strcmp(node->value, "true")) { > - tnl_cfg.is_layer3 = true; > + is_layer3 = true; > } > } else { > - ds_put_format(&errors, "%s: unknown %s argument '%s'\n", > - name, type, node->key); > + ds_put_format(&errors, "%s: unknown %s argument '%s'\n", name, > + type, node->key); > } > } > > + if (optional_layer3 && is_layer3) { > + tnl_cfg.is_layer3 = is_layer3; > + } else if (!optional_layer3 && is_layer3) { > + ds_put_format(&errors, "%s: unknown %s argument '%s'\n", > + name, type, "layer3"); > + } > + > if (!ipv6_addr_is_set(&tnl_cfg.ipv6_dst) && !tnl_cfg.ip_dst_flow) { > ds_put_format(&errors, > "%s: %s type requires valid 'remote_ip' argument\n", > @@ -660,7 +671,8 @@ get_tunnel_config(const struct netdev *dev, struct smap > *args) > smap_add(args, "csum", "true"); > } > > - if (tnl_cfg.is_layer3 && !strcmp("gre", type)) { > + if (tnl_cfg.is_layer3 && (!strcmp("gre", type) || > + !strcmp("vxlan", type))) { > smap_add(args, "layer3", "true"); > } > > diff --git a/lib/packets.h b/lib/packets.h > index d53e0b7..a00792d 100644 > --- a/lib/packets.h > +++ b/lib/packets.h > @@ -1174,12 +1174,64 @@ struct gre_base_hdr { > > /* VXLAN protocol header */ > struct vxlanhdr { > - ovs_16aligned_be32 vx_flags; > + union { > + ovs_16aligned_be32 vx_flags; /* VXLAN flags. */ > + struct { > + uint8_t flags; /* VXLAN GPE flags. */ > + uint8_t reserved_1; /* 16 bits reserved. */ > + uint8_t reserved_2; > + uint8_t next_protocol; /* Next Protocol field for VXLAN GPE. */ > + } vx_pge; > + }; > ovs_16aligned_be32 vx_vni; > }; > > #define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. > */ > > +/* > + * VXLAN Generic Protocol Extension (VXLAN_F_GPE): > + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ > + * |R|R|Ver|I|P|R|O| Reserved |Next Protocol | > + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ > + * | VXLAN Network Identifier (VNI) | Reserved | > + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ > + * > + * Ver = Version. Indicates VXLAN GPE protocol version. > + * > + * P = Next Protocol Bit. The P bit is set to indicate that the > + * Next Protocol field is present. > + * > + * O = OAM Flag Bit. The O bit is set to indicate that the packet > + * is an OAM packet. > + * > + * Next Protocol = This 8 bit field indicates the protocol header > + * immediately following the VXLAN GPE header. > + * > + * https://tools.ietf.org/html/draft-ietf-nvo3-vxlan-gpe-01 > + */ > + > +/* Fields in struct vxlanhdr.vx_gpe.flags */ > +#define VXLAN_GPE_FLAGS_VER 0x30 /* Version. */ > +#define VLXAN_GPE_FLAGS_P 0x04 /* Next Protocol Bit. */ > +#define VXLAN_GPE_FLAGS_O 0x01 /* OAM Bit. */ > + > +/* VXLAN-GPE header flags. */ > +#define VXLAN_HF_VER ((1U <<29) | (1U <<28)) > +#define VXLAN_HF_NP (1U <<26) > +#define VXLAN_HF_OAM (1U <<24) > + > +#define VXLAN_GPE_USED_BITS (VXLAN_HF_VER | VXLAN_HF_NP | VXLAN_HF_OAM | \ > + 0xff) > + > +/* VXLAN-GPE header Next Protocol. */ > +#define VXLAN_GPE_NP_IPV4 0x01 > +#define VXLAN_GPE_NP_IPV6 0x02 > +#define VXLAN_GPE_NP_ETHERNET 0x03 > +#define VXLAN_GPE_NP_NSH 0x04 > + > +#define VXLAN_F_GPE 0x4000 > +#define VXLAN_HF_GPE 0x04000000 > + > /* Input values for PACKET_TYPE macros have to be in host byte order. > * The _BE postfix indicates result is in network byte order. Otherwise > result > * is in host byte order. */ > diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at > index afa345e..e3aecb4 100644 > --- a/tests/tunnel-push-pop.at > +++ b/tests/tunnel-push-pop.at > @@ -16,6 +16,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:egress_pkt_mark=1234 > ofport_request=6\ > -- add-port int-br t6 -- set Interface t6 type=gre \ > options:remote_ip=1.1.2.92 options:key=456 > options:layer3=true ofport_request=7\ > + -- add-port int-br t7 -- set Interface t7 type=vxlan \ > + options:remote_ip=1.1.2.92 options:key=345 > options:exts=gpe ofport_request=8\ > ], [0]) > > AT_CHECK([ovs-appctl dpif/show], [0], [dnl > @@ -31,6 +33,7 @@ dummy@ovs-dummy: hit:0 missed:0 > t4 5/6081: (geneve: key=123, remote_ip=flow) > t5 6/6081: (geneve: egress_pkt_mark=1234, out_key=flow, > remote_ip=1.1.2.93) > t6 7/3: (gre: key=456, layer3=true, remote_ip=1.1.2.92) > + t7 8/4789: (vxlan: key=345, remote_ip=1.1.2.92) > ]) > > dnl First setup dummy interface IP address, then add the route > @@ -113,6 +116,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:b6,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(s > rc=1.1.2.88,dst=1.1.2.92,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0x8000000,vni=0 > x7b)),out_port(100)) > ]) > > +dnl Check VXLAN GPE tunnel push > +AT_CHECK([ovs-ofctl add-flow int-br action=8]) > +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy > 'in_port(2),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:01),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:b6,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(s > rc=1.1.2.88,dst=1.1.2.92,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0xc000003,vni=0 > x159)),out_port(100)) > +]) > + > dnl Check VXLAN tunnel push set tunnel id by flow and checksum > AT_CHECK([ovs-ofctl add-flow int-br "actions=set_tunnel:124,4"]) > AT_CHECK([ovs-appctl ofproto/trace ovs-dummy > 'in_port(2),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto= > 47,tos=0,ttl=64,frag=no)'], [0], [stdout]) > -- > 2.7.4 > > _______________________________________________ > dev mailing list > d...@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev