[ovs-dev] [PATCH V3 01/19] netdev-offload-dpdk: Refactor flow patterns
Eli Britstein
elibr at mellanox.com
Sun Dec 8 13:22:46 UTC 2019
Refactor the flow patterns code to a helper function for better
readability and towards supporting more matches.
Signed-off-by: Eli Britstein <elibr at mellanox.com>
Reviewed-by: Oz Shlomo <ozsh at mellanox.com>
---
lib/netdev-offload-dpdk.c | 208 +++++++++++++++++++++++++---------------------
1 file changed, 112 insertions(+), 96 deletions(-)
diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c
index 96794dc4d..a008e642f 100644
--- a/lib/netdev-offload-dpdk.c
+++ b/lib/netdev-offload-dpdk.c
@@ -410,54 +410,42 @@ add_flow_rss_action(struct flow_actions *actions,
return rss_data;
}
+struct flow_items {
+ struct rte_flow_item_eth eth;
+ struct rte_flow_item_vlan vlan;
+ struct rte_flow_item_ipv4 ipv4;
+ union {
+ struct rte_flow_item_tcp tcp;
+ struct rte_flow_item_udp udp;
+ struct rte_flow_item_sctp sctp;
+ struct rte_flow_item_icmp icmp;
+ };
+};
+
static int
-netdev_offload_dpdk_add_flow(struct netdev *netdev,
- const struct match *match,
- struct nlattr *nl_actions OVS_UNUSED,
- size_t actions_len OVS_UNUSED,
- const ovs_u128 *ufid,
- struct offload_info *info)
+parse_flow_match(struct flow_patterns *patterns,
+ struct flow_items *spec,
+ struct flow_items *mask,
+ const struct match *match)
{
- const struct rte_flow_attr flow_attr = {
- .group = 0,
- .priority = 0,
- .ingress = 1,
- .egress = 0
- };
- struct flow_patterns patterns = { .items = NULL, .cnt = 0 };
- struct flow_actions actions = { .actions = NULL, .cnt = 0 };
- struct rte_flow *flow;
- struct rte_flow_error error;
uint8_t proto = 0;
- int ret = 0;
- struct flow_items {
- struct rte_flow_item_eth eth;
- struct rte_flow_item_vlan vlan;
- struct rte_flow_item_ipv4 ipv4;
- union {
- struct rte_flow_item_tcp tcp;
- struct rte_flow_item_udp udp;
- struct rte_flow_item_sctp sctp;
- struct rte_flow_item_icmp icmp;
- };
- } spec, mask;
-
- memset(&spec, 0, sizeof spec);
- memset(&mask, 0, sizeof mask);
+
+ memset(spec, 0, sizeof *spec);
+ memset(mask, 0, sizeof *mask);
/* Eth */
if (!eth_addr_is_zero(match->wc.masks.dl_src) ||
!eth_addr_is_zero(match->wc.masks.dl_dst)) {
- memcpy(&spec.eth.dst, &match->flow.dl_dst, sizeof spec.eth.dst);
- memcpy(&spec.eth.src, &match->flow.dl_src, sizeof spec.eth.src);
- spec.eth.type = match->flow.dl_type;
+ memcpy(&spec->eth.dst, &match->flow.dl_dst, sizeof spec->eth.dst);
+ memcpy(&spec->eth.src, &match->flow.dl_src, sizeof spec->eth.src);
+ spec->eth.type = match->flow.dl_type;
- memcpy(&mask.eth.dst, &match->wc.masks.dl_dst, sizeof mask.eth.dst);
- memcpy(&mask.eth.src, &match->wc.masks.dl_src, sizeof mask.eth.src);
- mask.eth.type = match->wc.masks.dl_type;
+ memcpy(&mask->eth.dst, &match->wc.masks.dl_dst, sizeof mask->eth.dst);
+ memcpy(&mask->eth.src, &match->wc.masks.dl_src, sizeof mask->eth.src);
+ mask->eth.type = match->wc.masks.dl_type;
- add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_ETH,
- &spec.eth, &mask.eth);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_ETH,
+ &spec->eth, &mask->eth);
} else {
/*
* If user specifies a flow (like UDP flow) without L2 patterns,
@@ -466,41 +454,41 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev,
* NIC (such as XL710) doesn't support that. Below is a workaround,
* which simply matches any L2 pkts.
*/
- add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_ETH, NULL, NULL);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_ETH, NULL, NULL);
}
/* VLAN */
if (match->wc.masks.vlans[0].tci && match->flow.vlans[0].tci) {
- spec.vlan.tci = match->flow.vlans[0].tci & ~htons(VLAN_CFI);
- mask.vlan.tci = match->wc.masks.vlans[0].tci & ~htons(VLAN_CFI);
+ spec->vlan.tci = match->flow.vlans[0].tci & ~htons(VLAN_CFI);
+ mask->vlan.tci = match->wc.masks.vlans[0].tci & ~htons(VLAN_CFI);
/* Match any protocols. */
- mask.vlan.inner_type = 0;
+ mask->vlan.inner_type = 0;
- add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_VLAN,
- &spec.vlan, &mask.vlan);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_VLAN,
+ &spec->vlan, &mask->vlan);
}
/* IP v4 */
if (match->flow.dl_type == htons(ETH_TYPE_IP)) {
- spec.ipv4.hdr.type_of_service = match->flow.nw_tos;
- spec.ipv4.hdr.time_to_live = match->flow.nw_ttl;
- spec.ipv4.hdr.next_proto_id = match->flow.nw_proto;
- spec.ipv4.hdr.src_addr = match->flow.nw_src;
- spec.ipv4.hdr.dst_addr = match->flow.nw_dst;
+ spec->ipv4.hdr.type_of_service = match->flow.nw_tos;
+ spec->ipv4.hdr.time_to_live = match->flow.nw_ttl;
+ spec->ipv4.hdr.next_proto_id = match->flow.nw_proto;
+ spec->ipv4.hdr.src_addr = match->flow.nw_src;
+ spec->ipv4.hdr.dst_addr = match->flow.nw_dst;
- mask.ipv4.hdr.type_of_service = match->wc.masks.nw_tos;
- mask.ipv4.hdr.time_to_live = match->wc.masks.nw_ttl;
- mask.ipv4.hdr.next_proto_id = match->wc.masks.nw_proto;
- mask.ipv4.hdr.src_addr = match->wc.masks.nw_src;
- mask.ipv4.hdr.dst_addr = match->wc.masks.nw_dst;
+ mask->ipv4.hdr.type_of_service = match->wc.masks.nw_tos;
+ mask->ipv4.hdr.time_to_live = match->wc.masks.nw_ttl;
+ mask->ipv4.hdr.next_proto_id = match->wc.masks.nw_proto;
+ mask->ipv4.hdr.src_addr = match->wc.masks.nw_src;
+ mask->ipv4.hdr.dst_addr = match->wc.masks.nw_dst;
- add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_IPV4,
- &spec.ipv4, &mask.ipv4);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV4,
+ &spec->ipv4, &mask->ipv4);
/* Save proto for L4 protocol setup. */
- proto = spec.ipv4.hdr.next_proto_id &
- mask.ipv4.hdr.next_proto_id;
+ proto = spec->ipv4.hdr.next_proto_id &
+ mask->ipv4.hdr.next_proto_id;
}
if (proto != IPPROTO_ICMP && proto != IPPROTO_UDP &&
@@ -509,79 +497,107 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev,
match->wc.masks.tp_dst ||
match->wc.masks.tcp_flags)) {
VLOG_DBG("L4 Protocol (%u) not supported", proto);
- ret = -1;
- goto out;
+ return -1;
}
if ((match->wc.masks.tp_src && match->wc.masks.tp_src != OVS_BE16_MAX) ||
(match->wc.masks.tp_dst && match->wc.masks.tp_dst != OVS_BE16_MAX)) {
- ret = -1;
- goto out;
+ return -1;
}
switch (proto) {
case IPPROTO_TCP:
- spec.tcp.hdr.src_port = match->flow.tp_src;
- spec.tcp.hdr.dst_port = match->flow.tp_dst;
- spec.tcp.hdr.data_off = ntohs(match->flow.tcp_flags) >> 8;
- spec.tcp.hdr.tcp_flags = ntohs(match->flow.tcp_flags) & 0xff;
+ spec->tcp.hdr.src_port = match->flow.tp_src;
+ spec->tcp.hdr.dst_port = match->flow.tp_dst;
+ spec->tcp.hdr.data_off = ntohs(match->flow.tcp_flags) >> 8;
+ spec->tcp.hdr.tcp_flags = ntohs(match->flow.tcp_flags) & 0xff;
- mask.tcp.hdr.src_port = match->wc.masks.tp_src;
- mask.tcp.hdr.dst_port = match->wc.masks.tp_dst;
- mask.tcp.hdr.data_off = ntohs(match->wc.masks.tcp_flags) >> 8;
- mask.tcp.hdr.tcp_flags = ntohs(match->wc.masks.tcp_flags) & 0xff;
+ mask->tcp.hdr.src_port = match->wc.masks.tp_src;
+ mask->tcp.hdr.dst_port = match->wc.masks.tp_dst;
+ mask->tcp.hdr.data_off = ntohs(match->wc.masks.tcp_flags) >> 8;
+ mask->tcp.hdr.tcp_flags = ntohs(match->wc.masks.tcp_flags) & 0xff;
- add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_TCP,
- &spec.tcp, &mask.tcp);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_TCP,
+ &spec->tcp, &mask->tcp);
/* proto == TCP and ITEM_TYPE_TCP, thus no need for proto match. */
- mask.ipv4.hdr.next_proto_id = 0;
+ mask->ipv4.hdr.next_proto_id = 0;
break;
case IPPROTO_UDP:
- spec.udp.hdr.src_port = match->flow.tp_src;
- spec.udp.hdr.dst_port = match->flow.tp_dst;
+ spec->udp.hdr.src_port = match->flow.tp_src;
+ spec->udp.hdr.dst_port = match->flow.tp_dst;
- mask.udp.hdr.src_port = match->wc.masks.tp_src;
- mask.udp.hdr.dst_port = match->wc.masks.tp_dst;
+ mask->udp.hdr.src_port = match->wc.masks.tp_src;
+ mask->udp.hdr.dst_port = match->wc.masks.tp_dst;
- add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_UDP,
- &spec.udp, &mask.udp);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_UDP,
+ &spec->udp, &mask->udp);
/* proto == UDP and ITEM_TYPE_UDP, thus no need for proto match. */
- mask.ipv4.hdr.next_proto_id = 0;
+ mask->ipv4.hdr.next_proto_id = 0;
break;
case IPPROTO_SCTP:
- spec.sctp.hdr.src_port = match->flow.tp_src;
- spec.sctp.hdr.dst_port = match->flow.tp_dst;
+ spec->sctp.hdr.src_port = match->flow.tp_src;
+ spec->sctp.hdr.dst_port = match->flow.tp_dst;
- mask.sctp.hdr.src_port = match->wc.masks.tp_src;
- mask.sctp.hdr.dst_port = match->wc.masks.tp_dst;
+ mask->sctp.hdr.src_port = match->wc.masks.tp_src;
+ mask->sctp.hdr.dst_port = match->wc.masks.tp_dst;
- add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_SCTP,
- &spec.sctp, &mask.sctp);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_SCTP,
+ &spec->sctp, &mask->sctp);
/* proto == SCTP and ITEM_TYPE_SCTP, thus no need for proto match. */
- mask.ipv4.hdr.next_proto_id = 0;
+ mask->ipv4.hdr.next_proto_id = 0;
break;
case IPPROTO_ICMP:
- spec.icmp.hdr.icmp_type = (uint8_t) ntohs(match->flow.tp_src);
- spec.icmp.hdr.icmp_code = (uint8_t) ntohs(match->flow.tp_dst);
+ spec->icmp.hdr.icmp_type = (uint8_t) ntohs(match->flow.tp_src);
+ spec->icmp.hdr.icmp_code = (uint8_t) ntohs(match->flow.tp_dst);
- mask.icmp.hdr.icmp_type = (uint8_t) ntohs(match->wc.masks.tp_src);
- mask.icmp.hdr.icmp_code = (uint8_t) ntohs(match->wc.masks.tp_dst);
+ mask->icmp.hdr.icmp_type = (uint8_t) ntohs(match->wc.masks.tp_src);
+ mask->icmp.hdr.icmp_code = (uint8_t) ntohs(match->wc.masks.tp_dst);
- add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_ICMP,
- &spec.icmp, &mask.icmp);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_ICMP,
+ &spec->icmp, &mask->icmp);
/* proto == ICMP and ITEM_TYPE_ICMP, thus no need for proto match. */
- mask.ipv4.hdr.next_proto_id = 0;
+ mask->ipv4.hdr.next_proto_id = 0;
break;
}
- add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_END, NULL, NULL);
+ add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_END, NULL, NULL);
+
+ return 0;
+}
+
+static int
+netdev_offload_dpdk_add_flow(struct netdev *netdev,
+ const struct match *match,
+ struct nlattr *nl_actions OVS_UNUSED,
+ size_t actions_len OVS_UNUSED,
+ const ovs_u128 *ufid,
+ struct offload_info *info)
+{
+ const struct rte_flow_attr flow_attr = {
+ .group = 0,
+ .priority = 0,
+ .ingress = 1,
+ .egress = 0
+ };
+ struct flow_patterns patterns = { .items = NULL, .cnt = 0 };
+ struct flow_actions actions = { .actions = NULL, .cnt = 0 };
+ struct rte_flow *flow;
+ struct rte_flow_error error;
+ int ret = 0;
+ struct flow_items spec, mask;
+
+ ret = parse_flow_match(&patterns, &spec, &mask, match);
+ if (ret) {
+ ret = -1;
+ goto out;
+ }
struct rte_flow_action_mark mark;
struct action_rss_data *rss;
--
2.14.5
More information about the dev
mailing list