DPDK usage discussions
 help / color / mirror / Atom feed
From: Adrien Mazarguil <adrien.mazarguil@6wind.com>
To: 曾懷恩 <the@csie.io>
Cc: 張敬昊 <frank@csie.io>, users@dpdk.org
Subject: Re: [dpdk-users] Flow director struct rte_flow_item_raw guild
Date: Thu, 9 May 2019 14:38:33 +0200	[thread overview]
Message-ID: <20190509123833.GF4284@6wind.com> (raw)
In-Reply-To: <859A28C4-16C1-4397-9326-A3BEDB1AD73E@csie.io>

Hi,

On Thu, May 09, 2019 at 11:51:14AM +0800, 曾懷恩 wrote:
> Hi, 敬昊,
> 
> Sorry for my question is not clear.
> 
> My question is, should I declare a variable to store the bytes I want to filter and just assign it to the pattern element?

Yes, this is how it should work.

> 
> Therefore, will the result of init flow filter be like 
> 
> 	struct rte_flow_item_raw raw_spec, raw_mask; 

Just make sure to properly initialize these objects, especially unused
fields. I'll assume something like that was done at some point:

 memset(&raw_spec, 0, sizeof(raw_spec));
 memset(&raw_mask, 0, sizeof(raw_mask));

> 	uint8_t spec[12] = {0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}; 
> 	 uint8_t mask[12] = {0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff};

This mask will match the first 1st, 2nd and 12th bytes exactly, with
anything in between, i.e. IPv4's EtherType and ICMP protocol type in
subsequent IPv4 header. Seems correct.

> 	*(uint32_t *)&raw_spec = 0x40000000;
> 	raw_spec.offset = 12;
> 	raw_spec.limit = 12;

Note .limit is only meaningful when .search is enabled.

> 	raw_spec.length = 24;

This is the length of the byte pattern itself (12), it must not cover the
offset (12 + 12). In short raw_spec.length must be sizeof(spec).

> 	raw_spec.pattern = spec;
> 	raw_mask.pattern = mask;
> 	pattern[0].type = RTE_FLOW_ITEM_TYPE_RAW;
> 	pattern[0].spec = &raw_spec;
> 	pattern[0].mask = &raw_mask;
> 
> if i want to filter out icmp packet?

Almost... One issue is that, since you chose to provide your own empty mask
(raw_mask) instead of relying on the default one which happens to match all
fields exactly, you must also mask the relevant spec bits, e.g.:

 raw_mask.offset = -1;
 raw_mask.length = -1;

The only exception to this kind of masking is "raw_mask.pattern", which
should contain a valid pointer instead of a bit-mask when raw_spec.length &
raw_mask.length is nonzero.

Documentation example relies on the default mask so this part may not be
quite clear, so let me clarify:

Bit-masking does not apply to pointers the way it does with other types as
it makes no sense to mask them partially. They are either NULL or valid, so
in this specific case, the engine relies on another field (length) to
determine if spec.pattern can be dereferenced.

If length is nonzero, then mask.pattern is checked. If non-NULL, it can be
dereferenced, otherwise the engine defaults to matching "length" bytes from
spec.pattern exactly, hence the use of NULL as the default value in
rte_flow_item_raw_mask.

To summarize, here's how I'd rewrite your example (relying on C99 syntax to
initialize unspecified fields to zero without explicit memset() calls):

 uint8_t raw_pat_data[] = { [0] = 0x08, [1] = 0x00, [11] = 0x01 };
 uint8_t raw_pat_mask[] = { [0] = 0xff, [1] = 0xff, [11] = 0xff };
 struct rte_flow_item_raw raw_spec = {
     .offset = 12,
     .length = sizeof(raw_pat_data),
     .pattern = raw_pat_data,
 };
 struct rte_flow_item_raw raw_mask = {
     .offset = -1,
     .length = -1,
     .pattern = raw_pat_mask,
 };
 struct rte_flow_item pattern[] = {
     {
         .type = RTE_FLOW_ITEM_TYPE_RAW,
         .spec = &raw_spec,
         .mask = &raw_mask,
     },
     {
         .type = RTE_FLOW_ITEM_TYPE_END,
     },
 };

Or alternatively, using two pattern items and relying on the default mask to
avoid punching holes in the byte pattern:

 struct rte_flow_item_raw raw_spec[] = {
     {
         .offset = 12,
         .length = 2,
         .pattern = (uint8_t []){ 0x08, 0x00 },
     },
     {
         .offset = 23, /* or 11 with .relative = 1 */
         .length = 1,
         .pattern = (uint8_t []){ 0x01 },
     },
 };
 struct rte_flow_item pattern[] = {
     {
         .type = RTE_FLOW_ITEM_TYPE_RAW,
         .spec = &raw_spec[0],
     },
     {
         .type = RTE_FLOW_ITEM_TYPE_RAW,
         .spec = &raw_spec[1],
     },
     {
         .type = RTE_FLOW_ITEM_TYPE_END,
     },
 };

Now in practice I never had a chance to use this pattern item with any PMDs
that support it, so I don't know close their behavior sticks to what I just
described, especially regarding the handling of mask.pattern. Do not
hesitate to report odd or inconsistent behavior in any case.

-- 
Adrien Mazarguil
6WIND

  reply	other threads:[~2019-05-09 12:38 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-09  2:01 曾懷恩
2019-05-09  2:10 ` 張敬昊
2019-05-09  3:51   ` 曾懷恩
2019-05-09 12:38     ` Adrien Mazarguil [this message]
2019-05-10  6:38       ` 曾懷恩
2019-05-10 13:44         ` Adrien Mazarguil
2019-05-10 18:20           ` Huai-En Tseng
2019-05-13  8:49             ` Adrien Mazarguil
2019-05-16  5:34               ` 曾懷恩
2019-05-16  6:00                 ` Tom Barbette
2019-05-22  3:18                   ` 曾懷恩

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190509123833.GF4284@6wind.com \
    --to=adrien.mazarguil@6wind.com \
    --cc=frank@csie.io \
    --cc=the@csie.io \
    --cc=users@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).