From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by dpdk.space (Postfix) with ESMTP id B10FCA0096 for ; Thu, 9 May 2019 14:38:36 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 9B0343977; Thu, 9 May 2019 14:38:36 +0200 (CEST) Received: from mail-wm1-f65.google.com (mail-wm1-f65.google.com [209.85.128.65]) by dpdk.org (Postfix) with ESMTP id D1AF32082 for ; Thu, 9 May 2019 14:38:35 +0200 (CEST) Received: by mail-wm1-f65.google.com with SMTP id f2so3016729wmj.3 for ; Thu, 09 May 2019 05:38:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind.com; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to; bh=xKILgMHFZ6xif1rVfoqVXYS5/WNbVTIMJaAi4vJu5v8=; b=KBvpYTUPdbPChDLDxgxH66ERw5TfBr0NBx3Znt/m2bWGOS+vO1q2q7DPy6EIyOiDrN pYE62RxH+XRjk/s3d/5iA2lxL7SwfsxkQuCkHFq78djaOvNOs99R/819kp2sCIskXaa2 NOhisJLRpCQnFMH3rcMiQgUwayVcvZeGtV1q4pF/alvQvl+iLui/yArT5JEGtd1oRM3B cimSL+9dhvgLh02LDah91MmMk2hs8MdIWBFVirTXzyf0sd3UTIgfJPHNxIOhJvpkbdcp WY3XSwlMIC9FwLS6+Zmgs/3IxLUKCf+FSy5nMMX4l7Wcwl9k0ndtPHN36lHBS2TFufGF BTCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to; bh=xKILgMHFZ6xif1rVfoqVXYS5/WNbVTIMJaAi4vJu5v8=; b=WrY1XzhBUCOyEDUtlJd76IRGuYjzKwwS3tPSfrwVkYY58MJprcwB6f7TyI0Q7fhcYU ARADSOfar5BjU7yY0faKjgsl1lSSBK9ma0FisLEbVfm3ZuET+My8DJ6+EQQTOdS4+PA1 pDML6SQQAd+zwm4wax+ny5JbmcAa4+q9KaN0xQQQuLzIz/oK9B7o+aoNtWa5SLc33ipy jFIyKiZPv+SdC3bs8MAFdxiX9jmm7vg4uyP+3Q3pPOveZaGQBddzUJmsg7sZh+gd8DsL FFPt2P9bCoD5IDO+zGTtm/PwrS2jK09r14qag5ZbRSCXPSjCZsMKH70WGxwKUeJ3VjoE gPJA== X-Gm-Message-State: APjAAAU4w3S4Q4rYV2xBG7JdnCmgE6vnDYVA0tpGSTodz/dmGu5bUaQv 6tCqB5415DF4KenrsOopnGkOsKQkYykrGA== X-Google-Smtp-Source: APXvYqzh2SIW3ETicVd5R7F1QGHgb2omJHQ7opKUI7Bk/SamOIcOfGmrClEfwdqTJO/Y6BXw1JU59Q== X-Received: by 2002:a1c:5f02:: with SMTP id t2mr2735419wmb.19.1557405515601; Thu, 09 May 2019 05:38:35 -0700 (PDT) Received: from 6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id n17sm1813758wrw.77.2019.05.09.05.38.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 May 2019 05:38:34 -0700 (PDT) Date: Thu, 9 May 2019 14:38:33 +0200 From: Adrien Mazarguil To: =?utf-8?B?5pu+5oe35oGp?= Cc: =?utf-8?B?5by15pWs5piK?= , users@dpdk.org Message-ID: <20190509123833.GF4284@6wind.com> References: <859A28C4-16C1-4397-9326-A3BEDB1AD73E@csie.io> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <859A28C4-16C1-4397-9326-A3BEDB1AD73E@csie.io> Subject: Re: [dpdk-users] Flow director struct rte_flow_item_raw guild X-BeenThere: users@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK usage discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: users-bounces@dpdk.org Sender: "users" 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