[ovs-dev] [PATCH V2 1/4] netdev-offload-dpdk: Add last attribute to patterns
Eli Britstein
elibr at nvidia.com
Mon Aug 16 13:53:17 UTC 2021
Matching on frag types requires range. Add 'last' attribute to patterns.
Signed-off-by: Eli Britstein <elibr at nvidia.com>
---
lib/netdev-offload-dpdk.c | 151 ++++++++++++++++++++------------------
1 file changed, 81 insertions(+), 70 deletions(-)
diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c
index f6706ee0c..769dc48d2 100644
--- a/lib/netdev-offload-dpdk.c
+++ b/lib/netdev-offload-dpdk.c
@@ -184,8 +184,12 @@ dump_flow_attr(struct ds *s, struct ds *s_extra,
/* Adds one pattern item 'field' with the 'mask' to dynamic string 's' using
* 'testpmd command'-like format. */
-#define DUMP_PATTERN_ITEM(mask, field, fmt, spec_pri, mask_pri) \
- if (is_all_ones(&mask, sizeof mask)) { \
+#define DUMP_PATTERN_ITEM(mask, has_last, field, fmt, spec_pri, mask_pri, \
+ last_pri) \
+ if (has_last) { \
+ ds_put_format(s, field " spec " fmt " " field " mask " fmt " " field \
+ " last " fmt " ", spec_pri, mask_pri, last_pri); \
+ } else if (is_all_ones(&mask, sizeof mask)) { \
ds_put_format(s, field " is " fmt " ", spec_pri); \
} else if (!is_all_zeros(&mask, sizeof mask)) { \
ds_put_format(s, field " spec " fmt " " field " mask " fmt " ", \
@@ -207,21 +211,24 @@ dump_flow_pattern(struct ds *s,
} else if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
const struct rte_flow_item_eth *eth_spec = item->spec;
const struct rte_flow_item_eth *eth_mask = item->mask;
+ uint8_t ea[ETH_ADDR_LEN];
ds_put_cstr(s, "eth ");
if (eth_spec) {
if (!eth_mask) {
eth_mask = &rte_flow_item_eth_mask;
}
- DUMP_PATTERN_ITEM(eth_mask->src, "src", ETH_ADDR_FMT,
+ DUMP_PATTERN_ITEM(eth_mask->src, false, "src", ETH_ADDR_FMT,
ETH_ADDR_BYTES_ARGS(eth_spec->src.addr_bytes),
- ETH_ADDR_BYTES_ARGS(eth_mask->src.addr_bytes));
- DUMP_PATTERN_ITEM(eth_mask->dst, "dst", ETH_ADDR_FMT,
+ ETH_ADDR_BYTES_ARGS(eth_mask->src.addr_bytes),
+ ETH_ADDR_BYTES_ARGS(ea));
+ DUMP_PATTERN_ITEM(eth_mask->dst, false, "dst", ETH_ADDR_FMT,
ETH_ADDR_BYTES_ARGS(eth_spec->dst.addr_bytes),
- ETH_ADDR_BYTES_ARGS(eth_mask->dst.addr_bytes));
- DUMP_PATTERN_ITEM(eth_mask->type, "type", "0x%04"PRIx16,
+ ETH_ADDR_BYTES_ARGS(eth_mask->dst.addr_bytes),
+ ETH_ADDR_BYTES_ARGS(ea));
+ DUMP_PATTERN_ITEM(eth_mask->type, false, "type", "0x%04"PRIx16,
ntohs(eth_spec->type),
- ntohs(eth_mask->type));
+ ntohs(eth_mask->type), 0);
}
ds_put_cstr(s, "/ ");
} else if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
@@ -233,11 +240,11 @@ dump_flow_pattern(struct ds *s,
if (!vlan_mask) {
vlan_mask = &rte_flow_item_vlan_mask;
}
- DUMP_PATTERN_ITEM(vlan_mask->inner_type, "inner_type", "0x%"PRIx16,
- ntohs(vlan_spec->inner_type),
- ntohs(vlan_mask->inner_type));
- DUMP_PATTERN_ITEM(vlan_mask->tci, "tci", "0x%"PRIx16,
- ntohs(vlan_spec->tci), ntohs(vlan_mask->tci));
+ DUMP_PATTERN_ITEM(vlan_mask->inner_type, false, "inner_type",
+ "0x%"PRIx16, ntohs(vlan_spec->inner_type),
+ ntohs(vlan_mask->inner_type), 0);
+ DUMP_PATTERN_ITEM(vlan_mask->tci, false, "tci", "0x%"PRIx16,
+ ntohs(vlan_spec->tci), ntohs(vlan_mask->tci), 0);
}
ds_put_cstr(s, "/ ");
} else if (item->type == RTE_FLOW_ITEM_TYPE_IPV4) {
@@ -249,21 +256,21 @@ dump_flow_pattern(struct ds *s,
if (!ipv4_mask) {
ipv4_mask = &rte_flow_item_ipv4_mask;
}
- DUMP_PATTERN_ITEM(ipv4_mask->hdr.src_addr, "src", IP_FMT,
+ DUMP_PATTERN_ITEM(ipv4_mask->hdr.src_addr, false, "src", IP_FMT,
IP_ARGS(ipv4_spec->hdr.src_addr),
- IP_ARGS(ipv4_mask->hdr.src_addr));
- DUMP_PATTERN_ITEM(ipv4_mask->hdr.dst_addr, "dst", IP_FMT,
+ IP_ARGS(ipv4_mask->hdr.src_addr), IP_ARGS(0));
+ DUMP_PATTERN_ITEM(ipv4_mask->hdr.dst_addr, false, "dst", IP_FMT,
IP_ARGS(ipv4_spec->hdr.dst_addr),
- IP_ARGS(ipv4_mask->hdr.dst_addr));
- DUMP_PATTERN_ITEM(ipv4_mask->hdr.next_proto_id, "proto",
+ IP_ARGS(ipv4_mask->hdr.dst_addr), IP_ARGS(0));
+ DUMP_PATTERN_ITEM(ipv4_mask->hdr.next_proto_id, false, "proto",
"0x%"PRIx8, ipv4_spec->hdr.next_proto_id,
- ipv4_mask->hdr.next_proto_id);
- DUMP_PATTERN_ITEM(ipv4_mask->hdr.type_of_service, "tos",
+ ipv4_mask->hdr.next_proto_id, 0);
+ DUMP_PATTERN_ITEM(ipv4_mask->hdr.type_of_service, false, "tos",
"0x%"PRIx8, ipv4_spec->hdr.type_of_service,
- ipv4_mask->hdr.type_of_service);
- DUMP_PATTERN_ITEM(ipv4_mask->hdr.time_to_live, "ttl",
+ ipv4_mask->hdr.type_of_service, 0);
+ DUMP_PATTERN_ITEM(ipv4_mask->hdr.time_to_live, false, "ttl",
"0x%"PRIx8, ipv4_spec->hdr.time_to_live,
- ipv4_mask->hdr.time_to_live);
+ ipv4_mask->hdr.time_to_live, 0);
}
ds_put_cstr(s, "/ ");
} else if (item->type == RTE_FLOW_ITEM_TYPE_UDP) {
@@ -275,12 +282,12 @@ dump_flow_pattern(struct ds *s,
if (!udp_mask) {
udp_mask = &rte_flow_item_udp_mask;
}
- DUMP_PATTERN_ITEM(udp_mask->hdr.src_port, "src", "%"PRIu16,
+ DUMP_PATTERN_ITEM(udp_mask->hdr.src_port, false, "src", "%"PRIu16,
ntohs(udp_spec->hdr.src_port),
- ntohs(udp_mask->hdr.src_port));
- DUMP_PATTERN_ITEM(udp_mask->hdr.dst_port, "dst", "%"PRIu16,
+ ntohs(udp_mask->hdr.src_port), 0);
+ DUMP_PATTERN_ITEM(udp_mask->hdr.dst_port, false, "dst", "%"PRIu16,
ntohs(udp_spec->hdr.dst_port),
- ntohs(udp_mask->hdr.dst_port));
+ ntohs(udp_mask->hdr.dst_port), 0);
}
ds_put_cstr(s, "/ ");
} else if (item->type == RTE_FLOW_ITEM_TYPE_SCTP) {
@@ -292,12 +299,12 @@ dump_flow_pattern(struct ds *s,
if (!sctp_mask) {
sctp_mask = &rte_flow_item_sctp_mask;
}
- DUMP_PATTERN_ITEM(sctp_mask->hdr.src_port, "src", "%"PRIu16,
+ DUMP_PATTERN_ITEM(sctp_mask->hdr.src_port, false, "src", "%"PRIu16,
ntohs(sctp_spec->hdr.src_port),
- ntohs(sctp_mask->hdr.src_port));
- DUMP_PATTERN_ITEM(sctp_mask->hdr.dst_port, "dst", "%"PRIu16,
+ ntohs(sctp_mask->hdr.src_port), 0);
+ DUMP_PATTERN_ITEM(sctp_mask->hdr.dst_port, false, "dst", "%"PRIu16,
ntohs(sctp_spec->hdr.dst_port),
- ntohs(sctp_mask->hdr.dst_port));
+ ntohs(sctp_mask->hdr.dst_port), 0);
}
ds_put_cstr(s, "/ ");
} else if (item->type == RTE_FLOW_ITEM_TYPE_ICMP) {
@@ -309,12 +316,12 @@ dump_flow_pattern(struct ds *s,
if (!icmp_mask) {
icmp_mask = &rte_flow_item_icmp_mask;
}
- DUMP_PATTERN_ITEM(icmp_mask->hdr.icmp_type, "icmp_type", "%"PRIu8,
- icmp_spec->hdr.icmp_type,
- icmp_mask->hdr.icmp_type);
- DUMP_PATTERN_ITEM(icmp_mask->hdr.icmp_code, "icmp_code", "%"PRIu8,
- icmp_spec->hdr.icmp_code,
- icmp_mask->hdr.icmp_code);
+ DUMP_PATTERN_ITEM(icmp_mask->hdr.icmp_type, false, "icmp_type",
+ "%"PRIu8, icmp_spec->hdr.icmp_type,
+ icmp_mask->hdr.icmp_type, 0);
+ DUMP_PATTERN_ITEM(icmp_mask->hdr.icmp_code, false, "icmp_code",
+ "%"PRIu8, icmp_spec->hdr.icmp_code,
+ icmp_mask->hdr.icmp_code, 0);
}
ds_put_cstr(s, "/ ");
} else if (item->type == RTE_FLOW_ITEM_TYPE_TCP) {
@@ -326,15 +333,15 @@ dump_flow_pattern(struct ds *s,
if (!tcp_mask) {
tcp_mask = &rte_flow_item_tcp_mask;
}
- DUMP_PATTERN_ITEM(tcp_mask->hdr.src_port, "src", "%"PRIu16,
+ DUMP_PATTERN_ITEM(tcp_mask->hdr.src_port, false, "src", "%"PRIu16,
ntohs(tcp_spec->hdr.src_port),
- ntohs(tcp_mask->hdr.src_port));
- DUMP_PATTERN_ITEM(tcp_mask->hdr.dst_port, "dst", "%"PRIu16,
+ ntohs(tcp_mask->hdr.src_port), 0);
+ DUMP_PATTERN_ITEM(tcp_mask->hdr.dst_port, false, "dst", "%"PRIu16,
ntohs(tcp_spec->hdr.dst_port),
- ntohs(tcp_mask->hdr.dst_port));
- DUMP_PATTERN_ITEM(tcp_mask->hdr.tcp_flags, "flags", "0x%"PRIx8,
- tcp_spec->hdr.tcp_flags,
- tcp_mask->hdr.tcp_flags);
+ ntohs(tcp_mask->hdr.dst_port), 0);
+ DUMP_PATTERN_ITEM(tcp_mask->hdr.tcp_flags, false, "flags",
+ "0x%"PRIx8, tcp_spec->hdr.tcp_flags,
+ tcp_mask->hdr.tcp_flags, 0);
}
ds_put_cstr(s, "/ ");
} else if (item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
@@ -354,22 +361,22 @@ dump_flow_pattern(struct ds *s,
memcpy(&mask, ipv6_mask->hdr.src_addr, sizeof mask);
ipv6_string_mapped(addr_str, &addr);
ipv6_string_mapped(mask_str, &mask);
- DUMP_PATTERN_ITEM(mask, "src", "%s", addr_str, mask_str);
+ DUMP_PATTERN_ITEM(mask, false, "src", "%s", addr_str, mask_str, "");
memcpy(&addr, ipv6_spec->hdr.dst_addr, sizeof addr);
memcpy(&mask, ipv6_mask->hdr.dst_addr, sizeof mask);
ipv6_string_mapped(addr_str, &addr);
ipv6_string_mapped(mask_str, &mask);
- DUMP_PATTERN_ITEM(mask, "dst", "%s", addr_str, mask_str);
+ DUMP_PATTERN_ITEM(mask, false, "dst", "%s", addr_str, mask_str, "");
- DUMP_PATTERN_ITEM(ipv6_mask->hdr.proto, "proto", "%"PRIu8,
- ipv6_spec->hdr.proto, ipv6_mask->hdr.proto);
- DUMP_PATTERN_ITEM(ipv6_mask->hdr.vtc_flow, "tc", "0x%"PRIx32,
+ DUMP_PATTERN_ITEM(ipv6_mask->hdr.proto, false, "proto", "%"PRIu8,
+ ipv6_spec->hdr.proto, ipv6_mask->hdr.proto, 0);
+ DUMP_PATTERN_ITEM(ipv6_mask->hdr.vtc_flow, false, "tc", "0x%"PRIx32,
ntohl(ipv6_spec->hdr.vtc_flow),
- ntohl(ipv6_mask->hdr.vtc_flow));
- DUMP_PATTERN_ITEM(ipv6_mask->hdr.hop_limits, "hop", "%"PRIu8,
+ ntohl(ipv6_mask->hdr.vtc_flow), 0);
+ DUMP_PATTERN_ITEM(ipv6_mask->hdr.hop_limits, false, "hop", "%"PRIu8,
ipv6_spec->hdr.hop_limits,
- ipv6_mask->hdr.hop_limits);
+ ipv6_mask->hdr.hop_limits, 0);
}
ds_put_cstr(s, "/ ");
} else if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN) {
@@ -386,8 +393,8 @@ dump_flow_pattern(struct ds *s,
vxlan_spec->vni));
mask_vni = get_unaligned_be32(ALIGNED_CAST(ovs_be32 *,
vxlan_mask->vni));
- DUMP_PATTERN_ITEM(vxlan_mask->vni, "vni", "%"PRIu32,
- ntohl(spec_vni) >> 8, ntohl(mask_vni) >> 8);
+ DUMP_PATTERN_ITEM(vxlan_mask->vni, false, "vni", "%"PRIu32,
+ ntohl(spec_vni) >> 8, ntohl(mask_vni) >> 8, 0);
}
ds_put_cstr(s, "/ ");
} else {
@@ -683,7 +690,7 @@ netdev_offload_dpdk_flow_create(struct netdev *netdev,
static void
add_flow_pattern(struct flow_patterns *patterns, enum rte_flow_item_type type,
- const void *spec, const void *mask)
+ const void *spec, const void *mask, const void *last)
{
int cnt = patterns->cnt;
@@ -700,7 +707,7 @@ add_flow_pattern(struct flow_patterns *patterns, enum rte_flow_item_type type,
patterns->items[cnt].type = type;
patterns->items[cnt].spec = spec;
patterns->items[cnt].mask = mask;
- patterns->items[cnt].last = NULL;
+ patterns->items[cnt].last = last;
patterns->cnt++;
}
@@ -756,7 +763,7 @@ add_flow_tnl_items(struct flow_patterns *patterns,
patterns->tnl_pmd_items_cnt = tnl_pmd_items_cnt;
for (i = 0; i < tnl_pmd_items_cnt; i++) {
add_flow_pattern(patterns, tnl_pmd_items[i].type,
- tnl_pmd_items[i].spec, tnl_pmd_items[i].mask);
+ tnl_pmd_items[i].spec, tnl_pmd_items[i].mask, NULL);
}
}
@@ -787,6 +794,9 @@ free_flow_patterns(struct flow_patterns *patterns)
if (patterns->items[i].mask) {
free(CONST_CAST(void *, patterns->items[i].mask));
}
+ if (patterns->items[i].last) {
+ free(CONST_CAST(void *, patterns->items[i].last));
+ }
}
free(patterns->items);
patterns->items = NULL;
@@ -921,7 +931,7 @@ parse_tnl_ip_match(struct flow_patterns *patterns,
consumed_masks->tunnel.ip_src = 0;
consumed_masks->tunnel.ip_dst = 0;
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV4, spec, mask);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV4, spec, mask, NULL);
} else if (!is_all_zeros(&match->wc.masks.tunnel.ipv6_src,
sizeof(struct in6_addr)) ||
!is_all_zeros(&match->wc.masks.tunnel.ipv6_dst,
@@ -957,7 +967,7 @@ parse_tnl_ip_match(struct flow_patterns *patterns,
memset(&consumed_masks->tunnel.ipv6_dst, 0,
sizeof consumed_masks->tunnel.ipv6_dst);
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV6, spec, mask);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV6, spec, mask, NULL);
} else {
VLOG_ERR_RL(&rl, "Tunnel L3 protocol is neither IPv4 nor IPv6");
return -1;
@@ -987,7 +997,7 @@ parse_tnl_udp_match(struct flow_patterns *patterns,
consumed_masks->tunnel.tp_src = 0;
consumed_masks->tunnel.tp_dst = 0;
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_UDP, spec, mask);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_UDP, spec, mask, NULL);
}
static int
@@ -1017,7 +1027,8 @@ parse_vxlan_match(struct flow_patterns *patterns,
consumed_masks->tunnel.tun_id = 0;
consumed_masks->tunnel.flags = 0;
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_VXLAN, vx_spec, vx_mask);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_VXLAN, vx_spec, vx_mask,
+ NULL);
return 0;
}
@@ -1092,7 +1103,7 @@ parse_flow_match(struct netdev *netdev,
memset(&consumed_masks->dl_src, 0, sizeof consumed_masks->dl_src);
consumed_masks->dl_type = 0;
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_ETH, spec, mask);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_ETH, spec, mask, NULL);
}
/* VLAN */
@@ -1108,7 +1119,7 @@ parse_flow_match(struct netdev *netdev,
/* Match any protocols. */
mask->inner_type = 0;
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_VLAN, spec, mask);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_VLAN, spec, mask, NULL);
}
/* For untagged matching match->wc.masks.vlans[0].tci is 0xFFFF and
* match->flow.vlans[0].tci is 0. Consuming is needed outside of the if
@@ -1141,7 +1152,7 @@ parse_flow_match(struct netdev *netdev,
consumed_masks->nw_src = 0;
consumed_masks->nw_dst = 0;
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV4, spec, mask);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV4, spec, mask, NULL);
/* Save proto for L4 protocol setup. */
proto = spec->hdr.next_proto_id &
@@ -1184,7 +1195,7 @@ parse_flow_match(struct netdev *netdev,
memset(&consumed_masks->ipv6_src, 0, sizeof consumed_masks->ipv6_src);
memset(&consumed_masks->ipv6_dst, 0, sizeof consumed_masks->ipv6_dst);
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV6, spec, mask);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV6, spec, mask, NULL);
/* Save proto for L4 protocol setup. */
proto = spec->hdr.proto & mask->hdr.proto;
@@ -1219,7 +1230,7 @@ parse_flow_match(struct netdev *netdev,
consumed_masks->tp_dst = 0;
consumed_masks->tcp_flags = 0;
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_TCP, spec, mask);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_TCP, spec, mask, NULL);
} else if (proto == IPPROTO_UDP) {
struct rte_flow_item_udp *spec, *mask;
@@ -1235,7 +1246,7 @@ parse_flow_match(struct netdev *netdev,
consumed_masks->tp_src = 0;
consumed_masks->tp_dst = 0;
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_UDP, spec, mask);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_UDP, spec, mask, NULL);
} else if (proto == IPPROTO_SCTP) {
struct rte_flow_item_sctp *spec, *mask;
@@ -1251,7 +1262,7 @@ parse_flow_match(struct netdev *netdev,
consumed_masks->tp_src = 0;
consumed_masks->tp_dst = 0;
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_SCTP, spec, mask);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_SCTP, spec, mask, NULL);
} else if (proto == IPPROTO_ICMP) {
struct rte_flow_item_icmp *spec, *mask;
@@ -1267,10 +1278,10 @@ parse_flow_match(struct netdev *netdev,
consumed_masks->tp_src = 0;
consumed_masks->tp_dst = 0;
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_ICMP, spec, mask);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_ICMP, spec, mask, NULL);
}
- add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_END, NULL, NULL);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_END, NULL, NULL, NULL);
if (!is_all_zeros(consumed_masks, sizeof *consumed_masks)) {
return -1;
--
2.28.0.2311.g225365fb51
More information about the dev
mailing list