From patchwork Tue Oct 19 03:08:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jie Wang X-Patchwork-Id: 102130 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id CE1DDA0C45; Tue, 19 Oct 2021 05:09:10 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 94EB5410EE; Tue, 19 Oct 2021 05:09:10 +0200 (CEST) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mails.dpdk.org (Postfix) with ESMTP id 0B7B44003E for ; Tue, 19 Oct 2021 05:09:07 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10141"; a="251878073" X-IronPort-AV: E=Sophos;i="5.85,383,1624345200"; d="scan'208";a="251878073" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Oct 2021 20:09:06 -0700 X-IronPort-AV: E=Sophos;i="5.85,383,1624345200"; d="scan'208";a="493896962" Received: from dpdk.cd.intel.com ([10.240.178.133]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Oct 2021 20:09:03 -0700 From: Jie Wang To: dev@dpdk.org Cc: orika@nvidia.com, ferruh.yigit@intel.com, thomas@monjalon.net, andrew.rybchenko@oktetlabs.ru, xiaoyun.li@intel.com, stevex.yang@intel.com, jingjing.wu@intel.com, beilei.xing@intel.com, wenjun1.wu@intel.com, qi.z.zhang@intel.com, Jie Wang Date: Tue, 19 Oct 2021 11:08:24 +0800 Message-Id: <20211019030824.932102-4-jie1x.wang@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211019030824.932102-1-jie1x.wang@intel.com> References: <20211018093352.892788-1-jie1x.wang@intel.com> <20211019030824.932102-1-jie1x.wang@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v5 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add support for test-pmd to parse protocol pattern L2TPv2 and PPP. Signed-off-by: Wenjun Wu Signed-off-by: Jie Wang --- app/test-pmd/cmdline_flow.c | 251 ++++++++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index a90822b660..c1046e3e28 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -310,6 +310,23 @@ enum index { ITEM_PORT_REPRESENTOR_PORT_ID, ITEM_REPRESENTED_PORT, ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, + ITEM_L2TPV2, + ITEM_L2TPV2_COMMON, + ITEM_L2TPV2_COMMON_TYPE, + ITEM_L2TPV2_COMMON_TYPE_DATA_L, + ITEM_L2TPV2_COMMON_TYPE_CTRL, + ITEM_L2TPV2_MSG_DATA_L_LENGTH, + ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, + ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, + ITEM_L2TPV2_MSG_CTRL_LENGTH, + ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, + ITEM_L2TPV2_MSG_CTRL_SESSION_ID, + ITEM_L2TPV2_MSG_CTRL_NS, + ITEM_L2TPV2_MSG_CTRL_NR, + ITEM_PPP, + ITEM_PPP_ADDR, + ITEM_PPP_CTRL, + ITEM_PPP_PROTO_ID, /* Validate/create actions. */ ACTIONS, @@ -1018,6 +1035,8 @@ static const enum index next_item[] = { ITEM_CONNTRACK, ITEM_PORT_REPRESENTOR, ITEM_REPRESENTED_PORT, + ITEM_L2TPV2, + ITEM_PPP, END_SET, ZERO, }; @@ -1398,6 +1417,31 @@ static const enum index item_represented_port[] = { ZERO, }; +static const enum index item_l2tpv2[] = { + ITEM_L2TPV2_COMMON, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_l2tpv2_common[] = { + ITEM_L2TPV2_COMMON_TYPE, + ZERO, +}; + +static const enum index item_l2tpv2_common_type[] = { + ITEM_L2TPV2_COMMON_TYPE_DATA_L, + ITEM_L2TPV2_COMMON_TYPE_CTRL, + ZERO, +}; + +static const enum index item_ppp[] = { + ITEM_PPP_ADDR, + ITEM_PPP_CTRL, + ITEM_PPP_PROTO_ID, + ITEM_NEXT, + ZERO, +}; + static const enum index next_action[] = { ACTION_END, ACTION_VOID, @@ -1781,6 +1825,9 @@ static int parse_vc_conf(struct context *, const struct token *, static int parse_vc_item_ecpri_type(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); +static int parse_vc_item_l2tpv2_type(struct context *, const struct token *, + const char *, unsigned int, + void *, unsigned int); static int parse_vc_action_meter_color_type(struct context *, const struct token *, const char *, unsigned int, void *, @@ -3682,6 +3729,153 @@ static const struct token token_list[] = { item_param), .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), }, + [ITEM_L2TPV2] = { + .name = "l2tpv2", + .help = "match l2tpv2 header", + .priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), + .next = NEXT(item_l2tpv2), + .call = parse_vc, + }, + [ITEM_L2TPV2_COMMON] = { + .name = "common", + .help = "l2tpv2 common header", + .next = NEXT(item_l2tpv2_common), + }, + [ITEM_L2TPV2_COMMON_TYPE] = { + .name = "type", + .help = "type of common header", + .next = NEXT(item_l2tpv2_common_type), + .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)), + }, + [ITEM_L2TPV2_COMMON_TYPE_DATA_L] = { + .name = "data_l", + .help = "Type #6: data message with length option", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH, + ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, + ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, + ITEM_NEXT)), + .call = parse_vc_item_l2tpv2_type, + }, + [ITEM_L2TPV2_MSG_DATA_L_LENGTH] = { + .name = "length", + .help = "message length", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH, + ITEM_L2TPV2_COMMON, ITEM_NEXT), + NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, + hdr.type6.length)), + }, + [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = { + .name = "tunnel_id", + .help = "tunnel identifier", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, + ITEM_L2TPV2_COMMON, ITEM_NEXT), + NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, + hdr.type6.tunnel_id)), + }, + [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = { + .name = "session_id", + .help = "session identifier", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, + ITEM_L2TPV2_COMMON, ITEM_NEXT), + NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, + hdr.type6.session_id)), + }, + [ITEM_L2TPV2_COMMON_TYPE_CTRL] = { + .name = "control", + .help = "Type #3: conrtol message contains length, ns, nr options", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH, + ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, + ITEM_L2TPV2_MSG_CTRL_SESSION_ID, + ITEM_L2TPV2_MSG_CTRL_NS, + ITEM_L2TPV2_MSG_CTRL_NR, + ITEM_NEXT)), + .call = parse_vc_item_l2tpv2_type, + }, + [ITEM_L2TPV2_MSG_CTRL_LENGTH] = { + .name = "length", + .help = "message length", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH, + ITEM_L2TPV2_COMMON, ITEM_NEXT), + NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, + hdr.type3.length)), + }, + [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = { + .name = "tunnel_id", + .help = "tunnel identifier", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, + ITEM_L2TPV2_COMMON, ITEM_NEXT), + NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, + hdr.type3.tunnel_id)), + }, + [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = { + .name = "session_id", + .help = "session identifier", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_SESSION_ID, + ITEM_L2TPV2_COMMON, ITEM_NEXT), + NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, + hdr.type3.session_id)), + }, + [ITEM_L2TPV2_MSG_CTRL_NS] = { + .name = "ns", + .help = "sequence number for message", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS, + ITEM_L2TPV2_COMMON, ITEM_NEXT), + NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, + hdr.type3.ns)), + }, + [ITEM_L2TPV2_MSG_CTRL_NR] = { + .name = "nr", + .help = "sequence number for next receive message", + .next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS, + ITEM_L2TPV2_COMMON, ITEM_NEXT), + NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, + hdr.type3.nr)), + }, + [ITEM_PPP] = { + .name = "ppp", + .help = "match ppp header", + .priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), + .next = NEXT(item_ppp), + .call = parse_vc, + }, + [ITEM_PPP_ADDR] = { + .name = "addr", + .help = "ppp address", + .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)), + }, + [ITEM_PPP_CTRL] = { + .name = "ctrl", + .help = "ppp control", + .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)), + }, + [ITEM_PPP_PROTO_ID] = { + .name = "proto_id", + .help = "ppp protocol id", + .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, + hdr.proto_id)), + }, /* Validate/create actions. */ [ACTIONS] = { .name = "actions", @@ -5569,6 +5763,57 @@ parse_vc_item_ecpri_type(struct context *ctx, const struct token *token, return len; } +/** Parse L2TPV2 common header type field. */ +static int +parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + struct rte_flow_item_l2tpv2 *l2tpv2; + struct rte_flow_item_l2tpv2 *l2tpv2_mask; + struct rte_flow_item *item; + uint32_t data_size; + uint8_t msg_type = 0; + struct buffer *out = buf; + const struct arg *arg; + + (void)size; + /* Token name must match. */ + if (parse_default(ctx, token, str, len, NULL, 0) < 0) + return -1; + switch (ctx->curr) { + case ITEM_L2TPV2_COMMON_TYPE_DATA_L: + msg_type |= 0x4000; + break; + case ITEM_L2TPV2_COMMON_TYPE_CTRL: + msg_type |= 0xC800; + break; + default: + return -1; + } + if (!ctx->object) + return len; + arg = pop_args(ctx); + if (!arg) + return -1; + l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data; + l2tpv2->hdr.common.flags_version |= msg_type; + data_size = ctx->objdata / 3; /* spec, last, mask */ + l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data + + (data_size * 2)); + l2tpv2_mask->hdr.common.flags_version = 0xFFFF; + if (arg->hton) { + l2tpv2->hdr.common.flags_version = + rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version); + l2tpv2_mask->hdr.common.flags_version = + rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version); + } + item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; + item->spec = l2tpv2; + item->mask = l2tpv2_mask; + return len; +} + /** Parse meter color action type. */ static int parse_vc_action_meter_color_type(struct context *ctx, const struct token *token, @@ -8461,6 +8706,12 @@ flow_item_default_mask(const struct rte_flow_item *item) case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: mask = &rte_flow_item_ethdev_mask; break; + case RTE_FLOW_ITEM_TYPE_L2TPV2: + mask = &rte_flow_item_l2tpv2_mask; + break; + case RTE_FLOW_ITEM_TYPE_PPP: + mask = &rte_flow_item_ppp_mask; + break; default: break; }