From patchwork Wed Nov 16 16:23:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 17036 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id C64D2D4A8; Wed, 16 Nov 2016 17:25:26 +0100 (CET) Received: from mail-wm0-f50.google.com (mail-wm0-f50.google.com [74.125.82.50]) by dpdk.org (Postfix) with ESMTP id 0148A5599 for ; Wed, 16 Nov 2016 17:24:35 +0100 (CET) Received: by mail-wm0-f50.google.com with SMTP id t79so83428030wmt.0 for ; Wed, 16 Nov 2016 08:24:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=UIEFnNmnJSVW76761LS57op7YwBMx+dgFVLYJl9em28=; b=sAEGBLlRwYEwkneyG0WaeglCeTf++slvajR2OKCi4NRnvmYWMWL3HWMQM1emB15z5x +KRxKkB5/V/3g9ybqMJ49FCKqLgYfK4F1wmEFOKZXDZJLWHzhtADfZu2oVPSa+UYGVfE Dd/fpn4kCa6y7lvM/1KDxqN6bcA3Jum1FzGwN/rdeXwb44Kc4n7ayLyCPPLfO2D9AoEk d2sQKvYbN8tfd1IPvQJmKv2XAYJWES/fWTooHmoZSRiRgzArrJCgVfoiwhKWP4+NWflm e1lR31o+eYL+GWWr9Z6gbcfHDwXmavboF8s4C9WHBiYfoXZzvIxiY+fMPfTz5bjamaCu xWxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=UIEFnNmnJSVW76761LS57op7YwBMx+dgFVLYJl9em28=; b=SGm/TGtRoZzcKM03igrBhgtiDwdtdaQUs59dkW6QID8S9nrU2tTSGglrUDeeTa05bC bk5s90HzPdkBgG73tLwB6Fk+PGQBmtEX5pWqljKDZcO0FRc4CO1A/uacp9Vx+PnVHhpA JoPznvCi4v2gFhSF73L67RGXhxtn6CwER/WGpC0Lycf74y8oHNHOR47crmUQVyb4YD3Y YrPclyW/WVmftvSe5pp8TmLkWkHRg7Ql530fv2tOkk+LHIPnij4Uc97POwkLMOS1w/7v i6t8Y9OayFkNoNi8NyVTPfU7N+LWB7cFc4HhvSVAvGv2mBD0GnrTXJMj4aVZkhysc6eh tZ7Q== X-Gm-Message-State: ABUngveBP7Cr45D+3gWGKxsWxTETvY2sdBgr3kVRSRxpEsu0U9k+MwiSTUeM3WCHhRkmo49y X-Received: by 10.28.236.83 with SMTP id k80mr10295967wmh.0.1479313475555; Wed, 16 Nov 2016 08:24:35 -0800 (PST) Received: from 6wind.com (guy78-3-82-239-227-177.fbx.proxad.net. [82.239.227.177]) by smtp.gmail.com with ESMTPSA id x140sm10941242wme.19.2016.11.16.08.24.33 (version=TLS1_2 cipher=AES128-SHA bits=128/128); Wed, 16 Nov 2016 08:24:34 -0800 (PST) From: Adrien Mazarguil To: dev@dpdk.org Cc: Thomas Monjalon , Pablo de Lara , Olivier Matz Date: Wed, 16 Nov 2016 17:23:38 +0100 Message-Id: <2d37e8ee1c613557e94acef94e381b72b2a535ce.1479309720.git.adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: References: Subject: [dpdk-dev] [PATCH 12/22] app/testpmd: add rte_flow item spec handler X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add parser code to fully set individual fields of pattern item specification structures, using the following operators: - fix: sets field and applies full bit-mask for perfect matching. - spec: sets field without modifying its bit-mask. - last: sets upper value of the spec => last range. - mask: sets bit-mask affecting both spec and last from arbitrary value. Signed-off-by: Adrien Mazarguil --- app/test-pmd/cmdline_flow.c | 110 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index e70e8e2..790b4b8 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -89,6 +89,10 @@ enum index { /* Validate/create pattern. */ PATTERN, + ITEM_PARAM_FIX, + ITEM_PARAM_SPEC, + ITEM_PARAM_LAST, + ITEM_PARAM_MASK, ITEM_NEXT, ITEM_END, ITEM_VOID, @@ -121,6 +125,7 @@ struct context { uint16_t port; /**< Current port ID (for completions). */ uint32_t objdata; /**< Object-specific data. */ void *object; /**< Address of current object for relative offsets. */ + void *objmask; /**< Object a full mask must be written to. */ }; /** Token argument. */ @@ -267,6 +272,14 @@ static const enum index next_list_attr[] = { 0, }; +static const enum index item_param[] = { + ITEM_PARAM_FIX, + ITEM_PARAM_SPEC, + ITEM_PARAM_LAST, + ITEM_PARAM_MASK, + 0, +}; + static const enum index next_item[] = { ITEM_END, ITEM_VOID, @@ -287,6 +300,8 @@ static int parse_init(struct context *, const struct token *, static int parse_vc(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); +static int parse_vc_spec(struct context *, const struct token *, + const char *, unsigned int, void *, unsigned int); static int parse_destroy(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -492,6 +507,26 @@ static const struct token token_list[] = { .next = NEXT(next_item), .call = parse_vc, }, + [ITEM_PARAM_FIX] = { + .name = "fix", + .help = "match value perfectly (with full bit-mask)", + .call = parse_vc_spec, + }, + [ITEM_PARAM_SPEC] = { + .name = "spec", + .help = "match value according to configured bit-mask", + .call = parse_vc_spec, + }, + [ITEM_PARAM_LAST] = { + .name = "last", + .help = "specify upper bound to establish a range", + .call = parse_vc_spec, + }, + [ITEM_PARAM_MASK] = { + .name = "mask", + .help = "specify bit-mask with relevant bits set to one", + .call = parse_vc_spec, + }, [ITEM_NEXT] = { .name = "/", .help = "specify next pattern item", @@ -605,6 +640,7 @@ parse_init(struct context *ctx, const struct token *token, memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); ctx->objdata = 0; ctx->object = out; + ctx->objmask = NULL; return len; } @@ -632,11 +668,13 @@ parse_vc(struct context *ctx, const struct token *token, out->command = ctx->curr; ctx->objdata = 0; ctx->object = out; + ctx->objmask = NULL; out->args.vc.data = (uint8_t *)out + size; return len; } ctx->objdata = 0; ctx->object = &out->args.vc.attr; + ctx->objmask = NULL; switch (ctx->curr) { case GROUP: case PRIORITY: @@ -652,6 +690,7 @@ parse_vc(struct context *ctx, const struct token *token, (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), sizeof(double)); ctx->object = out->args.vc.pattern; + ctx->objmask = NULL; return len; case ACTIONS: out->args.vc.actions = @@ -660,6 +699,7 @@ parse_vc(struct context *ctx, const struct token *token, out->args.vc.pattern_n), sizeof(double)); ctx->object = out->args.vc.actions; + ctx->objmask = NULL; return len; default: if (!token->priv) @@ -682,6 +722,7 @@ parse_vc(struct context *ctx, const struct token *token, }; ++out->args.vc.pattern_n; ctx->object = item; + ctx->objmask = NULL; } else { const struct parse_action_priv *priv = token->priv; struct rte_flow_action *action = @@ -698,6 +739,7 @@ parse_vc(struct context *ctx, const struct token *token, }; ++out->args.vc.actions_n; ctx->object = action; + ctx->objmask = NULL; } memset(data, 0, data_size); out->args.vc.data = data; @@ -705,6 +747,60 @@ parse_vc(struct context *ctx, const struct token *token, return len; } +/** Parse pattern item parameter type. */ +static int +parse_vc_spec(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + struct buffer *out = buf; + struct rte_flow_item *item; + uint32_t data_size; + int index; + int objmask = 0; + + (void)size; + /* Token name must match. */ + if (parse_default(ctx, token, str, len, NULL, 0) < 0) + return -1; + /* Parse parameter types. */ + switch (ctx->curr) { + case ITEM_PARAM_FIX: + index = 0; + objmask = 1; + break; + case ITEM_PARAM_SPEC: + index = 0; + break; + case ITEM_PARAM_LAST: + index = 1; + break; + case ITEM_PARAM_MASK: + index = 2; + break; + default: + return -1; + } + /* Nothing else to do if there is no buffer. */ + if (!out) + return len; + if (!out->args.vc.pattern_n) + return -1; + item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; + data_size = ctx->objdata / 3; /* spec, last, mask */ + /* Point to selected object. */ + ctx->object = out->args.vc.data + (data_size * index); + if (objmask) { + ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */ + item->mask = ctx->objmask; + } else + ctx->objmask = NULL; + /* Update relevant item pointer. */ + *((const void **[]){ &item->spec, &item->last, &item->mask })[index] = + ctx->object; + return len; +} + /** Parse tokens for destroy command. */ static int parse_destroy(struct context *ctx, const struct token *token, @@ -727,6 +823,7 @@ parse_destroy(struct context *ctx, const struct token *token, out->command = ctx->curr; ctx->objdata = 0; ctx->object = out; + ctx->objmask = NULL; out->args.destroy.rule = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), sizeof(double)); @@ -737,6 +834,7 @@ parse_destroy(struct context *ctx, const struct token *token, return -1; ctx->objdata = 0; ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++; + ctx->objmask = NULL; return len; } @@ -762,6 +860,7 @@ parse_flush(struct context *ctx, const struct token *token, out->command = ctx->curr; ctx->objdata = 0; ctx->object = out; + ctx->objmask = NULL; } return len; } @@ -788,6 +887,7 @@ parse_query(struct context *ctx, const struct token *token, out->command = ctx->curr; ctx->objdata = 0; ctx->object = out; + ctx->objmask = NULL; } return len; } @@ -849,6 +949,7 @@ parse_list(struct context *ctx, const struct token *token, out->command = ctx->curr; ctx->objdata = 0; ctx->object = out; + ctx->objmask = NULL; out->args.list.group = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), sizeof(double)); @@ -859,6 +960,7 @@ parse_list(struct context *ctx, const struct token *token, return -1; ctx->objdata = 0; ctx->object = out->args.list.group + out->args.list.group_n++; + ctx->objmask = NULL; return len; } @@ -891,6 +993,7 @@ parse_int(struct context *ctx, const struct token *token, return len; buf = (uint8_t *)ctx->object + arg->offset; size = arg->size; +objmask: switch (size) { case sizeof(uint8_t): *(uint8_t *)buf = u; @@ -907,6 +1010,11 @@ parse_int(struct context *ctx, const struct token *token, default: goto error; } + if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) { + u = -1; + buf = (uint8_t *)ctx->objmask + arg->offset; + goto objmask; + } return len; error: push_args(ctx, arg); @@ -927,6 +1035,7 @@ parse_port(struct context *ctx, const struct token *token, else { ctx->objdata = 0; ctx->object = out; + ctx->objmask = NULL; size = sizeof(*out); } ret = parse_int(ctx, token, str, len, out, size); @@ -1033,6 +1142,7 @@ cmd_flow_context_init(struct context *ctx) ctx->port = 0; ctx->objdata = 0; ctx->object = NULL; + ctx->objmask = NULL; } /** Parse a token (cmdline API). */