diff options
author | Eli Britstein <elibr@mellanox.com> | 2020-07-08 06:38:26 +0000 |
---|---|---|
committer | Ilya Maximets <i.maximets@ovn.org> | 2020-07-08 17:51:33 +0200 |
commit | 85270e99630530300e579ebd3d52b3a11ffbe2bc (patch) | |
tree | e4689d5016b76e5b22b9f85232b1650a4d3eb772 /lib/netdev-offload-dpdk.c | |
parent | a79eae87abe4031353c10f775e1948b4a2c820c3 (diff) | |
download | openvswitch-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.c | 75 |
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 || |