summaryrefslogtreecommitdiff
path: root/lib/netdev-offload-dpdk.c
diff options
context:
space:
mode:
authorEli Britstein <elibr@mellanox.com>2020-07-08 06:38:26 +0000
committerIlya Maximets <i.maximets@ovn.org>2020-07-08 17:51:33 +0200
commit85270e99630530300e579ebd3d52b3a11ffbe2bc (patch)
treee4689d5016b76e5b22b9f85232b1650a4d3eb772 /lib/netdev-offload-dpdk.c
parenta79eae87abe4031353c10f775e1948b4a2c820c3 (diff)
downloadopenvswitch-85270e99630530300e579ebd3d52b3a11ffbe2bc.tar.gz
netdev-offload-dpdk: Add IPv6 pattern matching.
Add support for IPv6 pattern matching for offloading flows. Signed-off-by: Eli Britstein <elibr@mellanox.com> Reviewed-by: Roni Bar Yanai <roniba@mellanox.com> Acked-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Diffstat (limited to 'lib/netdev-offload-dpdk.c')
-rw-r--r--lib/netdev-offload-dpdk.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c
index 426b8414f..110f6e829 100644
--- a/lib/netdev-offload-dpdk.c
+++ b/lib/netdev-offload-dpdk.c
@@ -16,6 +16,8 @@
*/
#include <config.h>
+#include <sys/types.h>
+#include <netinet/ip6.h>
#include <rte_flow.h>
#include "cmap.h"
@@ -294,6 +296,41 @@ dump_flow_pattern(struct ds *s, const struct rte_flow_item *item)
tcp_mask->hdr.tcp_flags);
}
ds_put_cstr(s, "/ ");
+ } else if (item->type == RTE_FLOW_ITEM_TYPE_IPV6) {
+ const struct rte_flow_item_ipv6 *ipv6_spec = item->spec;
+ const struct rte_flow_item_ipv6 *ipv6_mask = item->mask;
+
+ char addr_str[INET6_ADDRSTRLEN];
+ char mask_str[INET6_ADDRSTRLEN];
+ struct in6_addr addr, mask;
+
+ ds_put_cstr(s, "ipv6 ");
+ if (ipv6_spec) {
+ if (!ipv6_mask) {
+ ipv6_mask = &rte_flow_item_ipv6_mask;
+ }
+ memcpy(&addr, ipv6_spec->hdr.src_addr, sizeof addr);
+ 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);
+
+ 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(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,
+ ntohl(ipv6_spec->hdr.vtc_flow),
+ ntohl(ipv6_mask->hdr.vtc_flow));
+ DUMP_PATTERN_ITEM(ipv6_mask->hdr.hop_limits, "hop", "%"PRIu8,
+ ipv6_spec->hdr.hop_limits,
+ ipv6_mask->hdr.hop_limits);
+ }
+ ds_put_cstr(s, "/ ");
} else {
ds_put_format(s, "unknown rte flow pattern (%d)\n", item->type);
}
@@ -644,6 +681,44 @@ parse_flow_match(struct flow_patterns *patterns,
}
consumed_masks->nw_frag = 0;
+ /* IP v6 */
+ if (match->flow.dl_type == htons(ETH_TYPE_IPV6)) {
+ struct rte_flow_item_ipv6 *spec, *mask;
+
+ spec = xzalloc(sizeof *spec);
+ mask = xzalloc(sizeof *mask);
+
+ spec->hdr.proto = match->flow.nw_proto;
+ spec->hdr.hop_limits = match->flow.nw_ttl;
+ spec->hdr.vtc_flow =
+ htonl((uint32_t) match->flow.nw_tos << RTE_IPV6_HDR_TC_SHIFT);
+ memcpy(spec->hdr.src_addr, &match->flow.ipv6_src,
+ sizeof spec->hdr.src_addr);
+ memcpy(spec->hdr.dst_addr, &match->flow.ipv6_dst,
+ sizeof spec->hdr.dst_addr);
+
+ mask->hdr.proto = match->wc.masks.nw_proto;
+ mask->hdr.hop_limits = match->wc.masks.nw_ttl;
+ mask->hdr.vtc_flow =
+ htonl((uint32_t) match->wc.masks.nw_tos << RTE_IPV6_HDR_TC_SHIFT);
+ memcpy(mask->hdr.src_addr, &match->wc.masks.ipv6_src,
+ sizeof mask->hdr.src_addr);
+ memcpy(mask->hdr.dst_addr, &match->wc.masks.ipv6_dst,
+ sizeof mask->hdr.dst_addr);
+
+ consumed_masks->nw_proto = 0;
+ consumed_masks->nw_ttl = 0;
+ consumed_masks->nw_tos = 0;
+ 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);
+
+ /* Save proto for L4 protocol setup. */
+ proto = spec->hdr.proto & mask->hdr.proto;
+ next_proto_mask = &mask->hdr.proto;
+ }
+
if (proto != IPPROTO_ICMP && proto != IPPROTO_UDP &&
proto != IPPROTO_SCTP && proto != IPPROTO_TCP &&
(match->wc.masks.tp_src ||