Message ID | 20230515082356.3471136-6-roid@nvidia.com |
---|---|
State | Changes Requested |
Delegated to: | Simon Horman |
Headers | show |
Series | Add vxlan gbp offload with TC | 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 Mon, May 15, 2023 at 11:23:54AM +0300, Roi Dayan via dev wrote: > From: Gavin Li <gavinl@nvidia.com> > > Add TC offload support for filtering vxlan tunnels with gbp option > > Signed-off-by: Gavin Li <gavinl@nvidia.com> > Reviewed-by: Gavi Teitz <gavi@nvidia.com> > Reviewed-by: Roi Dayan <roid@nvidia.com> Reviewed-by: Simon Horman <simon.horman@corigine.com>
On 15 May 2023, at 10:23, Roi Dayan wrote: > From: Gavin Li <gavinl@nvidia.com> > > Add TC offload support for filtering vxlan tunnels with gbp option > > Signed-off-by: Gavin Li <gavinl@nvidia.com> > Reviewed-by: Gavi Teitz <gavi@nvidia.com> > Reviewed-by: Roi Dayan <roid@nvidia.com> One comment below, the rest looks good to me. //Eelco > --- > include/linux/pkt_cls.h | 13 ++++++ > lib/netdev-offload-tc.c | 17 ++++++++ > lib/tc.c | 92 +++++++++++++++++++++++++++++++++++------ > lib/tc.h | 7 ++++ > 4 files changed, 117 insertions(+), 12 deletions(-) > > diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h > index a8cd8db5bf88..fb4a7ecea4cc 100644 > --- a/include/linux/pkt_cls.h > +++ b/include/linux/pkt_cls.h > @@ -273,6 +273,10 @@ enum { > * TCA_TUNNEL_KEY_ENC_OPTS_GENEVE > * attributes > */ > + TCA_FLOWER_KEY_ENC_OPTS_VXLAN, /* Nested > + * TCA_TUNNEL_KEY_ENC_OPTS_VXLAN > + * attributes > + */ > __TCA_FLOWER_KEY_ENC_OPTS_MAX, > }; > > @@ -290,6 +294,15 @@ enum { > #define TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX \ > (__TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX - 1) > > +enum { > + TCA_FLOWER_KEY_ENC_OPT_VXLAN_UNSPEC, > + TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP, /* u32 */ > + __TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX, > +}; > + > +#define TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX \ > + (__TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX - 1) > + > enum { > TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0), > TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1), > diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c > index 4f26dd8cca5f..1c97681bc92b 100644 > --- a/lib/netdev-offload-tc.c > +++ b/lib/netdev-offload-tc.c > @@ -1234,6 +1234,15 @@ parse_tc_flower_to_match(const struct netdev *netdev, > match_set_tun_tp_dst_masked(match, flower->key.tunnel.tp_dst, > flower->mask.tunnel.tp_dst); > } > + if (flower->mask.tunnel.gbp.id) { > + match_set_tun_gbp_id_masked(match, flower->key.tunnel.gbp.id, > + flower->mask.tunnel.gbp.id); > + } > + if (flower->mask.tunnel.gbp.flags) { > + match_set_tun_gbp_flags_masked(match, > + flower->key.tunnel.gbp.flags, > + flower->mask.tunnel.gbp.flags); > + } > > if (!strcmp(netdev_get_type(netdev), "geneve")) { > flower_tun_opt_to_match(match, flower); > @@ -2193,6 +2202,9 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, > flower.key.tunnel.ttl = tnl->ip_ttl; > flower.key.tunnel.tp_src = tnl->tp_src; > flower.key.tunnel.tp_dst = tnl->tp_dst; > + flower.key.tunnel.gbp.id = tnl->gbp_id; > + flower.key.tunnel.gbp.flags = tnl->gbp_flags; > + flower.key.tunnel.gbp.id_present = !!tnl_mask->gbp_id; > > flower.mask.tunnel.ipv4.ipv4_src = tnl_mask->ip_src; > flower.mask.tunnel.ipv4.ipv4_dst = tnl_mask->ip_dst; > @@ -2207,6 +2219,9 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, > * Degrading the flow down to exact match for now as a workaround. */ > flower.mask.tunnel.tp_dst = OVS_BE16_MAX; > flower.mask.tunnel.id = (tnl->flags & FLOW_TNL_F_KEY) ? tnl_mask->tun_id : 0; > + flower.mask.tunnel.gbp.id = tnl_mask->gbp_id; > + flower.mask.tunnel.gbp.flags = tnl_mask->gbp_flags; > + flower.mask.tunnel.gbp.id_present = !!tnl_mask->gbp_id; > > memset(&tnl_mask->ip_src, 0, sizeof tnl_mask->ip_src); > memset(&tnl_mask->ip_dst, 0, sizeof tnl_mask->ip_dst); > @@ -2218,6 +2233,8 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, > memset(&tnl_mask->tp_dst, 0, sizeof tnl_mask->tp_dst); > > memset(&tnl_mask->tun_id, 0, sizeof tnl_mask->tun_id); > + memset(&tnl_mask->gbp_id, 0, sizeof tnl_mask->gbp_id); > + memset(&tnl_mask->gbp_flags, 0, sizeof tnl_mask->gbp_flags); > tnl_mask->flags &= ~FLOW_TNL_F_KEY; > > /* XXX: This is wrong! We're ignoring DF and CSUM flags configuration > diff --git a/lib/tc.c b/lib/tc.c > index f2a02eee5e7c..3c335d5272db 100644 > --- a/lib/tc.c > +++ b/lib/tc.c > @@ -38,6 +38,7 @@ > #include "byte-order.h" > #include "netlink-socket.h" > #include "netlink.h" > +#include "odp-util.h" > #include "openvswitch/ofpbuf.h" > #include "openvswitch/util.h" > #include "openvswitch/vlog.h" > @@ -696,6 +697,38 @@ nl_parse_geneve_key(const struct nlattr *in_nlattr, > return 0; > } > > +static int > +nl_parse_vxlan_key(const struct nlattr *in_nlattr, > + struct tc_flower_tunnel *tunnel) > +{ > + const struct ofpbuf *msg; > + struct nlattr *nla; > + struct ofpbuf buf; > + uint32_t gbp_raw; > + size_t left; > + > + nl_attr_get_nested(in_nlattr, &buf); > + msg = &buf; > + > + NL_ATTR_FOR_EACH (nla, left, ofpbuf_at(msg, 0, 0), msg->size) { > + uint16_t type = nl_attr_type(nla); > + > + switch (type) { > + case TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP: > + gbp_raw = nl_attr_get_u32(nla); > + odp_decode_gbp_raw(gbp_raw, &tunnel->gbp.id, > + &tunnel->gbp.flags); > + tunnel->gbp.id_present = true; > + break; > + default: > + VLOG_ERR_RL(&error_rl, "failed to parse vxlan tun options"); > + return EINVAL; Should this not be a warning, and silently ignore it? What if a newer kernel reports an additional value, we do not need, it will break existing implementations. > + } > + } > + > + return 0; > +} > + > static int > nl_parse_flower_tunnel_opts(struct nlattr *options, > struct tc_flower_tunnel *tunnel) > @@ -718,6 +751,13 @@ nl_parse_flower_tunnel_opts(struct nlattr *options, > return err; > } > > + break; > + case TCA_FLOWER_KEY_ENC_OPTS_VXLAN: > + err = nl_parse_vxlan_key(nla, tunnel); > + if (err) { > + return err; > + } > + > break; > } > } > @@ -3432,23 +3472,18 @@ nl_msg_put_masked_value(struct ofpbuf *request, uint16_t type, > } > > static void > -nl_msg_put_flower_tunnel_opts(struct ofpbuf *request, uint16_t type, > - struct tc_flower_tunnel *tunnel) > +nl_msg_put_flower_geneve(struct ofpbuf *request, > + const struct tc_flower_tunnel *tunnel) > { > - struct tun_metadata *metadata = &tunnel->metadata; > - struct geneve_opt *opt; > - size_t outer, inner; > + const struct tun_metadata *metadata = &tunnel->metadata; > + const struct geneve_opt *opt; > int len, cnt = 0; > + size_t offset; > > len = metadata->present.len; > - if (!len) { > - return; > - } > - > - outer = nl_msg_start_nested(request, type); > while (len) { > opt = &metadata->opts.gnv[cnt]; > - inner = nl_msg_start_nested(request, TCA_FLOWER_KEY_ENC_OPTS_GENEVE); > + offset = nl_msg_start_nested(request, TCA_FLOWER_KEY_ENC_OPTS_GENEVE); > > nl_msg_put_be16(request, TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS, > opt->opt_class); > @@ -3459,8 +3494,41 @@ nl_msg_put_flower_tunnel_opts(struct ofpbuf *request, uint16_t type, > cnt += sizeof(struct geneve_opt) / 4 + opt->length; > len -= sizeof(struct geneve_opt) + opt->length * 4; > > - nl_msg_end_nested(request, inner); > + nl_msg_end_nested(request, offset); > } > +} > + > +static void > +nl_msg_put_flower_vxlan_tun_opts(struct ofpbuf *request, > + const struct tc_flower_tunnel *tunnel) > +{ > + uint32_t gbp_raw; > + size_t offset; > + > + if (!tunnel->gbp.id_present) { > + return; > + } > + > + gbp_raw = odp_encode_gbp_raw(tunnel->gbp.flags, tunnel->gbp.id); > + offset = nl_msg_start_nested_with_flag(request, > + TCA_FLOWER_KEY_ENC_OPTS_VXLAN); > + nl_msg_put_u32(request, TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP, gbp_raw); > + nl_msg_end_nested(request, offset); > +} > + > +static void > +nl_msg_put_flower_tunnel_opts(struct ofpbuf *request, uint16_t type, > + struct tc_flower_tunnel *tunnel) > +{ > + size_t outer; > + > + if (!tunnel->metadata.present.len && !tunnel->gbp.id_present) { > + return; > + } > + > + outer = nl_msg_start_nested(request, type); > + nl_msg_put_flower_geneve(request, tunnel); > + nl_msg_put_flower_vxlan_tun_opts(request, tunnel); > nl_msg_end_nested(request, outer); > } > > diff --git a/lib/tc.h b/lib/tc.h > index b9d449677ed9..95fff37b9b61 100644 > --- a/lib/tc.h > +++ b/lib/tc.h > @@ -105,6 +105,12 @@ struct tc_cookie { > size_t len; > }; > > +struct tc_tunnel_gbp { > + ovs_be16 id; > + uint8_t flags; > + bool id_present; > +}; > + > struct tc_flower_tunnel { > struct { > ovs_be32 ipv4_src; > @@ -118,6 +124,7 @@ struct tc_flower_tunnel { > uint8_t ttl; > ovs_be16 tp_src; > ovs_be16 tp_dst; > + struct tc_tunnel_gbp gbp; > ovs_be64 id; > struct tun_metadata metadata; > }; > -- > 2.38.0
On Fri, May 26, 2023 at 12:43:52PM +0200, Eelco Chaudron wrote: > > > On 15 May 2023, at 10:23, Roi Dayan wrote: > > > From: Gavin Li <gavinl@nvidia.com> > > > > Add TC offload support for filtering vxlan tunnels with gbp option > > > > Signed-off-by: Gavin Li <gavinl@nvidia.com> > > Reviewed-by: Gavi Teitz <gavi@nvidia.com> > > Reviewed-by: Roi Dayan <roid@nvidia.com> > > One comment below, the rest looks good to me. > > //Eelco Thanks Eelco. ... > > @@ -696,6 +697,38 @@ nl_parse_geneve_key(const struct nlattr *in_nlattr, > > return 0; > > } > > > > +static int > > +nl_parse_vxlan_key(const struct nlattr *in_nlattr, > > + struct tc_flower_tunnel *tunnel) > > +{ > > + const struct ofpbuf *msg; > > + struct nlattr *nla; > > + struct ofpbuf buf; > > + uint32_t gbp_raw; > > + size_t left; > > + > > + nl_attr_get_nested(in_nlattr, &buf); > > + msg = &buf; > > + > > + NL_ATTR_FOR_EACH (nla, left, ofpbuf_at(msg, 0, 0), msg->size) { > > + uint16_t type = nl_attr_type(nla); > > + > > + switch (type) { > > + case TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP: > > + gbp_raw = nl_attr_get_u32(nla); > > + odp_decode_gbp_raw(gbp_raw, &tunnel->gbp.id, > > + &tunnel->gbp.flags); > > + tunnel->gbp.id_present = true; > > + break; > > + default: > > + VLOG_ERR_RL(&error_rl, "failed to parse vxlan tun options"); > > + return EINVAL; > > Should this not be a warning, and silently ignore it? What if a newer kernel reports an additional value, we do not need, it will break existing implementations. Roi, could you address this and post v4?
On 26 May 2023, at 13:05, Simon Horman wrote: > On Fri, May 26, 2023 at 12:43:52PM +0200, Eelco Chaudron wrote: >> >> >> On 15 May 2023, at 10:23, Roi Dayan wrote: >> >>> From: Gavin Li <gavinl@nvidia.com> >>> >>> Add TC offload support for filtering vxlan tunnels with gbp option >>> >>> Signed-off-by: Gavin Li <gavinl@nvidia.com> >>> Reviewed-by: Gavi Teitz <gavi@nvidia.com> >>> Reviewed-by: Roi Dayan <roid@nvidia.com> >> >> One comment below, the rest looks good to me. >> >> //Eelco > > Thanks Eelco. Just to clarify, this is for patch 5 only. Have some more comments on 6 and 7. > ... > >>> @@ -696,6 +697,38 @@ nl_parse_geneve_key(const struct nlattr *in_nlattr, >>> return 0; >>> } >>> >>> +static int >>> +nl_parse_vxlan_key(const struct nlattr *in_nlattr, >>> + struct tc_flower_tunnel *tunnel) >>> +{ >>> + const struct ofpbuf *msg; >>> + struct nlattr *nla; >>> + struct ofpbuf buf; >>> + uint32_t gbp_raw; >>> + size_t left; >>> + >>> + nl_attr_get_nested(in_nlattr, &buf); >>> + msg = &buf; >>> + >>> + NL_ATTR_FOR_EACH (nla, left, ofpbuf_at(msg, 0, 0), msg->size) { >>> + uint16_t type = nl_attr_type(nla); >>> + >>> + switch (type) { >>> + case TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP: >>> + gbp_raw = nl_attr_get_u32(nla); >>> + odp_decode_gbp_raw(gbp_raw, &tunnel->gbp.id, >>> + &tunnel->gbp.flags); >>> + tunnel->gbp.id_present = true; >>> + break; >>> + default: >>> + VLOG_ERR_RL(&error_rl, "failed to parse vxlan tun options"); >>> + return EINVAL; >> >> Should this not be a warning, and silently ignore it? What if a newer kernel reports an additional value, we do not need, it will break existing implementations. > > Roi, > > could you address this and post v4?
diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h index a8cd8db5bf88..fb4a7ecea4cc 100644 --- a/include/linux/pkt_cls.h +++ b/include/linux/pkt_cls.h @@ -273,6 +273,10 @@ enum { * TCA_TUNNEL_KEY_ENC_OPTS_GENEVE * attributes */ + TCA_FLOWER_KEY_ENC_OPTS_VXLAN, /* Nested + * TCA_TUNNEL_KEY_ENC_OPTS_VXLAN + * attributes + */ __TCA_FLOWER_KEY_ENC_OPTS_MAX, }; @@ -290,6 +294,15 @@ enum { #define TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX \ (__TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX - 1) +enum { + TCA_FLOWER_KEY_ENC_OPT_VXLAN_UNSPEC, + TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP, /* u32 */ + __TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX, +}; + +#define TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX \ + (__TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX - 1) + enum { TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0), TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1), diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index 4f26dd8cca5f..1c97681bc92b 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -1234,6 +1234,15 @@ parse_tc_flower_to_match(const struct netdev *netdev, match_set_tun_tp_dst_masked(match, flower->key.tunnel.tp_dst, flower->mask.tunnel.tp_dst); } + if (flower->mask.tunnel.gbp.id) { + match_set_tun_gbp_id_masked(match, flower->key.tunnel.gbp.id, + flower->mask.tunnel.gbp.id); + } + if (flower->mask.tunnel.gbp.flags) { + match_set_tun_gbp_flags_masked(match, + flower->key.tunnel.gbp.flags, + flower->mask.tunnel.gbp.flags); + } if (!strcmp(netdev_get_type(netdev), "geneve")) { flower_tun_opt_to_match(match, flower); @@ -2193,6 +2202,9 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, flower.key.tunnel.ttl = tnl->ip_ttl; flower.key.tunnel.tp_src = tnl->tp_src; flower.key.tunnel.tp_dst = tnl->tp_dst; + flower.key.tunnel.gbp.id = tnl->gbp_id; + flower.key.tunnel.gbp.flags = tnl->gbp_flags; + flower.key.tunnel.gbp.id_present = !!tnl_mask->gbp_id; flower.mask.tunnel.ipv4.ipv4_src = tnl_mask->ip_src; flower.mask.tunnel.ipv4.ipv4_dst = tnl_mask->ip_dst; @@ -2207,6 +2219,9 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, * Degrading the flow down to exact match for now as a workaround. */ flower.mask.tunnel.tp_dst = OVS_BE16_MAX; flower.mask.tunnel.id = (tnl->flags & FLOW_TNL_F_KEY) ? tnl_mask->tun_id : 0; + flower.mask.tunnel.gbp.id = tnl_mask->gbp_id; + flower.mask.tunnel.gbp.flags = tnl_mask->gbp_flags; + flower.mask.tunnel.gbp.id_present = !!tnl_mask->gbp_id; memset(&tnl_mask->ip_src, 0, sizeof tnl_mask->ip_src); memset(&tnl_mask->ip_dst, 0, sizeof tnl_mask->ip_dst); @@ -2218,6 +2233,8 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, memset(&tnl_mask->tp_dst, 0, sizeof tnl_mask->tp_dst); memset(&tnl_mask->tun_id, 0, sizeof tnl_mask->tun_id); + memset(&tnl_mask->gbp_id, 0, sizeof tnl_mask->gbp_id); + memset(&tnl_mask->gbp_flags, 0, sizeof tnl_mask->gbp_flags); tnl_mask->flags &= ~FLOW_TNL_F_KEY; /* XXX: This is wrong! We're ignoring DF and CSUM flags configuration diff --git a/lib/tc.c b/lib/tc.c index f2a02eee5e7c..3c335d5272db 100644 --- a/lib/tc.c +++ b/lib/tc.c @@ -38,6 +38,7 @@ #include "byte-order.h" #include "netlink-socket.h" #include "netlink.h" +#include "odp-util.h" #include "openvswitch/ofpbuf.h" #include "openvswitch/util.h" #include "openvswitch/vlog.h" @@ -696,6 +697,38 @@ nl_parse_geneve_key(const struct nlattr *in_nlattr, return 0; } +static int +nl_parse_vxlan_key(const struct nlattr *in_nlattr, + struct tc_flower_tunnel *tunnel) +{ + const struct ofpbuf *msg; + struct nlattr *nla; + struct ofpbuf buf; + uint32_t gbp_raw; + size_t left; + + nl_attr_get_nested(in_nlattr, &buf); + msg = &buf; + + NL_ATTR_FOR_EACH (nla, left, ofpbuf_at(msg, 0, 0), msg->size) { + uint16_t type = nl_attr_type(nla); + + switch (type) { + case TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP: + gbp_raw = nl_attr_get_u32(nla); + odp_decode_gbp_raw(gbp_raw, &tunnel->gbp.id, + &tunnel->gbp.flags); + tunnel->gbp.id_present = true; + break; + default: + VLOG_ERR_RL(&error_rl, "failed to parse vxlan tun options"); + return EINVAL; + } + } + + return 0; +} + static int nl_parse_flower_tunnel_opts(struct nlattr *options, struct tc_flower_tunnel *tunnel) @@ -718,6 +751,13 @@ nl_parse_flower_tunnel_opts(struct nlattr *options, return err; } + break; + case TCA_FLOWER_KEY_ENC_OPTS_VXLAN: + err = nl_parse_vxlan_key(nla, tunnel); + if (err) { + return err; + } + break; } } @@ -3432,23 +3472,18 @@ nl_msg_put_masked_value(struct ofpbuf *request, uint16_t type, } static void -nl_msg_put_flower_tunnel_opts(struct ofpbuf *request, uint16_t type, - struct tc_flower_tunnel *tunnel) +nl_msg_put_flower_geneve(struct ofpbuf *request, + const struct tc_flower_tunnel *tunnel) { - struct tun_metadata *metadata = &tunnel->metadata; - struct geneve_opt *opt; - size_t outer, inner; + const struct tun_metadata *metadata = &tunnel->metadata; + const struct geneve_opt *opt; int len, cnt = 0; + size_t offset; len = metadata->present.len; - if (!len) { - return; - } - - outer = nl_msg_start_nested(request, type); while (len) { opt = &metadata->opts.gnv[cnt]; - inner = nl_msg_start_nested(request, TCA_FLOWER_KEY_ENC_OPTS_GENEVE); + offset = nl_msg_start_nested(request, TCA_FLOWER_KEY_ENC_OPTS_GENEVE); nl_msg_put_be16(request, TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS, opt->opt_class); @@ -3459,8 +3494,41 @@ nl_msg_put_flower_tunnel_opts(struct ofpbuf *request, uint16_t type, cnt += sizeof(struct geneve_opt) / 4 + opt->length; len -= sizeof(struct geneve_opt) + opt->length * 4; - nl_msg_end_nested(request, inner); + nl_msg_end_nested(request, offset); } +} + +static void +nl_msg_put_flower_vxlan_tun_opts(struct ofpbuf *request, + const struct tc_flower_tunnel *tunnel) +{ + uint32_t gbp_raw; + size_t offset; + + if (!tunnel->gbp.id_present) { + return; + } + + gbp_raw = odp_encode_gbp_raw(tunnel->gbp.flags, tunnel->gbp.id); + offset = nl_msg_start_nested_with_flag(request, + TCA_FLOWER_KEY_ENC_OPTS_VXLAN); + nl_msg_put_u32(request, TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP, gbp_raw); + nl_msg_end_nested(request, offset); +} + +static void +nl_msg_put_flower_tunnel_opts(struct ofpbuf *request, uint16_t type, + struct tc_flower_tunnel *tunnel) +{ + size_t outer; + + if (!tunnel->metadata.present.len && !tunnel->gbp.id_present) { + return; + } + + outer = nl_msg_start_nested(request, type); + nl_msg_put_flower_geneve(request, tunnel); + nl_msg_put_flower_vxlan_tun_opts(request, tunnel); nl_msg_end_nested(request, outer); } diff --git a/lib/tc.h b/lib/tc.h index b9d449677ed9..95fff37b9b61 100644 --- a/lib/tc.h +++ b/lib/tc.h @@ -105,6 +105,12 @@ struct tc_cookie { size_t len; }; +struct tc_tunnel_gbp { + ovs_be16 id; + uint8_t flags; + bool id_present; +}; + struct tc_flower_tunnel { struct { ovs_be32 ipv4_src; @@ -118,6 +124,7 @@ struct tc_flower_tunnel { uint8_t ttl; ovs_be16 tp_src; ovs_be16 tp_dst; + struct tc_tunnel_gbp gbp; ovs_be64 id; struct tun_metadata metadata; };