From patchwork Mon Apr 17 09:25:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rongwei Liu X-Patchwork-Id: 126176 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 85BCC4296B; Mon, 17 Apr 2023 11:26:32 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 8753942C24; Mon, 17 Apr 2023 11:26:18 +0200 (CEST) Received: from NAM11-BN8-obe.outbound.protection.outlook.com (mail-bn8nam11on2041.outbound.protection.outlook.com [40.107.236.41]) by mails.dpdk.org (Postfix) with ESMTP id EC8CE42B8C for ; Mon, 17 Apr 2023 11:26:15 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ACrS8OIE/uJyLYiEecBgM7zGuR7G8ExUKMrNcElntTpkuT9nYE9BfuCNZlF+p6VdNEL7/1O6zpEx7xunMXx6PW0SvJCKf43gBB/0UYVPGOLJDAfTehAOEmeoSUIw7/f5G4pUBXRQRZc8Oq6p4Dd5laOkEfer7g3Y2UUqMUxcLBFFhUYe8RvXTC5yn7A0haPHViOAyjxNZhfEm5FCANuCQztHPohBq924hN8tlX88XepeWVM28aHJepOIL9zDkKTr24CFpKdXQ8nKQFYyGDeA4m2bEdgaWOyJdaeKQSXem6ttT5MO2GHjUhaMM/b7W5qwIdMjKy8sAQzBYt/M+kMwyQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=lEAsKrVE6PHBLGuQiu7FouKryRQGBEEYJgZy/AQzYi0=; b=GLhl4Yj8UFA+XnGAYGkq5caZJ6KaPuzstj1ytM+2VHyPv6pMkHyTVS9Nt5kyPkzHT4MORWads7M99QOTqniaYqucJXpbFQzR80E/UhVQ0Pu46rrbmn18Xa3lQNZgCOwZ5oEZsPjsgNJyxV2eHAwMcEq93uHlygkAaej45ADieDBO16jdnI+tYYMzDewiPYYaGoBH+2+lq8PBAsNcrYV4ZMlxGa4Ge5pPcaWkxQH5bwmnVZvSrZXBH/rZCgZimeW35jS4Amt9jVHKL8D5i2ItdjLwzIGX/l/xgKwKpqfB2W/s0pl2lEjD8+xoWiHwWUnlrwkAFn/mOq61C1QnqFLZRQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.117.160) smtp.rcpttodomain=dpdk.org smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=lEAsKrVE6PHBLGuQiu7FouKryRQGBEEYJgZy/AQzYi0=; b=KO2YxUDq8eSboWFi8LFFpCv2J+XtyQUo380knnwxem6EcI+eMsxYzAEs2e/eeNptUMgkpYZUKL67NBE3hxn3zw+JNmLyTNtgPOqZpY1Z37g3nCnTln41qPoKQcyrmj9GuWhbHVph2zCYpi7/eW2SADt3ChnG7bAvXWjKi0lducBjSXQBSQneqmtTW1N1vHHYnXuriOsrQ1XeR9lwUTVPdUVxyTmse1mNjhKOeHs6RH/KNb/41uHLccF6ypcr06Q/XynmYfxDSWIjz0IGmvYjk0Z3hrXZF96b8Zo/GI+LeUPyJmE1/tobA/yzW9EIkDR5iB49Is+LAsFxvHkXtiG/Pg== Received: from BN0PR03CA0054.namprd03.prod.outlook.com (2603:10b6:408:e7::29) by BY5PR12MB4097.namprd12.prod.outlook.com (2603:10b6:a03:213::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6298.45; Mon, 17 Apr 2023 09:26:13 +0000 Received: from BN8NAM11FT105.eop-nam11.prod.protection.outlook.com (2603:10b6:408:e7:cafe::68) by BN0PR03CA0054.outlook.office365.com (2603:10b6:408:e7::29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6298.46 via Frontend Transport; Mon, 17 Apr 2023 09:26:12 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.117.160) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.117.160 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.117.160; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.117.160) by BN8NAM11FT105.mail.protection.outlook.com (10.13.176.183) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6319.19 via Frontend Transport; Mon, 17 Apr 2023 09:26:12 +0000 Received: from rnnvmail201.nvidia.com (10.129.68.8) by mail.nvidia.com (10.129.200.66) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.5; Mon, 17 Apr 2023 02:26:00 -0700 Received: from nvidia.com (10.126.231.37) by rnnvmail201.nvidia.com (10.129.68.8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.37; Mon, 17 Apr 2023 02:25:57 -0700 From: Rongwei Liu To: , , , , CC: Aman Singh , Yuying Zhang Subject: [PATCH v1 2/8] app/testpmd: add IPv6 extension push remove cli Date: Mon, 17 Apr 2023 12:25:34 +0300 Message-ID: <20230417092540.2617450-3-rongweil@nvidia.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20230417092540.2617450-1-rongweil@nvidia.com> References: <20230417092540.2617450-1-rongweil@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [10.126.231.37] X-ClientProxiedBy: rnnvmail201.nvidia.com (10.129.68.8) To rnnvmail201.nvidia.com (10.129.68.8) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BN8NAM11FT105:EE_|BY5PR12MB4097:EE_ X-MS-Office365-Filtering-Correlation-Id: c325ad55-7dc1-4df6-173e-08db3f25c97b X-LD-Processed: 43083d15-7273-40c1-b7db-39efd9ccc17a,ExtAddr X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: +WWCQWusRZM5rB4TbPQ5skjsPvfISO1pcnfrxaWVDzyQgCrafrZhcwWEdzIbuH/SUtv5e7mmFTcDl91TGWVWUH8lnodPSVBviWmWfLerokomH+bXahst6e9vciKf61Lynk4lFSvH2GkRbb3NZjEB2D1UxBuKK0/mnV6aLubPkUvFpv0aNIyT88zvcktuOWH+1qZPjloOskinQji1k6TMDb5D+6d3tSrtD4+DFsXFLrTZj3hvIBwyk7LEZjT4VWrXvrzZ8lkB2Bjwh+QyE1hq2LceyMX3qZxnveoAuvxsvmKo/h8BCedWZ2aUi3D/UP+0xa61+TU9XFOzXob9sgUQ31WdY+3kMlM3TwGR4SqW70ftU5HMMn+h+jkO9mi1zdrWDI25jmJqicaqrXlvlXLwyDw1AjYBBq9apXcTNAMTJWUMLXt/g9YNUbal6M3RagVv7MLYPGCAqm7/+wJKz6UKT+DndmcfGKPnn6aCbJGRxfL0fVlESq9aLwxeJ9MZkS8dycYeTs49wXyOlXWsz219YSJJkcppPOlOfpFuxnpD3MkMZvT8BNx9BmlvtteHEGit4L6x8twYioi6ysIkFyYymDyfdDrBIaZ07cYsXPFfIZVyq9Ta/szKIkGGqwsSoRFf1kIGf9Wt5JYu5ycYqyBE4NJcmng/06kGZCkE+CY8svo+DeusZtM4N4NONtRmO6qXSUJSDiG3tJ17RMf306ONWD2sLQrI89HOb5qNSG2Hj4Yl/YxTSiyXAEn/aLDE3gMW X-Forefront-Antispam-Report: CIP:216.228.117.160; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:dc6edge1.nvidia.com; CAT:NONE; SFS:(13230028)(4636009)(346002)(136003)(396003)(39850400004)(376002)(451199021)(36840700001)(46966006)(8676002)(8936002)(5660300002)(2906002)(30864003)(36756003)(82310400005)(86362001)(40480700001)(55016003)(34020700004)(478600001)(7696005)(6666004)(54906003)(110136005)(16526019)(6286002)(186003)(2616005)(36860700001)(26005)(1076003)(70206006)(70586007)(82740400003)(7636003)(83380400001)(316002)(41300700001)(356005)(4326008)(47076005)(426003)(336012); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Apr 2023 09:26:12.7653 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: c325ad55-7dc1-4df6-173e-08db3f25c97b X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.117.160]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BN8NAM11FT105.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY5PR12MB4097 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 Add command lines to generate IPv6 routing extension push and remove patterns and follow the raw_encap/decap style. Add the new actions to the action template parsing. Generating the action patterns 1. IPv6 routing extension push set ipv6_ext_push 1 ipv6_ext type is 43 / ipv6_routing_ext ext_type is 4 ext_next_hdr is 17 ext_seg_left is 2 / end_set 2. IPv6 routing extension remove set ipv6_ext_remove 1 ipv6_ext type is 43 / end_set Specifying the action in the template 1. actions_template_id 1 template ipv6_ext_push index 1 2. actions_template_id 1 template ipv6_ext_remove index 1 Signed-off-by: Rongwei Liu Acked-by: Ori Kam --- app/test-pmd/cmdline_flow.c | 443 +++++++++++++++++++++++++++++++++++- 1 file changed, 442 insertions(+), 1 deletion(-) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 58939ec321..ea4cebce1c 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -74,6 +74,9 @@ enum index { SET_RAW_INDEX, SET_SAMPLE_ACTIONS, SET_SAMPLE_INDEX, + SET_IPV6_EXT_REMOVE, + SET_IPV6_EXT_PUSH, + SET_IPV6_EXT_INDEX, /* Top-level command. */ FLOW, @@ -496,6 +499,8 @@ enum index { ITEM_QUOTA_STATE_NAME, ITEM_AGGR_AFFINITY, ITEM_AGGR_AFFINITY_VALUE, + ITEM_IPV6_PUSH_REMOVE_EXT, + ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, /* Validate/create actions. */ ACTIONS, @@ -665,6 +670,12 @@ enum index { ACTION_QUOTA_QU_LIMIT, ACTION_QUOTA_QU_UPDATE_OP, ACTION_QUOTA_QU_UPDATE_OP_NAME, + ACTION_IPV6_EXT_REMOVE, + ACTION_IPV6_EXT_REMOVE_INDEX, + ACTION_IPV6_EXT_REMOVE_INDEX_VALUE, + ACTION_IPV6_EXT_PUSH, + ACTION_IPV6_EXT_PUSH_INDEX, + ACTION_IPV6_EXT_PUSH_INDEX_VALUE, }; /** Maximum size for pattern in struct rte_flow_item_raw. */ @@ -731,6 +742,42 @@ struct action_raw_decap_data { uint16_t idx; }; +/** Maximum data size in struct rte_flow_action_ipv6_ext_push. */ +#define ACTION_IPV6_EXT_PUSH_MAX_DATA 512 +#define IPV6_EXT_PUSH_CONFS_MAX_NUM 8 + +/** Storage for struct rte_flow_action_ipv6_ext_push. */ +struct ipv6_ext_push_conf { + uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; + size_t size; + uint8_t type; +}; + +struct ipv6_ext_push_conf ipv6_ext_push_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; + +/** Storage for struct rte_flow_action_ipv6_ext_push including external data. */ +struct action_ipv6_ext_push_data { + struct rte_flow_action_ipv6_ext_push conf; + uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; + uint8_t type; + uint16_t idx; +}; + +/** Storage for struct rte_flow_action_ipv6_ext_remove. */ +struct ipv6_ext_remove_conf { + struct rte_flow_action_ipv6_ext_remove conf; + uint8_t type; +}; + +struct ipv6_ext_remove_conf ipv6_ext_remove_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; + +/** Storage for struct rte_flow_action_ipv6_ext_remove including external data. */ +struct action_ipv6_ext_remove_data { + struct rte_flow_action_ipv6_ext_remove conf; + uint8_t type; + uint16_t idx; +}; + struct vxlan_encap_conf vxlan_encap_conf = { .select_ipv4 = 1, .select_vlan = 0, @@ -2022,6 +2069,8 @@ static const enum index next_action[] = { ACTION_SEND_TO_KERNEL, ACTION_QUOTA_CREATE, ACTION_QUOTA_QU, + ACTION_IPV6_EXT_REMOVE, + ACTION_IPV6_EXT_PUSH, ZERO, }; @@ -2230,6 +2279,18 @@ static const enum index action_raw_decap[] = { ZERO, }; +static const enum index action_ipv6_ext_remove[] = { + ACTION_IPV6_EXT_REMOVE_INDEX, + ACTION_NEXT, + ZERO, +}; + +static const enum index action_ipv6_ext_push[] = { + ACTION_IPV6_EXT_PUSH_INDEX, + ACTION_NEXT, + ZERO, +}; + static const enum index action_set_tag[] = { ACTION_SET_TAG_DATA, ACTION_SET_TAG_INDEX, @@ -2293,6 +2354,22 @@ static const enum index next_action_sample[] = { ZERO, }; +static const enum index item_ipv6_push_ext[] = { + ITEM_IPV6_PUSH_REMOVE_EXT, + ZERO, +}; + +static const enum index item_ipv6_push_ext_type[] = { + ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, + ZERO, +}; + +static const enum index item_ipv6_push_ext_header[] = { + ITEM_IPV6_ROUTING_EXT, + ITEM_NEXT, + ZERO, +}; + static const enum index action_modify_field_dst[] = { ACTION_MODIFY_FIELD_DST_LEVEL, ACTION_MODIFY_FIELD_DST_OFFSET, @@ -2334,6 +2411,9 @@ static int parse_set_raw_encap_decap(struct context *, const struct token *, static int parse_set_sample_action(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); +static int parse_set_ipv6_ext_action(struct context *, const struct token *, + const char *, unsigned int, + void *, unsigned int); static int parse_set_init(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -2411,6 +2491,22 @@ static int parse_vc_action_raw_encap_index(struct context *, static int parse_vc_action_raw_decap_index(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); +static int parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, + const char *str, unsigned int len, void *buf, + unsigned int size); +static int parse_vc_action_ipv6_ext_remove_index(struct context *ctx, + const struct token *token, + const char *str, unsigned int len, + void *buf, + unsigned int size); +static int parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, + const char *str, unsigned int len, void *buf, + unsigned int size); +static int parse_vc_action_ipv6_ext_push_index(struct context *ctx, + const struct token *token, + const char *str, unsigned int len, + void *buf, + unsigned int size); static int parse_vc_action_set_meta(struct context *ctx, const struct token *token, const char *str, unsigned int len, void *buf, @@ -2596,6 +2692,8 @@ static int comp_set_raw_index(struct context *, const struct token *, unsigned int, char *, unsigned int); static int comp_set_sample_index(struct context *, const struct token *, unsigned int, char *, unsigned int); +static int comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, + unsigned int ent, char *buf, unsigned int size); static int comp_set_modify_field_op(struct context *, const struct token *, unsigned int, char *, unsigned int); static int comp_set_modify_field_id(struct context *, const struct token *, @@ -6472,6 +6570,48 @@ static const struct token token_list[] = { .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), .call = parse_vc, }, + [ACTION_IPV6_EXT_REMOVE] = { + .name = "ipv6_ext_remove", + .help = "IPv6 extension type, defined by set ipv6_ext_remove", + .priv = PRIV_ACTION(IPV6_EXT_REMOVE, + sizeof(struct action_ipv6_ext_remove_data)), + .next = NEXT(action_ipv6_ext_remove), + .call = parse_vc_action_ipv6_ext_remove, + }, + [ACTION_IPV6_EXT_REMOVE_INDEX] = { + .name = "index", + .help = "the index of ipv6_ext_remove", + .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_REMOVE_INDEX_VALUE)), + }, + [ACTION_IPV6_EXT_REMOVE_INDEX_VALUE] = { + .name = "{index}", + .type = "UNSIGNED", + .help = "unsigned integer value", + .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), + .call = parse_vc_action_ipv6_ext_remove_index, + .comp = comp_set_ipv6_ext_index, + }, + [ACTION_IPV6_EXT_PUSH] = { + .name = "ipv6_ext_push", + .help = "IPv6 extension data, defined by set ipv6_ext_push", + .priv = PRIV_ACTION(IPV6_EXT_PUSH, + sizeof(struct action_ipv6_ext_push_data)), + .next = NEXT(action_ipv6_ext_push), + .call = parse_vc_action_ipv6_ext_push, + }, + [ACTION_IPV6_EXT_PUSH_INDEX] = { + .name = "index", + .help = "the index of ipv6_ext_push", + .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_PUSH_INDEX_VALUE)), + }, + [ACTION_IPV6_EXT_PUSH_INDEX_VALUE] = { + .name = "{index}", + .type = "UNSIGNED", + .help = "unsigned integer value", + .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), + .call = parse_vc_action_ipv6_ext_push_index, + .comp = comp_set_ipv6_ext_index, + }, /* Top level command. */ [SET] = { .name = "set", @@ -6481,7 +6621,9 @@ static const struct token token_list[] = { .next = NEXT(NEXT_ENTRY (SET_RAW_ENCAP, SET_RAW_DECAP, - SET_SAMPLE_ACTIONS)), + SET_SAMPLE_ACTIONS, + SET_IPV6_EXT_REMOVE, + SET_IPV6_EXT_PUSH)), .call = parse_set_init, }, /* Sub-level commands. */ @@ -6529,6 +6671,49 @@ static const struct token token_list[] = { 0, RAW_SAMPLE_CONFS_MAX_NUM - 1)), .call = parse_set_sample_action, }, + [SET_IPV6_EXT_PUSH] = { + .name = "ipv6_ext_push", + .help = "set IPv6 extension header", + .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), + .args = ARGS(ARGS_ENTRY_ARB_BOUNDED + (offsetof(struct buffer, port), + sizeof(((struct buffer *)0)->port), + 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), + .call = parse_set_ipv6_ext_action, + }, + [SET_IPV6_EXT_REMOVE] = { + .name = "ipv6_ext_remove", + .help = "set IPv6 extension header", + .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), + .args = ARGS(ARGS_ENTRY_ARB_BOUNDED + (offsetof(struct buffer, port), + sizeof(((struct buffer *)0)->port), + 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), + .call = parse_set_ipv6_ext_action, + }, + [SET_IPV6_EXT_INDEX] = { + .name = "{index}", + .type = "UNSIGNED", + .help = "index of ipv6 extension push/remove actions", + .next = NEXT(item_ipv6_push_ext), + .call = parse_port, + }, + [ITEM_IPV6_PUSH_REMOVE_EXT] = { + .name = "ipv6_ext", + .help = "set IPv6 extension header", + .priv = PRIV_ITEM(IPV6_EXT, + sizeof(struct rte_flow_item_ipv6_ext)), + .next = NEXT(item_ipv6_push_ext_type), + .call = parse_vc, + }, + [ITEM_IPV6_PUSH_REMOVE_EXT_TYPE] = { + .name = "type", + .help = "set IPv6 extension type", + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, + next_hdr)), + .next = NEXT(item_ipv6_push_ext_header, NEXT_ENTRY(COMMON_UNSIGNED), + item_param), + }, [ACTION_SET_TAG] = { .name = "set_tag", .help = "set tag", @@ -8843,6 +9028,140 @@ parse_vc_action_raw_decap(struct context *ctx, const struct token *token, return ret; } +static int +parse_vc_action_ipv6_ext_remove(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_action *action; + struct action_ipv6_ext_remove_data *ipv6_ext_remove_data = NULL; + int ret; + + ret = parse_vc(ctx, token, str, len, buf, size); + if (ret < 0) + return ret; + /* Nothing else to do if there is no buffer. */ + if (!out) + return ret; + if (!out->args.vc.actions_n) + return -1; + action = &out->args.vc.actions[out->args.vc.actions_n - 1]; + /* Point to selected object. */ + ctx->object = out->args.vc.data; + ctx->objmask = NULL; + /* Copy the headers to the buffer. */ + ipv6_ext_remove_data = ctx->object; + ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[0].type; + action->conf = &ipv6_ext_remove_data->conf; + return ret; +} + +static int +parse_vc_action_ipv6_ext_remove_index(struct context *ctx, const struct token *token, + const char *str, unsigned int len, void *buf, + unsigned int size) +{ + struct action_ipv6_ext_remove_data *action_ipv6_ext_remove_data; + struct rte_flow_action *action; + const struct arg *arg; + struct buffer *out = buf; + int ret; + uint16_t idx; + + RTE_SET_USED(token); + RTE_SET_USED(buf); + RTE_SET_USED(size); + arg = ARGS_ENTRY_ARB_BOUNDED + (offsetof(struct action_ipv6_ext_remove_data, idx), + sizeof(((struct action_ipv6_ext_remove_data *)0)->idx), + 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); + if (push_args(ctx, arg)) + return -1; + ret = parse_int(ctx, token, str, len, NULL, 0); + if (ret < 0) { + pop_args(ctx); + return -1; + } + if (!ctx->object) + return len; + action = &out->args.vc.actions[out->args.vc.actions_n - 1]; + action_ipv6_ext_remove_data = ctx->object; + idx = action_ipv6_ext_remove_data->idx; + action_ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[idx].type; + action->conf = &action_ipv6_ext_remove_data->conf; + return len; +} + +static int +parse_vc_action_ipv6_ext_push(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_action *action; + struct action_ipv6_ext_push_data *ipv6_ext_push_data = NULL; + int ret; + + ret = parse_vc(ctx, token, str, len, buf, size); + if (ret < 0) + return ret; + /* Nothing else to do if there is no buffer. */ + if (!out) + return ret; + if (!out->args.vc.actions_n) + return -1; + action = &out->args.vc.actions[out->args.vc.actions_n - 1]; + /* Point to selected object. */ + ctx->object = out->args.vc.data; + ctx->objmask = NULL; + /* Copy the headers to the buffer. */ + ipv6_ext_push_data = ctx->object; + ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[0].type; + ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[0].data; + ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[0].size; + action->conf = &ipv6_ext_push_data->conf; + return ret; +} + +static int +parse_vc_action_ipv6_ext_push_index(struct context *ctx, const struct token *token, + const char *str, unsigned int len, void *buf, + unsigned int size) +{ + struct action_ipv6_ext_push_data *action_ipv6_ext_push_data; + struct rte_flow_action *action; + const struct arg *arg; + struct buffer *out = buf; + int ret; + uint16_t idx; + + RTE_SET_USED(token); + RTE_SET_USED(buf); + RTE_SET_USED(size); + arg = ARGS_ENTRY_ARB_BOUNDED + (offsetof(struct action_ipv6_ext_push_data, idx), + sizeof(((struct action_ipv6_ext_push_data *)0)->idx), + 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); + if (push_args(ctx, arg)) + return -1; + ret = parse_int(ctx, token, str, len, NULL, 0); + if (ret < 0) { + pop_args(ctx); + return -1; + } + if (!ctx->object) + return len; + action = &out->args.vc.actions[out->args.vc.actions_n - 1]; + action_ipv6_ext_push_data = ctx->object; + idx = action_ipv6_ext_push_data->idx; + action_ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[idx].type; + action_ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[idx].size; + action_ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[idx].data; + action->conf = &action_ipv6_ext_push_data->conf; + return len; +} + static int parse_vc_action_set_meta(struct context *ctx, const struct token *token, const char *str, unsigned int len, void *buf, @@ -10532,6 +10851,35 @@ parse_set_sample_action(struct context *ctx, const struct token *token, return len; } +/** Parse set command, initialize output buffer for subsequent tokens. */ +static int +parse_set_ipv6_ext_action(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + struct buffer *out = buf; + + /* Token name must match. */ + if (parse_default(ctx, token, str, len, NULL, 0) < 0) + return -1; + /* Nothing else to do if there is no buffer. */ + if (!out) + return len; + /* Make sure buffer is large enough. */ + if (size < sizeof(*out)) + return -1; + ctx->objdata = 0; + ctx->objmask = NULL; + ctx->object = out; + if (!out->command) + return -1; + out->command = ctx->curr; + /* For ipv6_ext_push/remove we need is pattern */ + out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), + sizeof(double)); + return len; +} + /** * Parse set raw_encap/raw_decap command, * initialize output buffer for subsequent tokens. @@ -10961,6 +11309,24 @@ comp_set_raw_index(struct context *ctx, const struct token *token, return nb; } +/** Complete index number for set raw_ipv6_ext_push/ipv6_ext_remove commands. */ +static int +comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, + unsigned int ent, char *buf, unsigned int size) +{ + uint16_t idx = 0; + uint16_t nb = 0; + + RTE_SET_USED(ctx); + RTE_SET_USED(token); + for (idx = 0; idx < IPV6_EXT_PUSH_CONFS_MAX_NUM; ++idx) { + if (buf && idx == ent) + return snprintf(buf, size, "%u", idx); + ++nb; + } + return nb; +} + /** Complete index number for set raw_encap/raw_decap commands. */ static int comp_set_sample_index(struct context *ctx, const struct token *token, @@ -11855,6 +12221,78 @@ flow_item_default_mask(const struct rte_flow_item *item) return mask; } +/** Dispatch parsed buffer to function calls. */ +static void +cmd_set_ipv6_ext_parsed(const struct buffer *in) +{ + uint32_t n = in->args.vc.pattern_n; + int i = 0; + struct rte_flow_item *item = NULL; + size_t size = 0; + uint8_t *data = NULL; + uint8_t *type = NULL; + size_t *total_size = NULL; + uint16_t idx = in->port; /* We borrow port field as index */ + struct rte_flow_item_ipv6_routing_ext *ext; + const struct rte_flow_item_ipv6_ext *ipv6_ext; + + RTE_ASSERT(in->command == SET_IPV6_EXT_PUSH || + in->command == SET_IPV6_EXT_REMOVE); + + if (in->command == SET_IPV6_EXT_REMOVE) { + if (n != 1 || in->args.vc.pattern->type != + RTE_FLOW_ITEM_TYPE_IPV6_EXT) { + fprintf(stderr, "Error - Not supported item\n"); + return; + } + type = (uint8_t *)&ipv6_ext_remove_confs[idx].type; + item = in->args.vc.pattern; + ipv6_ext = item->spec; + *type = ipv6_ext->next_hdr; + return; + } + + total_size = &ipv6_ext_push_confs[idx].size; + data = (uint8_t *)&ipv6_ext_push_confs[idx].data; + type = (uint8_t *)&ipv6_ext_push_confs[idx].type; + + *total_size = 0; + memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); + for (i = n - 1 ; i >= 0; --i) { + item = in->args.vc.pattern + i; + switch (item->type) { + case RTE_FLOW_ITEM_TYPE_IPV6_EXT: + ipv6_ext = item->spec; + *type = ipv6_ext->next_hdr; + break; + case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: + ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; + if (!ext->hdr.hdr_len) { + size = sizeof(struct rte_ipv6_routing_ext) + + (ext->hdr.segments_left << 4); + ext->hdr.hdr_len = ext->hdr.segments_left << 1; + /* Indicate no TLV once SRH. */ + if (ext->hdr.type == 4) + ext->hdr.last_entry = ext->hdr.segments_left - 1; + } else { + size = sizeof(struct rte_ipv6_routing_ext) + + (ext->hdr.hdr_len << 3); + } + *total_size += size; + memcpy(data, ext, size); + break; + default: + fprintf(stderr, "Error - Not supported item\n"); + goto error; + } + } + RTE_ASSERT((*total_size) <= ACTION_IPV6_EXT_PUSH_MAX_DATA); + return; +error: + *total_size = 0; + memset(data, 0x00, ACTION_IPV6_EXT_PUSH_MAX_DATA); +} + /** Dispatch parsed buffer to function calls. */ static void cmd_set_raw_parsed_sample(const struct buffer *in) @@ -11988,6 +12426,9 @@ cmd_set_raw_parsed(const struct buffer *in) if (in->command == SET_SAMPLE_ACTIONS) return cmd_set_raw_parsed_sample(in); + else if (in->command == SET_IPV6_EXT_PUSH || + in->command == SET_IPV6_EXT_REMOVE) + return cmd_set_ipv6_ext_parsed(in); RTE_ASSERT(in->command == SET_RAW_ENCAP || in->command == SET_RAW_DECAP); if (in->command == SET_RAW_ENCAP) {