From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 493A842B89; Wed, 24 May 2023 09:40:09 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2E41442D36; Wed, 24 May 2023 09:40:08 +0200 (CEST) Received: from NAM11-DM6-obe.outbound.protection.outlook.com (mail-dm6nam11on2077.outbound.protection.outlook.com [40.107.223.77]) by mails.dpdk.org (Postfix) with ESMTP id 0700042D32 for ; Wed, 24 May 2023 09:40:07 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=n4Jd+5Hf1yIoBDUyBq1rpmwJkYoq/NsM/vXd5gvhcL6Qcy9kpO6AoufkP2Qz+tbjg1oOtnT/Wk8+jXP8e76kIRdEiF5prx24qkiRCyybsX12Ki94s1XpGZQcoXDxiglBVeZ+v9fsW0eViYZSlyjuzSmExR9/n/3Ym7lLQ5aBp2RNU0VuPLPLOkJytME2Ujym1goopsDNYEe22VRpNMbv9yjiiDEGV/eqixp9g48VcB/YkZsUbnROeLm5CIUgNtJrKZlE7hhGpbUM8C1kApqtjvKqrs5HNjCtmjoZLNS9ABEQfqCy8OUzWI4UX9CzadG0dbzScEKe/IX/VS3fc3HODg== 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=qZpFjviIxnOjyj7Fsj42BWYz+L1MTzpA42h4Gj0aBS0=; b=XczVltiB+GXa0XQtHyR4B8JskZeD9xFl1mnnj78OmEwF5GiROaGSvJoFSEalpquqMFKMoecrD1RtB7CGmZBpCzQdTvFMKzuBsLIhcjIbLDYrjSax0sUKPz1jpqAcYGOBHVpjR6c/qlrUOluox7w79r1r4Ad8ptmEnby4bX3IMT8wXhZNDvpvsCvIldbD9rZBHLp0O/XTEnkfntQ3228jDbuEV0WosFUQp4eA0Lif7OUoHZflzT5VIsucNhONY96/8PfCDUwlaIcIJtj6cgwO4XoXuoRPxYdVHaWl7NQxaWpJVrq63QAXqCzTsnOLj6OnilhspNkmkz0bMorqOsHhEw== 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=qZpFjviIxnOjyj7Fsj42BWYz+L1MTzpA42h4Gj0aBS0=; b=ewQywgyQ8lwQonExCCPXYllQdChb/fw8Ys8cplr1mCyVPXf8aw9vcBxusjb6rlzA9sPx4Q/vupqr8fVmkHCCTk9JbQCZDlMvRFwVjujE246aJm9pDpiuLqfgLtArzPgQxKB8Rjl8mQZmx6v6xAgdfhXZp8dPb+Rh7Zxfk0GPJYnzL/xCJDYO9ytK/5+TSz1u1ya87sY11LvkNMMOTvIqTwfRD2x68AULP12PD3QBr9t8vl1JDzow3MFaf+QhMc20Hznlt1Rq7kGX7IB0Y8V8su5lE3y/FS2UUg8rh+5BWwK0M5FRW9L0yMX1+Xreg7Evoq6F5xynIbV6d/9g/AbEtQ== Received: from BN9PR03CA0723.namprd03.prod.outlook.com (2603:10b6:408:110::8) by BN9PR12MB5354.namprd12.prod.outlook.com (2603:10b6:408:103::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6411.28; Wed, 24 May 2023 07:40:04 +0000 Received: from BN8NAM11FT023.eop-nam11.prod.protection.outlook.com (2603:10b6:408:110:cafe::fc) by BN9PR03CA0723.outlook.office365.com (2603:10b6:408:110::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6411.30 via Frontend Transport; Wed, 24 May 2023 07:40:04 +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 BN8NAM11FT023.mail.protection.outlook.com (10.13.177.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6411.30 via Frontend Transport; Wed, 24 May 2023 07:40:04 +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; Wed, 24 May 2023 00:39:50 -0700 Received: from nvidia.com (10.126.231.35) 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; Wed, 24 May 2023 00:39:47 -0700 From: Rongwei Liu To: , , , , , CC: Aman Singh , Yuying Zhang Subject: [PATCH v1 2/2] app/testpmd: add IPv6 extension push remove cli Date: Wed, 24 May 2023 10:39:29 +0300 Message-ID: <20230524073929.400623-3-rongweil@nvidia.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20230524073929.400623-1-rongweil@nvidia.com> References: <20230524073929.400623-1-rongweil@nvidia.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [10.126.231.35] 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: BN8NAM11FT023:EE_|BN9PR12MB5354:EE_ X-MS-Office365-Filtering-Correlation-Id: 5cd9aac2-17fe-4bac-58c1-08db5c2a171a 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: AwJ/W4YEYgGhoqQKlG/hwTE3wBGmczZH2YZkfQN4SRzrsAQ0d9fnk7GORmUrVKmVuTfb20CSFeBRYg9zOrqtrUoiE18DNgPmexTNDLwpZiEQzVORs/gxIMXVYv/PHfQP3L7zm279zZSXlng8TJYyfUUQUevPyoz9kg53UKAaYxzbk06hxAtFUvBM9zoAoKulRiLTy6xbAecCGamOCV3gCs/axVblNTPiN/NuuR7GypqYolMp7UiwOhz2hd2/j6DJD56yVFax4i6QFmFespSx66p/dQGw7zPoa62hrucrXy0OjuMcLjglQfgwChwIvtxhoh+C4fcDeZ/9676mdzd0FUasOBW2vA7y3Zn8FDjwko4hZhVJ21Ac/ysV4OIpL9RxRYRXGvMC6SY6hYIZ5hxAVyjj7AD0h8Y9uahuPobxsnWJD7k+Iw8EdwualEi2OMt2KUILizAcDiAqOk0InbOwdiuPuLzNDgY/TVt6ijWnp5hPd+NcOn1E9u5N9nSO0c0C+Nl2ix8xm1rcda2LxDEwWVUNwZfJkYVXaMsI7tzdYc6bNuM0WKBJrOhd+quriJ7iYjV4DhI1Ydu2+raouzO3ipPuOMj+CkoYWZ/VU3oQZzIAdOkuma+UM5YsyU82AG951GDnSndytLEoTRH6uQObYflVnvJ8ip3Z4xrJSc+2uhFa8gPYxhjAtdMgm/tcCe1u/xLJHeVfeIS/2ELmj6ntyS8l0cX5zAxPESbMrB9eIAQl4Oi9U2DE3xt1czqmOERs 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)(39860400002)(346002)(396003)(376002)(136003)(451199021)(40470700004)(46966006)(36840700001)(186003)(7636003)(356005)(26005)(40460700003)(82740400003)(1076003)(55016003)(2616005)(47076005)(36860700001)(83380400001)(426003)(336012)(36756003)(6286002)(16526019)(2906002)(30864003)(40480700001)(54906003)(7696005)(316002)(41300700001)(6666004)(82310400005)(110136005)(478600001)(86362001)(4326008)(70206006)(70586007)(8676002)(8936002)(5660300002); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2023 07:40:04.7322 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 5cd9aac2-17fe-4bac-58c1-08db5c2a171a 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: BN8NAM11FT023.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN9PR12MB5354 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) { -- 2.27.0