mirror of
https://github.com/openvswitch/ovs
synced 2025-08-22 01:51:26 +00:00
netdev-offload-tc: Check if TCA_FLOWER_KEY_ENC_FLAGS is supported.
This patch checks to see if the TCA_FLOWER_KEY_ENC_FLAGS key is supported. Acked-by: Roi Dayan <roid@nvidia.com> Acked-by: Simon Horman <horms@ovn.org> Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
This commit is contained in:
parent
19ee88ef0f
commit
3f7af5233a
@ -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>])
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
29
lib/tc.c
29
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);
|
||||
|
12
lib/tc.h
12
lib/tc.h
@ -52,9 +52,16 @@ enum tc_flower_reserved_prio {
|
||||
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 +132,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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user