[ovs-dev] [PATCH V3 02/12] netdev-offload-dpdk: Add IPv6 pattern matching
Eli Britstein
elibr at mellanox.com
Mon Jun 29 07:45:22 UTC 2020
On 6/29/2020 1:42 AM, Ilya Maximets wrote:
> On 6/21/20 1:19 PM, Eli Britstein wrote:
>> Add support for IPv6 pattern matching for offloading flows.
>>
>> Signed-off-by: Eli Britstein <elibr at mellanox.com>
>> Reviewed-by: Roni Bar Yanai <roniba at mellanox.com>
>> ---
>> Documentation/howto/dpdk.rst | 2 +-
>> NEWS | 1 +
>> lib/netdev-offload-dpdk.c | 76 ++++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 78 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/howto/dpdk.rst b/Documentation/howto/dpdk.rst
>> index be950d7ce..8a0eee80c 100644
>> --- a/Documentation/howto/dpdk.rst
>> +++ b/Documentation/howto/dpdk.rst
>> @@ -385,7 +385,7 @@ The validated NICs are:
>> Supported protocols for hardware offload matches are:
>>
>> - L2: Ethernet, VLAN
>> -- L3: IPv4
>> +- L3: IPv4, IPv6
>> - L4: TCP, UDP, SCTP, ICMP
>>
>> Supported actions for hardware offload are:
>> diff --git a/NEWS b/NEWS
>> index 22cacda20..07e23316c 100644
>> --- a/NEWS
>> +++ b/NEWS
>> @@ -9,6 +9,7 @@ Post-v2.13.0
>> - DPDK:
>> * Deprecated DPDK pdump packet capture support removed.
>> * Deprecated DPDK ring ports (dpdkr) are no longer supported.
>> + * Add hardware offload support for matching IPv6 protocol.
> Not experimental? :)
OK. BTW, when do features stop being experimental but mainstream?
>
>> - Linux datapath:
>> * Support for kernel versions up to 5.5.x.
>> - AF_XDP:
>> diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c
>> index 2f1b42bf7..6b12e9ae3 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>
> Can we keep these in alphabetical order?
OK.
>
>>
>> #include "cmap.h"
>> @@ -321,6 +323,42 @@ dump_flow_pattern(struct ds *s, const struct rte_flow_item *item)
>> } else {
>> ds_put_cstr(s, " Mask = null\n");
>> }
>> + } 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 src_addr_str[INET6_ADDRSTRLEN];
>> + char dst_addr_str[INET6_ADDRSTRLEN];
>> +
>> + ds_put_cstr(s, "rte flow ipv6 pattern:\n");
>> + if (ipv6_spec) {
>> + ipv6_string_mapped(src_addr_str,
>> + (struct in6_addr *)&ipv6_spec->hdr.src_addr);
>> + ipv6_string_mapped(dst_addr_str,
>> + (struct in6_addr *)&ipv6_spec->hdr.dst_addr);
>> +
>> + ds_put_format(s, " Spec: vtc_flow=%#"PRIx32", proto=%"PRIu8","
>> + " hlim=%"PRIu8", src=%s, dst=%s\n",
>> + ntohl(ipv6_spec->hdr.vtc_flow), ipv6_spec->hdr.proto,
>> + ipv6_spec->hdr.hop_limits, src_addr_str,
>> + dst_addr_str);
>> + } else {
>> + ds_put_cstr(s, " Spec = null\n");
>> + }
>> + if (ipv6_mask) {
>> + ipv6_string_mapped(src_addr_str,
>> + (struct in6_addr *)&ipv6_mask->hdr.src_addr);
>> + ipv6_string_mapped(dst_addr_str,
>> + (struct in6_addr *)&ipv6_mask->hdr.dst_addr);
>> +
>> + ds_put_format(s, " Mask: vtc_flow=%#"PRIx32", proto=%#"PRIx8","
>> + " hlim=%#"PRIx8", src=%s, dst=%s\n",
>> + ntohl(ipv6_mask->hdr.vtc_flow), ipv6_mask->hdr.proto,
>> + ipv6_mask->hdr.hop_limits, src_addr_str,
>> + dst_addr_str);
>> + } else {
>> + ds_put_cstr(s, " Mask = null\n");
>> + }
>> } else {
>> ds_put_format(s, "unknown rte flow pattern (%d)\n", item->type);
>> }
>> @@ -658,6 +696,44 @@ parse_flow_match(struct flow_patterns *patterns,
>> /* ignore mask match for now */
>> 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 <<
> Please, add a space between the caset and a value.
> It also might look better if the whole right side of the assignment
> will be moved to the next line and joined.
OK
>
>> + 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);
> Ditto.
OK
>
>> + 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 */
> There should be period at the end of the comment.
OK
>
>> + 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 ||
>>
More information about the dev
mailing list