Message ID | 20220207172426.813734-4-elibr@nvidia.com |
---|---|
State | Deferred |
Headers | show |
Series | Support geneve offloads | expand |
Context | Check | Description |
---|---|---|
ovsrobot/apply-robot | success | apply and check: success |
ovsrobot/github-robot-_Build_and_Test | success | github build: passed |
ovsrobot/intel-ovs-compilation | success | test: success |
On 2/7/22 18:24, Eli Britstein wrote: > Add support for matching on geneve header. > > Signed-off-by: Eli Britstein <elibr@nvidia.com> > Reviewed-by: Nir Anteby <nanteby@nvidia.com> > Acked-by: Michael Santana <msantana@redhat.com> > --- > NEWS | 2 ++ > lib/netdev-offload-dpdk.c | 58 +++++++++++++++++++++++++++++++++++++++ > 2 files changed, 60 insertions(+) > > diff --git a/NEWS b/NEWS > index e1c48f3a1..41a80d127 100644 > --- a/NEWS > +++ b/NEWS > @@ -29,6 +29,8 @@ v2.17.0 - xx xxx xxxx > * Add support for DPDK 21.11. > * Forbid use of DPDK multiprocess feature. > * Add support for running threads on cores >= RTE_MAX_LCORE. > + * Add hardware offload support for GENEVE flows (experimental). > + Available only if DPDK experimantal APIs enabled during the build. > - Python: > * For SSL support, the use of the pyOpenSSL library has been replaced > with the native 'ssl' module. > diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c > index edd4e009d..0303bd2df 100644 > --- a/lib/netdev-offload-dpdk.c > +++ b/lib/netdev-offload-dpdk.c > @@ -638,6 +638,24 @@ dump_flow_pattern(struct ds *s, > ntohl(*key_spec), ntohl(*key_mask), 0); > } > ds_put_cstr(s, "/ "); > + } else if (item->type == RTE_FLOW_ITEM_TYPE_GENEVE) { > + const struct rte_flow_item_geneve *geneve_spec = item->spec; > + const struct rte_flow_item_geneve *geneve_mask = item->mask; > + ovs_be32 spec_vni, mask_vni; > + > + ds_put_cstr(s, "geneve "); > + if (geneve_spec) { > + if (!geneve_mask) { > + geneve_mask = &rte_flow_item_geneve_mask; > + } > + spec_vni = get_unaligned_be32(ALIGNED_CAST(ovs_be32 *, > + geneve_spec->vni)); > + mask_vni = get_unaligned_be32(ALIGNED_CAST(ovs_be32 *, > + geneve_mask->vni)); > + DUMP_PATTERN_ITEM(geneve_mask->vni, false, "vni", "%"PRIu32, > + ntohl(spec_vni) >> 8, ntohl(mask_vni) >> 8, 0); > + } > + ds_put_cstr(s, "/ "); > } else { > ds_put_format(s, "unknown rte flow pattern (%d)\n", item->type); > } > @@ -1351,6 +1369,44 @@ parse_gre_match(struct flow_patterns *patterns, > return 0; > } > > +static int > +parse_geneve_match(struct flow_patterns *patterns, > + struct match *match) > +{ > + struct rte_flow_item_geneve *geneve_spec, *geneve_mask; > + struct flow *consumed_masks; > + int ret; > + > + ret = parse_tnl_ip_match(patterns, match, IPPROTO_UDP); > + if (ret) { > + return -1; > + } > + parse_tnl_udp_match(patterns, match); > + > + consumed_masks = &match->wc.masks; > + /* GENEVE */ > + geneve_spec = xzalloc(sizeof *geneve_spec); > + geneve_mask = xzalloc(sizeof *geneve_mask); > + > + put_unaligned_be32(ALIGNED_CAST(ovs_be32 *, geneve_spec->vni), > + htonl(ntohll(match->flow.tunnel.tun_id) << 8)); > + put_unaligned_be32(ALIGNED_CAST(ovs_be32 *, geneve_mask->vni), > + htonl(ntohll(match->wc.masks.tunnel.tun_id) << 8)); > + > + consumed_masks->tunnel.tun_id = 0; > + consumed_masks->tunnel.flags = 0; > + /* tunnel.metadata.present.len value indicates the number of > + * options, it's mask does not indicate any match on the packet, > + * thus masked. I'm not sure I get that. Options are part of the geneve header, so if the match is requested, we have to match on them. And there is a special item for them - RTE_FLOW_ITEM_TYPE_GENEVE_OPT, which, I think, should be used in this patch. It also not clear why flags are cleared without handling them. Best regards, Ilya Maximets.
>-----Original Message----- >From: Ilya Maximets <i.maximets@ovn.org> >Sent: Wednesday, May 4, 2022 2:44 PM >To: Eli Britstein <elibr@nvidia.com>; dev@openvswitch.org >Cc: i.maximets@ovn.org; Gaetan Rivet <gaetanr@nvidia.com>; >msantana@redhat.com; Nir Anteby <nanteby@nvidia.com> >Subject: Re: [PATCH V2 3/3] netdev-offload-dpdk: Add geneve header pattern >match > >External email: Use caution opening links or attachments > > >On 2/7/22 18:24, Eli Britstein wrote: >> Add support for matching on geneve header. >> >> Signed-off-by: Eli Britstein <elibr@nvidia.com> >> Reviewed-by: Nir Anteby <nanteby@nvidia.com> >> Acked-by: Michael Santana <msantana@redhat.com> >> --- >> NEWS | 2 ++ >> lib/netdev-offload-dpdk.c | 58 >> +++++++++++++++++++++++++++++++++++++++ >> 2 files changed, 60 insertions(+) >> >> diff --git a/NEWS b/NEWS >> index e1c48f3a1..41a80d127 100644 >> --- a/NEWS >> +++ b/NEWS >> @@ -29,6 +29,8 @@ v2.17.0 - xx xxx xxxx >> * Add support for DPDK 21.11. >> * Forbid use of DPDK multiprocess feature. >> * Add support for running threads on cores >= RTE_MAX_LCORE. >> + * Add hardware offload support for GENEVE flows (experimental). >> + Available only if DPDK experimantal APIs enabled during the build. >> - Python: >> * For SSL support, the use of the pyOpenSSL library has been replaced >> with the native 'ssl' module. >> diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c >> index edd4e009d..0303bd2df 100644 >> --- a/lib/netdev-offload-dpdk.c >> +++ b/lib/netdev-offload-dpdk.c >> @@ -638,6 +638,24 @@ dump_flow_pattern(struct ds *s, >> ntohl(*key_spec), ntohl(*key_mask), 0); >> } >> ds_put_cstr(s, "/ "); >> + } else if (item->type == RTE_FLOW_ITEM_TYPE_GENEVE) { >> + const struct rte_flow_item_geneve *geneve_spec = item->spec; >> + const struct rte_flow_item_geneve *geneve_mask = item->mask; >> + ovs_be32 spec_vni, mask_vni; >> + >> + ds_put_cstr(s, "geneve "); >> + if (geneve_spec) { >> + if (!geneve_mask) { >> + geneve_mask = &rte_flow_item_geneve_mask; >> + } >> + spec_vni = get_unaligned_be32(ALIGNED_CAST(ovs_be32 *, >> + geneve_spec->vni)); >> + mask_vni = get_unaligned_be32(ALIGNED_CAST(ovs_be32 *, >> + geneve_mask->vni)); >> + DUMP_PATTERN_ITEM(geneve_mask->vni, false, "vni", "%"PRIu32, >> + ntohl(spec_vni) >> 8, ntohl(mask_vni) >> 8, 0); >> + } >> + ds_put_cstr(s, "/ "); >> } else { >> ds_put_format(s, "unknown rte flow pattern (%d)\n", item->type); >> } >> @@ -1351,6 +1369,44 @@ parse_gre_match(struct flow_patterns >*patterns, >> return 0; >> } >> >> +static int >> +parse_geneve_match(struct flow_patterns *patterns, >> + struct match *match) { >> + struct rte_flow_item_geneve *geneve_spec, *geneve_mask; >> + struct flow *consumed_masks; >> + int ret; >> + >> + ret = parse_tnl_ip_match(patterns, match, IPPROTO_UDP); >> + if (ret) { >> + return -1; >> + } >> + parse_tnl_udp_match(patterns, match); >> + >> + consumed_masks = &match->wc.masks; >> + /* GENEVE */ >> + geneve_spec = xzalloc(sizeof *geneve_spec); >> + geneve_mask = xzalloc(sizeof *geneve_mask); >> + >> + put_unaligned_be32(ALIGNED_CAST(ovs_be32 *, geneve_spec->vni), >> + htonl(ntohll(match->flow.tunnel.tun_id) << 8)); >> + put_unaligned_be32(ALIGNED_CAST(ovs_be32 *, geneve_mask->vni), >> + htonl(ntohll(match->wc.masks.tunnel.tun_id) << >> + 8)); >> + >> + consumed_masks->tunnel.tun_id = 0; >> + consumed_masks->tunnel.flags = 0; >> + /* tunnel.metadata.present.len value indicates the number of >> + * options, it's mask does not indicate any match on the packet, >> + * thus masked. > >I'm not sure I get that. Options are part of the geneve header, so if the match >is requested, we have to match on them. And there is a special item for them >- RTE_FLOW_ITEM_TYPE_GENEVE_OPT, which, I think, should be used in this >patch. It is correct dpdk supports this flow item. However, it doesn't support options in 'struct rte_flow_restore_info'. Therefore, it currently cannot be supported. Options are *optional*. This patch-set can support geneve w/o options only. If there are options to be matched, they are not cleared from the masks, and the parsing fails. > >It also not clear why flags are cleared without handling them. There are no flags field in geneve header, maybe except OAM. I can add it after completing the previous comment. > >Best regards, Ilya Maximets.
Eli, I'm trying to understand options handling during Geneve encap/decap offload. 1. This patchset will allow decap offload for Geneve w/o options only. I do not think that covers important use cases for Geneve. Geneve was meant to be used with options. Why is the limitation of not having options support in struct rte_flow_restore_info gating the offload design? 2. I have not seen companion patch support for encap offload for Geneve. Is similar restriction of not offloading Geneve w/ options apply on the encap offload? Hemal On Sat, May 7, 2022 at 10:07 PM Eli Britstein via dev < ovs-dev@openvswitch.org> wrote: > > > >-----Original Message----- > >From: Ilya Maximets <i.maximets@ovn.org> > >Sent: Wednesday, May 4, 2022 2:44 PM > >To: Eli Britstein <elibr@nvidia.com>; dev@openvswitch.org > >Cc: i.maximets@ovn.org; Gaetan Rivet <gaetanr@nvidia.com>; > >msantana@redhat.com; Nir Anteby <nanteby@nvidia.com> > >Subject: Re: [PATCH V2 3/3] netdev-offload-dpdk: Add geneve header pattern > >match > > > >External email: Use caution opening links or attachments > > > > > >On 2/7/22 18:24, Eli Britstein wrote: > >> Add support for matching on geneve header. > >> > >> Signed-off-by: Eli Britstein <elibr@nvidia.com> > >> Reviewed-by: Nir Anteby <nanteby@nvidia.com> > >> Acked-by: Michael Santana <msantana@redhat.com> > >> --- > >> NEWS | 2 ++ > >> lib/netdev-offload-dpdk.c | 58 > >> +++++++++++++++++++++++++++++++++++++++ > >> 2 files changed, 60 insertions(+) > >> > >> diff --git a/NEWS b/NEWS > >> index e1c48f3a1..41a80d127 100644 > >> --- a/NEWS > >> +++ b/NEWS > >> @@ -29,6 +29,8 @@ v2.17.0 - xx xxx xxxx > >> * Add support for DPDK 21.11. > >> * Forbid use of DPDK multiprocess feature. > >> * Add support for running threads on cores >= RTE_MAX_LCORE. > >> + * Add hardware offload support for GENEVE flows (experimental). > >> + Available only if DPDK experimantal APIs enabled during the > build. > >> - Python: > >> * For SSL support, the use of the pyOpenSSL library has been > replaced > >> with the native 'ssl' module. > >> diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c > >> index edd4e009d..0303bd2df 100644 > >> --- a/lib/netdev-offload-dpdk.c > >> +++ b/lib/netdev-offload-dpdk.c > >> @@ -638,6 +638,24 @@ dump_flow_pattern(struct ds *s, > >> ntohl(*key_spec), ntohl(*key_mask), 0); > >> } > >> ds_put_cstr(s, "/ "); > >> + } else if (item->type == RTE_FLOW_ITEM_TYPE_GENEVE) { > >> + const struct rte_flow_item_geneve *geneve_spec = item->spec; > >> + const struct rte_flow_item_geneve *geneve_mask = item->mask; > >> + ovs_be32 spec_vni, mask_vni; > >> + > >> + ds_put_cstr(s, "geneve "); > >> + if (geneve_spec) { > >> + if (!geneve_mask) { > >> + geneve_mask = &rte_flow_item_geneve_mask; > >> + } > >> + spec_vni = get_unaligned_be32(ALIGNED_CAST(ovs_be32 *, > >> + > geneve_spec->vni)); > >> + mask_vni = get_unaligned_be32(ALIGNED_CAST(ovs_be32 *, > >> + > geneve_mask->vni)); > >> + DUMP_PATTERN_ITEM(geneve_mask->vni, false, "vni", > "%"PRIu32, > >> + ntohl(spec_vni) >> 8, ntohl(mask_vni) >> > 8, 0); > >> + } > >> + ds_put_cstr(s, "/ "); > >> } else { > >> ds_put_format(s, "unknown rte flow pattern (%d)\n", > item->type); > >> } > >> @@ -1351,6 +1369,44 @@ parse_gre_match(struct flow_patterns > >*patterns, > >> return 0; > >> } > >> > >> +static int > >> +parse_geneve_match(struct flow_patterns *patterns, > >> + struct match *match) { > >> + struct rte_flow_item_geneve *geneve_spec, *geneve_mask; > >> + struct flow *consumed_masks; > >> + int ret; > >> + > >> + ret = parse_tnl_ip_match(patterns, match, IPPROTO_UDP); > >> + if (ret) { > >> + return -1; > >> + } > >> + parse_tnl_udp_match(patterns, match); > >> + > >> + consumed_masks = &match->wc.masks; > >> + /* GENEVE */ > >> + geneve_spec = xzalloc(sizeof *geneve_spec); > >> + geneve_mask = xzalloc(sizeof *geneve_mask); > >> + > >> + put_unaligned_be32(ALIGNED_CAST(ovs_be32 *, geneve_spec->vni), > >> + htonl(ntohll(match->flow.tunnel.tun_id) << 8)); > >> + put_unaligned_be32(ALIGNED_CAST(ovs_be32 *, geneve_mask->vni), > >> + htonl(ntohll(match->wc.masks.tunnel.tun_id) << > >> + 8)); > >> + > >> + consumed_masks->tunnel.tun_id = 0; > >> + consumed_masks->tunnel.flags = 0; > >> + /* tunnel.metadata.present.len value indicates the number of > >> + * options, it's mask does not indicate any match on the packet, > >> + * thus masked. > > > >I'm not sure I get that. Options are part of the geneve header, so if > the match > >is requested, we have to match on them. And there is a special item for > them > >- RTE_FLOW_ITEM_TYPE_GENEVE_OPT, which, I think, should be used in this > >patch. > It is correct dpdk supports this flow item. However, it doesn't support > options in 'struct rte_flow_restore_info'. Therefore, it currently cannot > be supported. Options are *optional*. This patch-set can support geneve w/o > options only. If there are options to be matched, they are not cleared from > the masks, and the parsing fails. > > > >It also not clear why flags are cleared without handling them. > There are no flags field in geneve header, maybe except OAM. I can add it > after completing the previous comment. > > > >Best regards, Ilya Maximets. > _______________________________________________ > dev mailing list > dev@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev >
1. The focus was VXLAN. Need to enhance DPDK to support it. If this is not important, let’s abandon this patch-set until DPDK is enhanced. 2. There is no need. DPDK has only specific encaps for VXLAN/NVGRE. Other encaps are done only by “RAW”. In OVS VXLAN is used if applicable, and fallback to RAW. Geneve is under this category. From: Hemal Shah <hemal.shah@broadcom.com> Sent: Wednesday, May 18, 2022 6:02 PM To: Eli Britstein <elibr@nvidia.com> Cc: Ilya Maximets <i.maximets@ovn.org>; dev@openvswitch.org Subject: Re: [ovs-dev] [PATCH V2 3/3] netdev-offload-dpdk: Add geneve header pattern match Eli, I'm trying to understand options handling during Geneve encap/decap offload. 1. This patchset will allow decap offload for Geneve w/o options only. I do not think that covers important use cases for Geneve. Geneve was meant to be used with options. Why is the limitation of not having options support in struct rte_flow_restore_info gating the offload design? 2. I have not seen companion patch support for encap offload for Geneve. Is similar restriction of not offloading Geneve w/ options apply on the encap offload? Hemal On Sat, May 7, 2022 at 10:07 PM Eli Britstein via dev <ovs-dev@openvswitch.org<mailto:ovs-dev@openvswitch.org>> wrote: >-----Original Message----- >From: Ilya Maximets <i.maximets@ovn.org<mailto:i.maximets@ovn.org>> >Sent: Wednesday, May 4, 2022 2:44 PM >To: Eli Britstein <elibr@nvidia.com<mailto:elibr@nvidia.com>>; dev@openvswitch.org<mailto:dev@openvswitch.org> >Cc: i.maximets@ovn.org<mailto:i.maximets@ovn.org>; Gaetan Rivet <gaetanr@nvidia.com<mailto:gaetanr@nvidia.com>>; >msantana@redhat.com<mailto:msantana@redhat.com>; Nir Anteby <nanteby@nvidia.com<mailto:nanteby@nvidia.com>> >Subject: Re: [PATCH V2 3/3] netdev-offload-dpdk: Add geneve header pattern >match > >External email: Use caution opening links or attachments > > >On 2/7/22 18:24, Eli Britstein wrote: >> Add support for matching on geneve header. >> >> Signed-off-by: Eli Britstein <elibr@nvidia.com<mailto:elibr@nvidia.com>> >> Reviewed-by: Nir Anteby <nanteby@nvidia.com<mailto:nanteby@nvidia.com>> >> Acked-by: Michael Santana <msantana@redhat.com<mailto:msantana@redhat.com>> >> --- >> NEWS | 2 ++ >> lib/netdev-offload-dpdk.c | 58 >> +++++++++++++++++++++++++++++++++++++++ >> 2 files changed, 60 insertions(+) >> >> diff --git a/NEWS b/NEWS >> index e1c48f3a1..41a80d127 100644 >> --- a/NEWS >> +++ b/NEWS >> @@ -29,6 +29,8 @@ v2.17.0 - xx xxx xxxx >> * Add support for DPDK 21.11. >> * Forbid use of DPDK multiprocess feature. >> * Add support for running threads on cores >= RTE_MAX_LCORE. >> + * Add hardware offload support for GENEVE flows (experimental). >> + Available only if DPDK experimantal APIs enabled during the build. >> - Python: >> * For SSL support, the use of the pyOpenSSL library has been replaced >> with the native 'ssl' module. >> diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c >> index edd4e009d..0303bd2df 100644 >> --- a/lib/netdev-offload-dpdk.c >> +++ b/lib/netdev-offload-dpdk.c >> @@ -638,6 +638,24 @@ dump_flow_pattern(struct ds *s, >> ntohl(*key_spec), ntohl(*key_mask), 0); >> } >> ds_put_cstr(s, "/ "); >> + } else if (item->type == RTE_FLOW_ITEM_TYPE_GENEVE) { >> + const struct rte_flow_item_geneve *geneve_spec = item->spec; >> + const struct rte_flow_item_geneve *geneve_mask = item->mask; >> + ovs_be32 spec_vni, mask_vni; >> + >> + ds_put_cstr(s, "geneve "); >> + if (geneve_spec) { >> + if (!geneve_mask) { >> + geneve_mask = &rte_flow_item_geneve_mask; >> + } >> + spec_vni = get_unaligned_be32(ALIGNED_CAST(ovs_be32 *, >> + geneve_spec->vni)); >> + mask_vni = get_unaligned_be32(ALIGNED_CAST(ovs_be32 *, >> + geneve_mask->vni)); >> + DUMP_PATTERN_ITEM(geneve_mask->vni, false, "vni", "%"PRIu32, >> + ntohl(spec_vni) >> 8, ntohl(mask_vni) >> 8, 0); >> + } >> + ds_put_cstr(s, "/ "); >> } else { >> ds_put_format(s, "unknown rte flow pattern (%d)\n", item->type); >> } >> @@ -1351,6 +1369,44 @@ parse_gre_match(struct flow_patterns >*patterns, >> return 0; >> } >> >> +static int >> +parse_geneve_match(struct flow_patterns *patterns, >> + struct match *match) { >> + struct rte_flow_item_geneve *geneve_spec, *geneve_mask; >> + struct flow *consumed_masks; >> + int ret; >> + >> + ret = parse_tnl_ip_match(patterns, match, IPPROTO_UDP); >> + if (ret) { >> + return -1; >> + } >> + parse_tnl_udp_match(patterns, match); >> + >> + consumed_masks = &match->wc.masks; >> + /* GENEVE */ >> + geneve_spec = xzalloc(sizeof *geneve_spec); >> + geneve_mask = xzalloc(sizeof *geneve_mask); >> + >> + put_unaligned_be32(ALIGNED_CAST(ovs_be32 *, geneve_spec->vni), >> + htonl(ntohll(match->flow.tunnel.tun_id) << 8)); >> + put_unaligned_be32(ALIGNED_CAST(ovs_be32 *, geneve_mask->vni), >> + htonl(ntohll(match->wc.masks.tunnel.tun_id) << >> + 8)); >> + >> + consumed_masks->tunnel.tun_id = 0; >> + consumed_masks->tunnel.flags = 0; >> + /* tunnel.metadata.present.len value indicates the number of >> + * options, it's mask does not indicate any match on the packet, >> + * thus masked. > >I'm not sure I get that. Options are part of the geneve header, so if the match >is requested, we have to match on them. And there is a special item for them >- RTE_FLOW_ITEM_TYPE_GENEVE_OPT, which, I think, should be used in this >patch. It is correct dpdk supports this flow item. However, it doesn't support options in 'struct rte_flow_restore_info'. Therefore, it currently cannot be supported. Options are *optional*. This patch-set can support geneve w/o options only. If there are options to be matched, they are not cleared from the masks, and the parsing fails. > >It also not clear why flags are cleared without handling them. There are no flags field in geneve header, maybe except OAM. I can add it after completing the previous comment. > >Best regards, Ilya Maximets.
diff --git a/NEWS b/NEWS index e1c48f3a1..41a80d127 100644 --- a/NEWS +++ b/NEWS @@ -29,6 +29,8 @@ v2.17.0 - xx xxx xxxx * Add support for DPDK 21.11. * Forbid use of DPDK multiprocess feature. * Add support for running threads on cores >= RTE_MAX_LCORE. + * Add hardware offload support for GENEVE flows (experimental). + Available only if DPDK experimantal APIs enabled during the build. - Python: * For SSL support, the use of the pyOpenSSL library has been replaced with the native 'ssl' module. diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index edd4e009d..0303bd2df 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -638,6 +638,24 @@ dump_flow_pattern(struct ds *s, ntohl(*key_spec), ntohl(*key_mask), 0); } ds_put_cstr(s, "/ "); + } else if (item->type == RTE_FLOW_ITEM_TYPE_GENEVE) { + const struct rte_flow_item_geneve *geneve_spec = item->spec; + const struct rte_flow_item_geneve *geneve_mask = item->mask; + ovs_be32 spec_vni, mask_vni; + + ds_put_cstr(s, "geneve "); + if (geneve_spec) { + if (!geneve_mask) { + geneve_mask = &rte_flow_item_geneve_mask; + } + spec_vni = get_unaligned_be32(ALIGNED_CAST(ovs_be32 *, + geneve_spec->vni)); + mask_vni = get_unaligned_be32(ALIGNED_CAST(ovs_be32 *, + geneve_mask->vni)); + DUMP_PATTERN_ITEM(geneve_mask->vni, false, "vni", "%"PRIu32, + ntohl(spec_vni) >> 8, ntohl(mask_vni) >> 8, 0); + } + ds_put_cstr(s, "/ "); } else { ds_put_format(s, "unknown rte flow pattern (%d)\n", item->type); } @@ -1351,6 +1369,44 @@ parse_gre_match(struct flow_patterns *patterns, return 0; } +static int +parse_geneve_match(struct flow_patterns *patterns, + struct match *match) +{ + struct rte_flow_item_geneve *geneve_spec, *geneve_mask; + struct flow *consumed_masks; + int ret; + + ret = parse_tnl_ip_match(patterns, match, IPPROTO_UDP); + if (ret) { + return -1; + } + parse_tnl_udp_match(patterns, match); + + consumed_masks = &match->wc.masks; + /* GENEVE */ + geneve_spec = xzalloc(sizeof *geneve_spec); + geneve_mask = xzalloc(sizeof *geneve_mask); + + put_unaligned_be32(ALIGNED_CAST(ovs_be32 *, geneve_spec->vni), + htonl(ntohll(match->flow.tunnel.tun_id) << 8)); + put_unaligned_be32(ALIGNED_CAST(ovs_be32 *, geneve_mask->vni), + htonl(ntohll(match->wc.masks.tunnel.tun_id) << 8)); + + consumed_masks->tunnel.tun_id = 0; + consumed_masks->tunnel.flags = 0; + /* tunnel.metadata.present.len value indicates the number of + * options, it's mask does not indicate any match on the packet, + * thus masked. + */ + memset(&consumed_masks->tunnel.metadata.present, 0, + sizeof consumed_masks->tunnel.metadata.present); + + add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_GENEVE, geneve_spec, + geneve_mask, NULL); + return 0; +} + static int OVS_UNUSED parse_flow_tnl_match(struct netdev *tnldev, struct flow_patterns *patterns, @@ -1366,6 +1422,8 @@ parse_flow_tnl_match(struct netdev *tnldev, if (!strcmp(netdev_get_type(tnldev), "vxlan")) { ret = parse_vxlan_match(patterns, match); + } else if (!strcmp(netdev_get_type(tnldev), "geneve")) { + ret = parse_geneve_match(patterns, match); } else if (!strcmp(netdev_get_type(tnldev), "gre")) { ret = parse_gre_match(patterns, match);