Message ID | b2c35c5b99eec4a18eb6d8f723c3298bdc009ea1.1728907640.git.echaudro@redhat.com |
---|---|
State | New |
Delegated to: | Simon Horman |
Headers | show |
Series | Add missing TC flower tunnel match and encap flags. | expand |
Context | Check | Description |
---|---|---|
ovsrobot/apply-robot | success | apply and check: success |
ovsrobot/github-robot-_Build_and_Test | success | github build: passed |
On 14/10/2024 15:09, Eelco Chaudron wrote: > This patch checks to see if the TCA_FLOWER_KEY_ENC_FLAGS key is supported. > > Signed-off-by: Eelco Chaudron <echaudro@redhat.com> > --- > acinclude.m4 | 6 +++--- > include/linux/pkt_cls.h | 28 +++++++++++++++++++++++- > lib/netdev-offload-tc.c | 47 ++++++++++++++++++++++++++++++++++++++++- > lib/tc.c | 29 ++++++++++++++++++++++--- > lib/tc.h | 15 ++++++++++--- > 5 files changed, 114 insertions(+), 11 deletions(-) > > diff --git a/acinclude.m4 b/acinclude.m4 > index 1ace70c92..f4cb4a146 100644 > --- a/acinclude.m4 > +++ b/acinclude.m4 > @@ -163,10 +163,10 @@ dnl Configure Linux tc compat. > AC_DEFUN([OVS_CHECK_LINUX_TC], [ > AC_COMPILE_IFELSE([ > AC_LANG_PROGRAM([#include <linux/pkt_cls.h>], [ > - int x = TCA_ACT_FLAGS_SKIP_HW; > + int x = TCA_FLOWER_KEY_ENC_FLAGS_MASK; > ])], > - [AC_DEFINE([HAVE_TCA_ACT_FLAGS_SKIP_HW], [1], > - [Define to 1 if TCA_ACT_FLAGS_SKIP_HW is available.])]) > + [AC_DEFINE([HAVE_TCA_FLOWER_KEY_ENC_FLAGS_MASK], [1], > + [Define to 1 if TCA_FLOWER_KEY_ENC_FLAGS_MASK is available.])]) > > AC_CHECK_MEMBERS([struct tcf_t.firstuse], [], [], [#include <linux/pkt_cls.h>]) > > diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h > index fb4a7ecea..5890dc157 100644 > --- a/include/linux/pkt_cls.h > +++ b/include/linux/pkt_cls.h > @@ -1,7 +1,7 @@ > #ifndef __LINUX_PKT_CLS_WRAPPER_H > #define __LINUX_PKT_CLS_WRAPPER_H 1 > > -#if defined(__KERNEL__) || defined(HAVE_TCA_ACT_FLAGS_SKIP_HW) > +#if defined(__KERNEL__) || defined(HAVE_TCA_FLOWER_KEY_ENC_FLAGS_MASK) > #include_next <linux/pkt_cls.h> > #else > > @@ -252,6 +252,28 @@ enum { > TCA_FLOWER_KEY_CT_LABELS, /* u128 */ > TCA_FLOWER_KEY_CT_LABELS_MASK, /* u128 */ > > + TCA_FLOWER_KEY_MPLS_OPTS, > + > + TCA_FLOWER_KEY_HASH, /* u32 */ > + TCA_FLOWER_KEY_HASH_MASK, /* u32 */ > + > + TCA_FLOWER_KEY_NUM_OF_VLANS, /* u8 */ > + > + TCA_FLOWER_KEY_PPPOE_SID, /* be16 */ > + TCA_FLOWER_KEY_PPP_PROTO, /* be16 */ > + > + TCA_FLOWER_KEY_L2TPV3_SID, /* be32 */ > + > + TCA_FLOWER_L2_MISS, /* u8 */ > + > + TCA_FLOWER_KEY_CFM, /* nested */ > + > + TCA_FLOWER_KEY_SPI, /* be32 */ > + TCA_FLOWER_KEY_SPI_MASK, /* be32 */ > + > + TCA_FLOWER_KEY_ENC_FLAGS, /* be32 */ > + TCA_FLOWER_KEY_ENC_FLAGS_MASK, /* be32 */ > + > __TCA_FLOWER_MAX, > }; > > @@ -306,6 +328,10 @@ enum { > enum { > TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0), > TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1), > + TCA_FLOWER_KEY_FLAGS_TUNNEL_CSUM = (1 << 2), > + TCA_FLOWER_KEY_FLAGS_TUNNEL_DONT_FRAGMENT = (1 << 3), > + TCA_FLOWER_KEY_FLAGS_TUNNEL_OAM = (1 << 4), > + TCA_FLOWER_KEY_FLAGS_TUNNEL_CRIT_OPT = (1 << 5), > }; > > /* Match-all classifier */ > diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c > index 3be1c08d2..a2aa4062a 100644 > --- a/lib/netdev-offload-tc.c > +++ b/lib/netdev-offload-tc.c > @@ -53,6 +53,7 @@ static bool multi_mask_per_prio = false; > static bool block_support = false; > static uint16_t ct_state_support; > static bool vxlan_gbp_support = false; > +static bool enc_flags_support = false; > > struct netlink_field { > int offset; > @@ -407,7 +408,7 @@ get_next_available_prio(ovs_be16 protocol) > > /* last_prio can overflow if there will be many different kinds of > * flows which shouldn't happen organically. */ > - if (last_prio == UINT16_MAX) { > + if (last_prio == TC_MAX_PRIORITY) { > return TC_RESERVED_PRIORITY_NONE; > } > > @@ -2863,6 +2864,49 @@ out: > tc_add_del_qdisc(ifindex, false, block_id, TC_INGRESS); > } > > +static void > +probe_enc_flags_support(int ifindex) > +{ > + struct tc_flower flower; > + struct tcf_id id; > + int block_id = 0; > + int prio = TC_RESERVED_PRIORITY_FEATURE_PROBE; > + int error; > + > + error = tc_add_del_qdisc(ifindex, true, block_id, TC_INGRESS); > + if (error) { > + return; > + } > + > + memset(&flower, 0, sizeof flower); > + flower.tc_policy = TC_POLICY_SKIP_HW; > + flower.key.eth_type = htons(ETH_P_IP); > + flower.mask.eth_type = OVS_BE16_MAX; > + flower.tunnel = true; > + flower.mask.tunnel.id = OVS_BE64_MAX; > + flower.mask.tunnel.ipv4.ipv4_src = OVS_BE32_MAX; > + flower.mask.tunnel.ipv4.ipv4_dst = OVS_BE32_MAX; > + flower.mask.tunnel.tp_dst = OVS_BE16_MAX; > + flower.mask.tunnel.tc_enc_flags = TCA_FLOWER_KEY_FLAGS_TUNNEL_CRIT_OPT; > + flower.key.tunnel.ipv4.ipv4_src = htonl(0x01010101); > + flower.key.tunnel.ipv4.ipv4_dst = htonl(0x01010102); > + flower.key.tunnel.tp_dst = htons(46354); > + flower.key.tunnel.tc_enc_flags = TCA_FLOWER_KEY_FLAGS_TUNNEL_CRIT_OPT; > + > + id = tc_make_tcf_id(ifindex, block_id, prio, TC_INGRESS); > + error = tc_replace_flower(&id, &flower); > + if (error) { > + goto out; > + } > + > + tc_del_flower_filter(&id); > + > + enc_flags_support = true; > + VLOG_INFO("probe tc: enc flags are supported."); > +out: > + tc_add_del_qdisc(ifindex, false, block_id, TC_INGRESS); > +} > + > static int > tc_get_policer_action_ids(struct hmap *map) > { > @@ -2991,6 +3035,7 @@ netdev_tc_init_flow_api(struct netdev *netdev) > probe_multi_mask_per_prio(ifindex); > probe_ct_state_support(ifindex); > probe_vxlan_gbp_support(ifindex); > + probe_enc_flags_support(ifindex); > > ovs_mutex_lock(&meter_police_ids_mutex); > meter_police_ids = id_pool_create(METER_POLICE_IDS_BASE, > diff --git a/lib/tc.c b/lib/tc.c > index e55ba3b1b..6c853b8e6 100644 > --- a/lib/tc.c > +++ b/lib/tc.c > @@ -454,6 +454,9 @@ static const struct nl_policy tca_flower_policy[] = { > [TCA_FLOWER_KEY_ENC_OPTS] = { .type = NL_A_NESTED, .optional = true, }, > [TCA_FLOWER_KEY_ENC_OPTS_MASK] = { .type = NL_A_NESTED, > .optional = true, }, > + [TCA_FLOWER_KEY_ENC_FLAGS] = { .type = NL_A_BE32, .optional = true, }, > + [TCA_FLOWER_KEY_ENC_FLAGS_MASK] = { .type = NL_A_BE32, > + .optional = true, }, > [TCA_FLOWER_KEY_CT_STATE] = { .type = NL_A_U16, .optional = true, }, > [TCA_FLOWER_KEY_CT_STATE_MASK] = { .type = NL_A_U16, .optional = true, }, > [TCA_FLOWER_KEY_CT_ZONE] = { .type = NL_A_U16, .optional = true, }, > @@ -865,6 +868,13 @@ nl_parse_flower_tunnel(struct nlattr **attrs, struct tc_flower *flower) > flower->tunnel = true; > } > > + if (attrs[TCA_FLOWER_KEY_ENC_FLAGS_MASK]) { > + flower->key.tunnel.tc_enc_flags = ntohl( > + nl_attr_get_be32(attrs[TCA_FLOWER_KEY_ENC_FLAGS])); > + flower->mask.tunnel.tc_enc_flags = ntohl( > + nl_attr_get_be32(attrs[TCA_FLOWER_KEY_ENC_FLAGS_MASK])); > + } > + > if (attrs[TCA_FLOWER_KEY_ENC_OPTS] && > attrs[TCA_FLOWER_KEY_ENC_OPTS_MASK]) { > err = nl_parse_flower_tunnel_opts(attrs[TCA_FLOWER_KEY_ENC_OPTS], > @@ -3611,6 +3621,7 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower) > struct in6_addr *ipv6_src = &flower->key.tunnel.ipv6.ipv6_src; > struct in6_addr *ipv6_dst = &flower->key.tunnel.ipv6.ipv6_dst; > ovs_be32 id = be64_to_be32(flower->key.tunnel.id); > + ovs_be32 enc_flags = htonl(flower->key.tunnel.tc_enc_flags); > ovs_be16 tp_src = flower->key.tunnel.tp_src; > ovs_be16 tp_dst = flower->key.tunnel.tp_dst; > uint8_t tos = flower->key.tunnel.tos; > @@ -3618,6 +3629,7 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower) > uint8_t tos_mask = flower->mask.tunnel.tos; > uint8_t ttl_mask = flower->mask.tunnel.ttl; > ovs_be64 id_mask = flower->mask.tunnel.id; > + ovs_be32 enc_flags_mask = htonl(flower->mask.tunnel.tc_enc_flags); > ovs_be16 tp_src_mask = flower->mask.tunnel.tp_src; > ovs_be16 tp_dst_mask = flower->mask.tunnel.tp_dst; > > @@ -3655,6 +3667,11 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower) > nl_msg_put_be16(request, TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK, > tp_dst_mask); > } > + if (enc_flags_mask) { > + nl_msg_put_be32(request, TCA_FLOWER_KEY_ENC_FLAGS, enc_flags); > + nl_msg_put_be32(request, TCA_FLOWER_KEY_ENC_FLAGS_MASK, > + enc_flags_mask); > + } > if (id_mask) { > nl_msg_put_be32(request, TCA_FLOWER_KEY_ENC_KEY_ID, id); > } > @@ -3961,6 +3978,7 @@ tc_replace_flower(struct tcf_id *id, struct tc_flower *flower) > struct ofpbuf b = ofpbuf_const_initializer(reply->data, reply->size); > struct nlmsghdr *nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg); > struct tcmsg *tc = ofpbuf_try_pull(&b, sizeof *tc); > + bool is_probe = id->prio == TC_RESERVED_PRIORITY_FEATURE_PROBE; > > if (!nlmsg || !tc) { > COVERAGE_INC(tc_netlink_malformed_reply); > @@ -3980,9 +3998,14 @@ tc_replace_flower(struct tcf_id *id, struct tc_flower *flower) > false); > > if (ret || !cmp_tc_flower_match_action(flower, &flower_out)) { > - VLOG_WARN_RL(&error_rl, "Kernel flower acknowledgment does " > - "not match request! Set dpif_netlink to dbg to " > - "see which rule caused this error."); > + if (is_probe) { > + error = EINVAL; > + } else { > + VLOG_WARN_RL(&error_rl, "Kernel flower acknowledgment " > + "does not match request! Set " > + "dpif_netlink to dbg to see " > + "which rule caused this error."); > + } > } > } > ofpbuf_delete(reply); > diff --git a/lib/tc.h b/lib/tc.h > index 8442c8d8b..c0a1d5d0e 100644 > --- a/lib/tc.h > +++ b/lib/tc.h > @@ -46,15 +46,23 @@ > > #define TC_POLICY_DEFAULT "none" > > -enum tc_flower_reserved_prio { > +enum tc_flower_reserved_prio > +{ > TC_RESERVED_PRIORITY_NONE, > TC_RESERVED_PRIORITY_POLICE, > TC_RESERVED_PRIORITY_IPV4, > TC_RESERVED_PRIORITY_IPV6, > TC_RESERVED_PRIORITY_VLAN, > - __TC_RESERVED_PRIORITY_MAX > + __TC_RESERVED_PRIORITY_MAX, > + > + TC_MAX_PRIORITY = UINT16_MAX - 1, > + /* This priority is reserved solely for probing purposes. > + * Since it's not used in actual traffic flows, we assign it a high value > + * to avoid impacting vendor specific hardware offload implementations. */ > + TC_RESERVED_PRIORITY_FEATURE_PROBE > }; > -#define TC_RESERVED_PRIORITY_MAX (__TC_RESERVED_PRIORITY_MAX -1) > +#define TC_RESERVED_PRIORITY_MAX (__TC_RESERVED_PRIORITY_MAX - 1) > + > > enum tc_qdisc_hook { > TC_INGRESS, > @@ -125,6 +133,7 @@ struct tc_flower_tunnel { > uint8_t ttl; > ovs_be16 tp_src; > ovs_be16 tp_dst; > + uint32_t tc_enc_flags; > struct tc_tunnel_gbp gbp; > ovs_be64 id; > struct tun_metadata metadata; Acked-by: Roi Dayan <roid@nvidia.com>
diff --git a/acinclude.m4 b/acinclude.m4 index 1ace70c92..f4cb4a146 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -163,10 +163,10 @@ dnl Configure Linux tc compat. AC_DEFUN([OVS_CHECK_LINUX_TC], [ AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([#include <linux/pkt_cls.h>], [ - int x = TCA_ACT_FLAGS_SKIP_HW; + int x = TCA_FLOWER_KEY_ENC_FLAGS_MASK; ])], - [AC_DEFINE([HAVE_TCA_ACT_FLAGS_SKIP_HW], [1], - [Define to 1 if TCA_ACT_FLAGS_SKIP_HW is available.])]) + [AC_DEFINE([HAVE_TCA_FLOWER_KEY_ENC_FLAGS_MASK], [1], + [Define to 1 if TCA_FLOWER_KEY_ENC_FLAGS_MASK is available.])]) AC_CHECK_MEMBERS([struct tcf_t.firstuse], [], [], [#include <linux/pkt_cls.h>]) diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h index fb4a7ecea..5890dc157 100644 --- a/include/linux/pkt_cls.h +++ b/include/linux/pkt_cls.h @@ -1,7 +1,7 @@ #ifndef __LINUX_PKT_CLS_WRAPPER_H #define __LINUX_PKT_CLS_WRAPPER_H 1 -#if defined(__KERNEL__) || defined(HAVE_TCA_ACT_FLAGS_SKIP_HW) +#if defined(__KERNEL__) || defined(HAVE_TCA_FLOWER_KEY_ENC_FLAGS_MASK) #include_next <linux/pkt_cls.h> #else @@ -252,6 +252,28 @@ enum { TCA_FLOWER_KEY_CT_LABELS, /* u128 */ TCA_FLOWER_KEY_CT_LABELS_MASK, /* u128 */ + TCA_FLOWER_KEY_MPLS_OPTS, + + TCA_FLOWER_KEY_HASH, /* u32 */ + TCA_FLOWER_KEY_HASH_MASK, /* u32 */ + + TCA_FLOWER_KEY_NUM_OF_VLANS, /* u8 */ + + TCA_FLOWER_KEY_PPPOE_SID, /* be16 */ + TCA_FLOWER_KEY_PPP_PROTO, /* be16 */ + + TCA_FLOWER_KEY_L2TPV3_SID, /* be32 */ + + TCA_FLOWER_L2_MISS, /* u8 */ + + TCA_FLOWER_KEY_CFM, /* nested */ + + TCA_FLOWER_KEY_SPI, /* be32 */ + TCA_FLOWER_KEY_SPI_MASK, /* be32 */ + + TCA_FLOWER_KEY_ENC_FLAGS, /* be32 */ + TCA_FLOWER_KEY_ENC_FLAGS_MASK, /* be32 */ + __TCA_FLOWER_MAX, }; @@ -306,6 +328,10 @@ enum { enum { TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0), TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1), + TCA_FLOWER_KEY_FLAGS_TUNNEL_CSUM = (1 << 2), + TCA_FLOWER_KEY_FLAGS_TUNNEL_DONT_FRAGMENT = (1 << 3), + TCA_FLOWER_KEY_FLAGS_TUNNEL_OAM = (1 << 4), + TCA_FLOWER_KEY_FLAGS_TUNNEL_CRIT_OPT = (1 << 5), }; /* Match-all classifier */ diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index 3be1c08d2..a2aa4062a 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -53,6 +53,7 @@ static bool multi_mask_per_prio = false; static bool block_support = false; static uint16_t ct_state_support; static bool vxlan_gbp_support = false; +static bool enc_flags_support = false; struct netlink_field { int offset; @@ -407,7 +408,7 @@ get_next_available_prio(ovs_be16 protocol) /* last_prio can overflow if there will be many different kinds of * flows which shouldn't happen organically. */ - if (last_prio == UINT16_MAX) { + if (last_prio == TC_MAX_PRIORITY) { return TC_RESERVED_PRIORITY_NONE; } @@ -2863,6 +2864,49 @@ out: tc_add_del_qdisc(ifindex, false, block_id, TC_INGRESS); } +static void +probe_enc_flags_support(int ifindex) +{ + struct tc_flower flower; + struct tcf_id id; + int block_id = 0; + int prio = TC_RESERVED_PRIORITY_FEATURE_PROBE; + int error; + + error = tc_add_del_qdisc(ifindex, true, block_id, TC_INGRESS); + if (error) { + return; + } + + memset(&flower, 0, sizeof flower); + flower.tc_policy = TC_POLICY_SKIP_HW; + flower.key.eth_type = htons(ETH_P_IP); + flower.mask.eth_type = OVS_BE16_MAX; + flower.tunnel = true; + flower.mask.tunnel.id = OVS_BE64_MAX; + flower.mask.tunnel.ipv4.ipv4_src = OVS_BE32_MAX; + flower.mask.tunnel.ipv4.ipv4_dst = OVS_BE32_MAX; + flower.mask.tunnel.tp_dst = OVS_BE16_MAX; + flower.mask.tunnel.tc_enc_flags = TCA_FLOWER_KEY_FLAGS_TUNNEL_CRIT_OPT; + flower.key.tunnel.ipv4.ipv4_src = htonl(0x01010101); + flower.key.tunnel.ipv4.ipv4_dst = htonl(0x01010102); + flower.key.tunnel.tp_dst = htons(46354); + flower.key.tunnel.tc_enc_flags = TCA_FLOWER_KEY_FLAGS_TUNNEL_CRIT_OPT; + + id = tc_make_tcf_id(ifindex, block_id, prio, TC_INGRESS); + error = tc_replace_flower(&id, &flower); + if (error) { + goto out; + } + + tc_del_flower_filter(&id); + + enc_flags_support = true; + VLOG_INFO("probe tc: enc flags are supported."); +out: + tc_add_del_qdisc(ifindex, false, block_id, TC_INGRESS); +} + static int tc_get_policer_action_ids(struct hmap *map) { @@ -2991,6 +3035,7 @@ netdev_tc_init_flow_api(struct netdev *netdev) probe_multi_mask_per_prio(ifindex); probe_ct_state_support(ifindex); probe_vxlan_gbp_support(ifindex); + probe_enc_flags_support(ifindex); ovs_mutex_lock(&meter_police_ids_mutex); meter_police_ids = id_pool_create(METER_POLICE_IDS_BASE, diff --git a/lib/tc.c b/lib/tc.c index e55ba3b1b..6c853b8e6 100644 --- a/lib/tc.c +++ b/lib/tc.c @@ -454,6 +454,9 @@ static const struct nl_policy tca_flower_policy[] = { [TCA_FLOWER_KEY_ENC_OPTS] = { .type = NL_A_NESTED, .optional = true, }, [TCA_FLOWER_KEY_ENC_OPTS_MASK] = { .type = NL_A_NESTED, .optional = true, }, + [TCA_FLOWER_KEY_ENC_FLAGS] = { .type = NL_A_BE32, .optional = true, }, + [TCA_FLOWER_KEY_ENC_FLAGS_MASK] = { .type = NL_A_BE32, + .optional = true, }, [TCA_FLOWER_KEY_CT_STATE] = { .type = NL_A_U16, .optional = true, }, [TCA_FLOWER_KEY_CT_STATE_MASK] = { .type = NL_A_U16, .optional = true, }, [TCA_FLOWER_KEY_CT_ZONE] = { .type = NL_A_U16, .optional = true, }, @@ -865,6 +868,13 @@ nl_parse_flower_tunnel(struct nlattr **attrs, struct tc_flower *flower) flower->tunnel = true; } + if (attrs[TCA_FLOWER_KEY_ENC_FLAGS_MASK]) { + flower->key.tunnel.tc_enc_flags = ntohl( + nl_attr_get_be32(attrs[TCA_FLOWER_KEY_ENC_FLAGS])); + flower->mask.tunnel.tc_enc_flags = ntohl( + nl_attr_get_be32(attrs[TCA_FLOWER_KEY_ENC_FLAGS_MASK])); + } + if (attrs[TCA_FLOWER_KEY_ENC_OPTS] && attrs[TCA_FLOWER_KEY_ENC_OPTS_MASK]) { err = nl_parse_flower_tunnel_opts(attrs[TCA_FLOWER_KEY_ENC_OPTS], @@ -3611,6 +3621,7 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower) struct in6_addr *ipv6_src = &flower->key.tunnel.ipv6.ipv6_src; struct in6_addr *ipv6_dst = &flower->key.tunnel.ipv6.ipv6_dst; ovs_be32 id = be64_to_be32(flower->key.tunnel.id); + ovs_be32 enc_flags = htonl(flower->key.tunnel.tc_enc_flags); ovs_be16 tp_src = flower->key.tunnel.tp_src; ovs_be16 tp_dst = flower->key.tunnel.tp_dst; uint8_t tos = flower->key.tunnel.tos; @@ -3618,6 +3629,7 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower) uint8_t tos_mask = flower->mask.tunnel.tos; uint8_t ttl_mask = flower->mask.tunnel.ttl; ovs_be64 id_mask = flower->mask.tunnel.id; + ovs_be32 enc_flags_mask = htonl(flower->mask.tunnel.tc_enc_flags); ovs_be16 tp_src_mask = flower->mask.tunnel.tp_src; ovs_be16 tp_dst_mask = flower->mask.tunnel.tp_dst; @@ -3655,6 +3667,11 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower) nl_msg_put_be16(request, TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK, tp_dst_mask); } + if (enc_flags_mask) { + nl_msg_put_be32(request, TCA_FLOWER_KEY_ENC_FLAGS, enc_flags); + nl_msg_put_be32(request, TCA_FLOWER_KEY_ENC_FLAGS_MASK, + enc_flags_mask); + } if (id_mask) { nl_msg_put_be32(request, TCA_FLOWER_KEY_ENC_KEY_ID, id); } @@ -3961,6 +3978,7 @@ tc_replace_flower(struct tcf_id *id, struct tc_flower *flower) struct ofpbuf b = ofpbuf_const_initializer(reply->data, reply->size); struct nlmsghdr *nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg); struct tcmsg *tc = ofpbuf_try_pull(&b, sizeof *tc); + bool is_probe = id->prio == TC_RESERVED_PRIORITY_FEATURE_PROBE; if (!nlmsg || !tc) { COVERAGE_INC(tc_netlink_malformed_reply); @@ -3980,9 +3998,14 @@ tc_replace_flower(struct tcf_id *id, struct tc_flower *flower) false); if (ret || !cmp_tc_flower_match_action(flower, &flower_out)) { - VLOG_WARN_RL(&error_rl, "Kernel flower acknowledgment does " - "not match request! Set dpif_netlink to dbg to " - "see which rule caused this error."); + if (is_probe) { + error = EINVAL; + } else { + VLOG_WARN_RL(&error_rl, "Kernel flower acknowledgment " + "does not match request! Set " + "dpif_netlink to dbg to see " + "which rule caused this error."); + } } } ofpbuf_delete(reply); diff --git a/lib/tc.h b/lib/tc.h index 8442c8d8b..c0a1d5d0e 100644 --- a/lib/tc.h +++ b/lib/tc.h @@ -46,15 +46,23 @@ #define TC_POLICY_DEFAULT "none" -enum tc_flower_reserved_prio { +enum tc_flower_reserved_prio +{ TC_RESERVED_PRIORITY_NONE, TC_RESERVED_PRIORITY_POLICE, TC_RESERVED_PRIORITY_IPV4, TC_RESERVED_PRIORITY_IPV6, TC_RESERVED_PRIORITY_VLAN, - __TC_RESERVED_PRIORITY_MAX + __TC_RESERVED_PRIORITY_MAX, + + TC_MAX_PRIORITY = UINT16_MAX - 1, + /* This priority is reserved solely for probing purposes. + * Since it's not used in actual traffic flows, we assign it a high value + * to avoid impacting vendor specific hardware offload implementations. */ + TC_RESERVED_PRIORITY_FEATURE_PROBE }; -#define TC_RESERVED_PRIORITY_MAX (__TC_RESERVED_PRIORITY_MAX -1) +#define TC_RESERVED_PRIORITY_MAX (__TC_RESERVED_PRIORITY_MAX - 1) + enum tc_qdisc_hook { TC_INGRESS, @@ -125,6 +133,7 @@ struct tc_flower_tunnel { uint8_t ttl; ovs_be16 tp_src; ovs_be16 tp_dst; + uint32_t tc_enc_flags; struct tc_tunnel_gbp gbp; ovs_be64 id; struct tun_metadata metadata;
This patch checks to see if the TCA_FLOWER_KEY_ENC_FLAGS key is supported. Signed-off-by: Eelco Chaudron <echaudro@redhat.com> --- acinclude.m4 | 6 +++--- include/linux/pkt_cls.h | 28 +++++++++++++++++++++++- lib/netdev-offload-tc.c | 47 ++++++++++++++++++++++++++++++++++++++++- lib/tc.c | 29 ++++++++++++++++++++++--- lib/tc.h | 15 ++++++++++--- 5 files changed, 114 insertions(+), 11 deletions(-)