From patchwork Wed Nov 23 15:25:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steen Hegelund X-Patchwork-Id: 25054 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2856984wrr; Wed, 23 Nov 2022 07:28:24 -0800 (PST) X-Google-Smtp-Source: AA0mqf4S5RW4yVf2hd7ugY/q1+HBk1xwBx6Wh9acbzFEBj3FY09F3B3UlvGD48Nf4gV9qIccZo6K X-Received: by 2002:a05:6402:3810:b0:467:42a9:3568 with SMTP id es16-20020a056402381000b0046742a93568mr25667463edb.70.1669217304686; Wed, 23 Nov 2022 07:28:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669217304; cv=none; d=google.com; s=arc-20160816; b=ACv1T393uKoHRPJUvZxtUFZCYM5g27+WqJpIGIH3W/jkVt1eDwwgrNAbIhMbGO1uK3 ucs49Q8127Kmu/5a4PpGnC5uRHYAoNRBVTRh/ROXz8V3zOskWVtXogUHgc9R/vwt0rUZ wT8QGMzv0M6f/1YCD5MK03GpHAXvfDaV/LInTK5pd5OJ6rSAqaH4i5Kw+m9LZbD2THky shmb3LrVRheO4sM8LyR+AHzzT518fypZ8RmqgDQL/cwJSiGzTzbwNHz1V7mlRshacnN6 ddWy+KGULIQoPeLEMhP+s0TCxlNTwtnvMe7Pdu8ropc4nn2IH2Wf1P5SPoBAsN1M3MBg 7MyA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=OPNwE9ceRnqChQoB3/pq1FJN+hZnhn2Od2oruLa8+Tg=; b=NkxEbrRMSzVbTppbVnux9IHMqlUw39DGFNkxwHrBzW33POEzV1MbgKI7BjeUu3A2Jf z0xUSwzaWk4W2/7f/MblyKZud9i8Gzw8Zr1epsa/BuhJSHDEhH8nm2xOAUkRSvFZfieQ y++AqJwkIE6vdjvJlGGjJ0uzD4t8In+A3IXR2LhZX6UzFWlpCxPSQhlH7ohf51n+wMOa I1s9eLJHecdXMNxxPfLox81+7Ohco700AFjJ4/HTDTOD5ird+1JKvtYKAEB1IhLPwQp3 qE2sq7iHt98yerNT+mAGqmFhs++CNeL7A2E6QNJffWXjHEWL/GM9/8BsGAwPo+ZeWnoo jc7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@microchip.com header.s=mchp header.b=e4zO0BiI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=microchip.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id cs13-20020a170906dc8d00b0078db3ae83d0si11679151ejc.3.2022.11.23.07.27.55; Wed, 23 Nov 2022 07:28:24 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@microchip.com header.s=mchp header.b=e4zO0BiI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=microchip.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237667AbiKWP0a (ORCPT + 99 others); Wed, 23 Nov 2022 10:26:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35526 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237659AbiKWP0F (ORCPT ); Wed, 23 Nov 2022 10:26:05 -0500 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DA9E39B3A0; Wed, 23 Nov 2022 07:26:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1669217162; x=1700753162; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=SlcSvsk0a/gQBJiMcIytaYQtqJMh0GYV9BpXJsXg1iY=; b=e4zO0BiIkwFDWPuVIixGo7Hj28RTmx/K6PtPB5ln2pbc681JdEWueLza bJWvekRxKR1SLj80iTFj4aXJfxMjpBi3IzMzB7KIpwYIqA3HMQXKG+3qD aKlHRWiUekFoa5TBWR5Gzb9W8uenm9zhyrfJYJY13Z3t5Hg/Cu7PDbTJ5 wh1DxrSLWgBFbAX23ppA5nhQ5PyqOrLZITdnYNXR3hkJ69EyRT/y+esUz OH0+jNl97Mry5Mx/HWMn4LpJ4pMWCn+quv7wCrjVovEXK9O9XN+SL77Ty uCe54KGNKUFVwFmdbPLwc5QuG2Y0ClpYd+wT5jF1HX18UGCeRgi1eJ0m2 w==; X-IronPort-AV: E=Sophos;i="5.96,187,1665471600"; d="scan'208";a="190256275" Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa5.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 23 Nov 2022 08:26:01 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.12; Wed, 23 Nov 2022 08:25:54 -0700 Received: from den-dk-m31857.microchip.com (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.12 via Frontend Transport; Wed, 23 Nov 2022 08:25:51 -0700 From: Steen Hegelund To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni CC: Steen Hegelund , , Randy Dunlap , "Casper Andersson" , Russell King , Wan Jiabing , "Nathan Huckleberry" , , , , "Steen Hegelund" , Daniel Machon , Horatiu Vultur , Lars Povlsen Subject: [PATCH net-next v2 1/4] net: microchip: sparx5: Support for copying and modifying rules in the API Date: Wed, 23 Nov 2022 16:25:42 +0100 Message-ID: <20221123152545.1997266-2-steen.hegelund@microchip.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221123152545.1997266-1-steen.hegelund@microchip.com> References: <20221123152545.1997266-1-steen.hegelund@microchip.com> MIME-Version: 1.0 X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,T_SPF_TEMPERROR autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1750301204539466262?= X-GMAIL-MSGID: =?utf-8?q?1750301204539466262?= This adds support for making a copy of a rule and modify keys and actions to differentiate the copy. Signed-off-by: Steen Hegelund --- .../net/ethernet/microchip/vcap/vcap_api.c | 185 +++++++++++++++++- .../ethernet/microchip/vcap/vcap_api_client.h | 22 ++- .../ethernet/microchip/vcap/vcap_api_kunit.c | 6 +- .../microchip/vcap/vcap_api_private.h | 4 - 4 files changed, 206 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api.c b/drivers/net/ethernet/microchip/vcap/vcap_api.c index ac7a32ff755e..2f171d0b9187 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api.c +++ b/drivers/net/ethernet/microchip/vcap/vcap_api.c @@ -173,6 +173,7 @@ const struct vcap_set *vcap_keyfieldset(struct vcap_control *vctrl, return NULL; return kset; } +EXPORT_SYMBOL_GPL(vcap_keyfieldset); /* Return the typegroup table for the matching keyset (using subword size) */ const struct vcap_typegroup * @@ -824,8 +825,8 @@ vcap_find_keyset_keyfield(struct vcap_control *vctrl, } /* Match a list of keys against the keysets available in a vcap type */ -static bool vcap_rule_find_keysets(struct vcap_rule_internal *ri, - struct vcap_keyset_list *matches) +static bool _vcap_rule_find_keysets(struct vcap_rule_internal *ri, + struct vcap_keyset_list *matches) { const struct vcap_client_keyfield *ckf; int keyset, found, keycount, map_size; @@ -864,6 +865,16 @@ static bool vcap_rule_find_keysets(struct vcap_rule_internal *ri, return matches->cnt > 0; } +/* Match a list of keys against the keysets available in a vcap type */ +bool vcap_rule_find_keysets(struct vcap_rule *rule, + struct vcap_keyset_list *matches) +{ + struct vcap_rule_internal *ri = to_intrule(rule); + + return _vcap_rule_find_keysets(ri, matches); +} +EXPORT_SYMBOL_GPL(vcap_rule_find_keysets); + /* Validate a rule with respect to available port keys */ int vcap_val_rule(struct vcap_rule *rule, u16 l3_proto) { @@ -888,7 +899,7 @@ int vcap_val_rule(struct vcap_rule *rule, u16 l3_proto) matches.max = ARRAY_SIZE(keysets); if (ri->data.keyset == VCAP_KFS_NO_VALUE) { /* Iterate over rule keyfields and select keysets that fits */ - if (!vcap_rule_find_keysets(ri, &matches)) { + if (!_vcap_rule_find_keysets(ri, &matches)) { ri->data.exterr = VCAP_ERR_NO_KEYSET_MATCH; return -EINVAL; } @@ -1270,6 +1281,19 @@ int vcap_del_rules(struct vcap_control *vctrl, struct vcap_admin *admin) } EXPORT_SYMBOL_GPL(vcap_del_rules); +/* Find a client key field in a rule */ +static struct vcap_client_keyfield * +vcap_find_keyfield(struct vcap_rule *rule, enum vcap_key_field key) +{ + struct vcap_rule_internal *ri = to_intrule(rule); + struct vcap_client_keyfield *ckf; + + list_for_each_entry(ckf, &ri->data.keyfields, ctrl.list) + if (ckf->ctrl.key == key) + return ckf; + return NULL; +} + /* Find information on a key field in a rule */ const struct vcap_field *vcap_lookup_keyfield(struct vcap_rule *rule, enum vcap_key_field key) @@ -1434,6 +1458,19 @@ int vcap_rule_add_key_u128(struct vcap_rule *rule, enum vcap_key_field key, } EXPORT_SYMBOL_GPL(vcap_rule_add_key_u128); +/* Find a client action field in a rule */ +static struct vcap_client_actionfield * +vcap_find_actionfield(struct vcap_rule *rule, enum vcap_action_field act) +{ + struct vcap_rule_internal *ri = (struct vcap_rule_internal *)rule; + struct vcap_client_actionfield *caf; + + list_for_each_entry(caf, &ri->data.actionfields, ctrl.list) + if (caf->ctrl.action == act) + return caf; + return NULL; +} + static void vcap_copy_from_client_actionfield(struct vcap_rule *rule, struct vcap_client_actionfield *field, struct vcap_client_actionfield_data *data) @@ -1772,6 +1809,148 @@ int vcap_rule_get_counter(struct vcap_rule *rule, struct vcap_counter *ctr) } EXPORT_SYMBOL_GPL(vcap_rule_get_counter); +static int vcap_rule_mod_key(struct vcap_rule *rule, + enum vcap_key_field key, + enum vcap_field_type ftype, + struct vcap_client_keyfield_data *data) +{ + struct vcap_client_keyfield *field; + + field = vcap_find_keyfield(rule, key); + if (!field) + return vcap_rule_add_key(rule, key, ftype, data); + vcap_copy_from_client_keyfield(rule, field, data); + return 0; +} + +/* Modify a 32 bit key field with value and mask in the rule */ +int vcap_rule_mod_key_u32(struct vcap_rule *rule, enum vcap_key_field key, + u32 value, u32 mask) +{ + struct vcap_client_keyfield_data data; + + data.u32.value = value; + data.u32.mask = mask; + return vcap_rule_mod_key(rule, key, VCAP_FIELD_U32, &data); +} +EXPORT_SYMBOL_GPL(vcap_rule_mod_key_u32); + +static int vcap_rule_mod_action(struct vcap_rule *rule, + enum vcap_action_field action, + enum vcap_field_type ftype, + struct vcap_client_actionfield_data *data) +{ + struct vcap_client_actionfield *field; + + field = vcap_find_actionfield(rule, action); + if (!field) + return vcap_rule_add_action(rule, action, ftype, data); + vcap_copy_from_client_actionfield(rule, field, data); + return 0; +} + +/* Modify a 32 bit action field with value in the rule */ +int vcap_rule_mod_action_u32(struct vcap_rule *rule, + enum vcap_action_field action, + u32 value) +{ + struct vcap_client_actionfield_data data; + + data.u32.value = value; + return vcap_rule_mod_action(rule, action, VCAP_FIELD_U32, &data); +} +EXPORT_SYMBOL_GPL(vcap_rule_mod_action_u32); + +/* Drop keys in a keylist and any keys that are not supported by the keyset */ +int vcap_filter_rule_keys(struct vcap_rule *rule, + enum vcap_key_field keylist[], int length, + bool drop_unsupported) +{ + struct vcap_rule_internal *ri = to_intrule(rule); + struct vcap_client_keyfield *ckf, *next_ckf; + const struct vcap_field *fields; + enum vcap_key_field key; + int err = 0; + int idx; + + if (length > 0) { + err = -EEXIST; + list_for_each_entry_safe(ckf, next_ckf, + &ri->data.keyfields, ctrl.list) { + key = ckf->ctrl.key; + for (idx = 0; idx < length; ++idx) + if (key == keylist[idx]) { + list_del(&ckf->ctrl.list); + kfree(ckf); + idx++; + err = 0; + } + } + } + if (drop_unsupported) { + err = -EEXIST; + fields = vcap_keyfields(ri->vctrl, ri->admin->vtype, + rule->keyset); + if (!fields) + return err; + list_for_each_entry_safe(ckf, next_ckf, + &ri->data.keyfields, ctrl.list) { + key = ckf->ctrl.key; + if (fields[key].width == 0) { + list_del(&ckf->ctrl.list); + kfree(ckf); + err = 0; + } + } + } + return err; +} +EXPORT_SYMBOL_GPL(vcap_filter_rule_keys); + +/* Make a full copy of an existing rule with a new rule id */ +struct vcap_rule *vcap_copy_rule(struct vcap_rule *erule) +{ + struct vcap_rule_internal *ri = to_intrule(erule); + struct vcap_client_actionfield *caf; + struct vcap_client_keyfield *ckf; + struct vcap_rule *rule; + int err; + + err = vcap_api_check(ri->vctrl); + if (err) + return ERR_PTR(err); + + rule = vcap_alloc_rule(ri->vctrl, ri->ndev, ri->data.vcap_chain_id, + ri->data.user, ri->data.priority, 0); + if (IS_ERR(rule)) + return rule; + + list_for_each_entry(ckf, &ri->data.keyfields, ctrl.list) { + /* Add a key duplicate in the new rule */ + err = vcap_rule_add_key(rule, + ckf->ctrl.key, + ckf->ctrl.type, + &ckf->data); + if (err) + goto err; + } + + list_for_each_entry(caf, &ri->data.actionfields, ctrl.list) { + /* Add a action duplicate in the new rule */ + err = vcap_rule_add_action(rule, + caf->ctrl.action, + caf->ctrl.type, + &caf->data); + if (err) + goto err; + } + return rule; +err: + vcap_free_rule(rule); + return ERR_PTR(err); +} +EXPORT_SYMBOL_GPL(vcap_copy_rule); + #ifdef CONFIG_VCAP_KUNIT_TEST #include "vcap_api_kunit.c" #endif diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_client.h b/drivers/net/ethernet/microchip/vcap/vcap_api_client.h index 654ef8fa6d62..93a0fcb12a81 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api_client.h +++ b/drivers/net/ethernet/microchip/vcap/vcap_api_client.h @@ -168,6 +168,8 @@ int vcap_val_rule(struct vcap_rule *rule, u16 l3_proto); int vcap_add_rule(struct vcap_rule *rule); /* Delete rule in a VCAP instance */ int vcap_del_rule(struct vcap_control *vctrl, struct net_device *ndev, u32 id); +/* Make a full copy of an existing rule with a new rule id */ +struct vcap_rule *vcap_copy_rule(struct vcap_rule *rule); /* Update the keyset for the rule */ int vcap_set_rule_set_keyset(struct vcap_rule *rule, @@ -213,7 +215,13 @@ bool vcap_is_next_lookup(struct vcap_control *vctrl, int cur_cid, int next_cid); /* Provide all rules via a callback interface */ int vcap_rule_iter(struct vcap_control *vctrl, int (*callback)(void *, struct vcap_rule *), void *arg); - +/* Match a list of keys against the keysets available in a vcap type */ +bool vcap_rule_find_keysets(struct vcap_rule *rule, + struct vcap_keyset_list *matches); +/* Return the keyset information for the keyset */ +const struct vcap_set *vcap_keyfieldset(struct vcap_control *vctrl, + enum vcap_type vt, + enum vcap_keyfield_set keyset); /* Copy to host byte order */ void vcap_netbytes_copy(u8 *dst, u8 *src, int count); @@ -226,6 +234,10 @@ int vcap_del_rules(struct vcap_control *vctrl, struct vcap_admin *admin); /* Add a keyset to a keyset list */ bool vcap_keyset_list_add(struct vcap_keyset_list *keysetlist, enum vcap_keyfield_set keyset); +/* Drop keys in a keylist and any keys that are not supported by the keyset */ +int vcap_filter_rule_keys(struct vcap_rule *rule, + enum vcap_key_field keylist[], int length, + bool drop_unsupported); /* map keyset id to a string with the keyset name */ const char *vcap_keyset_name(struct vcap_control *vctrl, @@ -234,4 +246,12 @@ const char *vcap_keyset_name(struct vcap_control *vctrl, const char *vcap_keyfield_name(struct vcap_control *vctrl, enum vcap_key_field key); +/* Modify a 32 bit key field with value and mask in the rule */ +int vcap_rule_mod_key_u32(struct vcap_rule *rule, enum vcap_key_field key, + u32 value, u32 mask); +/* Modify a 32 bit action field with value in the rule */ +int vcap_rule_mod_action_u32(struct vcap_rule *rule, + enum vcap_action_field action, + u32 value); + #endif /* __VCAP_API_CLIENT__ */ diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c b/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c index f48d93f374af..875068e484c9 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c +++ b/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c @@ -1197,7 +1197,7 @@ static void vcap_api_rule_find_keyset_basic_test(struct kunit *test) for (idx = 0; idx < ARRAY_SIZE(ckf); idx++) list_add_tail(&ckf[idx].ctrl.list, &ri.data.keyfields); - ret = vcap_rule_find_keysets(&ri, &matches); + ret = vcap_rule_find_keysets(&ri.data, &matches); KUNIT_EXPECT_EQ(test, true, ret); KUNIT_EXPECT_EQ(test, 1, matches.cnt); @@ -1244,7 +1244,7 @@ static void vcap_api_rule_find_keyset_failed_test(struct kunit *test) for (idx = 0; idx < ARRAY_SIZE(ckf); idx++) list_add_tail(&ckf[idx].ctrl.list, &ri.data.keyfields); - ret = vcap_rule_find_keysets(&ri, &matches); + ret = vcap_rule_find_keysets(&ri.data, &matches); KUNIT_EXPECT_EQ(test, false, ret); KUNIT_EXPECT_EQ(test, 0, matches.cnt); @@ -1291,7 +1291,7 @@ static void vcap_api_rule_find_keyset_many_test(struct kunit *test) for (idx = 0; idx < ARRAY_SIZE(ckf); idx++) list_add_tail(&ckf[idx].ctrl.list, &ri.data.keyfields); - ret = vcap_rule_find_keysets(&ri, &matches); + ret = vcap_rule_find_keysets(&ri.data, &matches); KUNIT_EXPECT_EQ(test, true, ret); KUNIT_EXPECT_EQ(test, 6, matches.cnt); diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_private.h b/drivers/net/ethernet/microchip/vcap/vcap_api_private.h index 18a9a0cd9606..9ac1b1d55f22 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api_private.h +++ b/drivers/net/ethernet/microchip/vcap/vcap_api_private.h @@ -59,10 +59,6 @@ void vcap_iter_update(struct vcap_stream_iter *itr); /* Keyset and keyfield functionality */ -/* Return the keyset information for the keyset */ -const struct vcap_set *vcap_keyfieldset(struct vcap_control *vctrl, - enum vcap_type vt, - enum vcap_keyfield_set keyset); /* Return the number of keyfields in the keyset */ int vcap_keyfield_count(struct vcap_control *vctrl, enum vcap_type vt, enum vcap_keyfield_set keyset); From patchwork Wed Nov 23 15:25:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steen Hegelund X-Patchwork-Id: 25055 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2857130wrr; Wed, 23 Nov 2022 07:28:40 -0800 (PST) X-Google-Smtp-Source: AA0mqf6omp4T9yEs4zj14f3BgRRVQIRpPIZrp+EurnKGp16Ec8e2ICJVOKHzjzxgc5ZVX9DLqauZ X-Received: by 2002:a17:906:2dc2:b0:7ae:c1af:a078 with SMTP id h2-20020a1709062dc200b007aec1afa078mr25237164eji.294.1669217316439; Wed, 23 Nov 2022 07:28:36 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669217316; cv=none; d=google.com; s=arc-20160816; b=R3EeuRIUWfKvHJmeBfc2/5QVyWOWOzTPu4PAlmCECewcyBuvEwiLTI3oNflK7QkNMC UgFpRUNZ9Qa6sTCrLbXFmBxViUwKZXziK+GRvFHO1JKzRGgEvKaEYGBAz3/yneQ8a+xn 8ZseAzDYcNzqjs9fTdrDhKpVGmdsoQ2VdP+13GqnM1/JPpr9W+c5nKEOj+kSt9/JAMbq k86AaZs7G7BbZm+/zCyJ677JVujhAYvIOXEImV1k/qUJ311pkSbKYguhS5hgF/wXDN2W lWTTb8ymJw/e0MFIF3oFFEUCH1DXckRFrF5imAJluOXzdrisZVHOfOztcnDiEx1auqKd f1cg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=5UC/j3BMmdUt9fBpPG71xfbRUrQMl3z1iZ4l9BRwD50=; b=M4wdLlWlZpqg1gEjk9L1mX4qHKzdfpXezY1eHwSc1NM/r4XxLDjrxpYR+cYGQ7vj28 2elUiea4YNQyKHnx7XVEemiXXniJnimc26WjFkruCsm2K0hVF5raKCS28GjL9i3xe9vI 4jmEvJNwKpHeWQq/JvLWtM20Yz+MYd3LfeJkASthzAbLHq6f9f5BeGdxKWqo6vwNJewJ aFhGUUuAXRcyuzOSzzGUEOPNaMr1xntgNgiRk0hlttldX7nJzlptDqs2F3OB/z8LDTIH vzQUSvaRpgZZZMyukbmssnd3HWe97TgqZm5tM7rQIlC0WZgquo8QmSNELlCAYGTR7ZEB j5Dg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@microchip.com header.s=mchp header.b=D8GyBbh1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=microchip.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id sb22-20020a1709076d9600b007a9c3366e9asi16204415ejc.716.2022.11.23.07.28.11; Wed, 23 Nov 2022 07:28:36 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@microchip.com header.s=mchp header.b=D8GyBbh1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=microchip.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238772AbiKWP07 (ORCPT + 99 others); Wed, 23 Nov 2022 10:26:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36064 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236767AbiKWP0S (ORCPT ); Wed, 23 Nov 2022 10:26:18 -0500 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3CEC682235; Wed, 23 Nov 2022 07:26:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1669217172; x=1700753172; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=13nnEeD5/sqn4Q5vO902YKQTR+lPJMkEUpXmaLS9Ryc=; b=D8GyBbh1jNjDkS+RzxfnZqfWCZ9gZ2PvpmUm3cm4Ldj1jPi9PNWVsWBi X4vosrh/Vm3QkBWa31MMCb5jwOXt2512OwBc0kuK3k5IkeXCtuihbZKVa ovvj9uI/puOS7jVZDH1JEg+8MwYz6TusNXrUD/6AJiFdMqR06K380ujN3 s7Cpk7Bx7ZWsy5LDdRfRNFzh6piiBfy6HgRhNtdo8HWOUf4O4+UOTSrxX 27o0DL5Uh6ZLdzSnbEaIF4wpeBye5dG6de4wFUcRrsmgOZ/B/ezJFag4l ZgZIdU3DyG5suB0tT0EW+9On6hJiOFJ05ee/aTcNxQ7hPAXZ4i/9j00Zj g==; X-IronPort-AV: E=Sophos;i="5.96,187,1665471600"; d="scan'208";a="184877202" Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa4.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 23 Nov 2022 08:26:10 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.12; Wed, 23 Nov 2022 08:25:58 -0700 Received: from den-dk-m31857.microchip.com (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.12 via Frontend Transport; Wed, 23 Nov 2022 08:25:55 -0700 From: Steen Hegelund To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni CC: Steen Hegelund , , Randy Dunlap , "Casper Andersson" , Russell King , Wan Jiabing , "Nathan Huckleberry" , , , , "Steen Hegelund" , Daniel Machon , Horatiu Vultur , Lars Povlsen Subject: [PATCH net-next v2 2/4] net: microchip: sparx5: Support for TC protocol all Date: Wed, 23 Nov 2022 16:25:43 +0100 Message-ID: <20221123152545.1997266-3-steen.hegelund@microchip.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221123152545.1997266-1-steen.hegelund@microchip.com> References: <20221123152545.1997266-1-steen.hegelund@microchip.com> MIME-Version: 1.0 X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_PASS,T_SPF_TEMPERROR autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1750301216832502858?= X-GMAIL-MSGID: =?utf-8?q?1750301216832502858?= This allows support of TC protocol all for the Sparx5 IS2 VCAP. This is done by creating multiple rules that covers the rule size and traffic types in the IS2. Each rule size (e.g X16 and X6) may have multiple keysets and if there are more than one the type field in the VCAP rule will be wildcarded to support these keysets. Signed-off-by: Steen Hegelund --- .../microchip/sparx5/sparx5_tc_flower.c | 209 +++++++++++++++++- .../microchip/sparx5/sparx5_vcap_impl.c | 18 +- .../microchip/sparx5/sparx5_vcap_impl.h | 13 ++ 3 files changed, 234 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c index bd6bd380ba34..1ed304a816cc 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c @@ -12,6 +12,20 @@ #include "sparx5_main.h" #include "sparx5_vcap_impl.h" +#define SPX5_MAX_RULE_SIZE 13 /* allows X1, X2, X4, X6 and X12 rules */ + +/* Collect keysets and type ids for multiple rules per size */ +struct sparx5_wildcard_rule { + bool selected; + u8 value; + u8 mask; + enum vcap_keyfield_set keyset; +}; + +struct sparx5_multiple_rules { + struct sparx5_wildcard_rule rule[SPX5_MAX_RULE_SIZE]; +}; + struct sparx5_tc_flower_parse_usage { struct flow_cls_offload *fco; struct flow_rule *frule; @@ -618,7 +632,7 @@ static int sparx5_tc_add_rule_counter(struct vcap_admin *admin, { int err; - err = vcap_rule_add_action_u32(vrule, VCAP_AF_CNT_ID, vrule->id); + err = vcap_rule_mod_action_u32(vrule, VCAP_AF_CNT_ID, vrule->id); if (err) return err; @@ -626,11 +640,190 @@ static int sparx5_tc_add_rule_counter(struct vcap_admin *admin, return err; } +/* Collect all port keysets and apply the first of them, possibly wildcarded */ +static int sparx5_tc_select_protocol_keyset(struct net_device *ndev, + struct vcap_rule *vrule, + struct vcap_admin *admin, + u16 l3_proto, + struct sparx5_multiple_rules *multi) +{ + struct sparx5_port *port = netdev_priv(ndev); + struct vcap_keyset_list portkeysetlist = {}; + enum vcap_keyfield_set portkeysets[10] = {}; + struct vcap_keyset_list matches = {}; + enum vcap_keyfield_set keysets[10]; + int idx, jdx, err = 0, count = 0; + struct sparx5_wildcard_rule *mru; + const struct vcap_set *kinfo; + struct vcap_control *vctrl; + + vctrl = port->sparx5->vcap_ctrl; + + /* Find the keysets that the rule can use */ + matches.keysets = keysets; + matches.max = ARRAY_SIZE(keysets); + if (vcap_rule_find_keysets(vrule, &matches) == 0) + return -EINVAL; + + /* Find the keysets that the port configuration supports */ + portkeysetlist.max = ARRAY_SIZE(portkeysets); + portkeysetlist.keysets = portkeysets; + err = sparx5_vcap_get_port_keyset(ndev, + admin, vrule->vcap_chain_id, + l3_proto, + &portkeysetlist); + if (err) + return err; + + /* Find the intersection of the two sets of keyset */ + for (idx = 0; idx < portkeysetlist.cnt; ++idx) { + kinfo = vcap_keyfieldset(vctrl, admin->vtype, + portkeysetlist.keysets[idx]); + if (!kinfo) + continue; + + /* Find a port keyset that matches the required keys + * If there are multiple keysets then compose a type id mask + */ + for (jdx = 0; jdx < matches.cnt; ++jdx) { + if (portkeysetlist.keysets[idx] != matches.keysets[jdx]) + continue; + + mru = &multi->rule[kinfo->sw_per_item]; + if (!mru->selected) { + mru->selected = true; + mru->keyset = portkeysetlist.keysets[idx]; + mru->value = kinfo->type_id; + } + mru->value &= kinfo->type_id; + mru->mask |= kinfo->type_id; + ++count; + } + } + if (count == 0) + return -EPROTO; + + if (l3_proto == ETH_P_ALL && count < portkeysetlist.cnt) + return -ENOENT; + + for (idx = 0; idx < SPX5_MAX_RULE_SIZE; ++idx) { + mru = &multi->rule[idx]; + if (!mru->selected) + continue; + + /* Align the mask to the combined value */ + mru->mask ^= mru->value; + } + + /* Set the chosen keyset on the rule and set a wildcarded type if there + * are more than one keyset + */ + for (idx = 0; idx < SPX5_MAX_RULE_SIZE; ++idx) { + mru = &multi->rule[idx]; + if (!mru->selected) + continue; + + vcap_set_rule_set_keyset(vrule, mru->keyset); + if (count > 1) + /* Some keysets do not have a type field */ + vcap_rule_mod_key_u32(vrule, VCAP_KF_TYPE, + mru->value, + ~mru->mask); + mru->selected = false; /* mark as done */ + break; /* Stop here and add more rules later */ + } + return err; +} + +static int sparx5_tc_add_rule_copy(struct vcap_control *vctrl, + struct flow_cls_offload *fco, + struct vcap_rule *erule, + struct vcap_admin *admin, + struct sparx5_wildcard_rule *rule) +{ + enum vcap_key_field keylist[] = { + VCAP_KF_IF_IGR_PORT_MASK, + VCAP_KF_IF_IGR_PORT_MASK_SEL, + VCAP_KF_IF_IGR_PORT_MASK_RNG, + VCAP_KF_LOOKUP_FIRST_IS, + VCAP_KF_TYPE, + }; + struct vcap_rule *vrule; + int err; + + /* Add an extra rule with a special user and the new keyset */ + erule->user = VCAP_USER_TC_EXTRA; + vrule = vcap_copy_rule(erule); + if (IS_ERR(vrule)) + return PTR_ERR(vrule); + + /* Link the new rule to the existing rule with the cookie */ + vrule->cookie = erule->cookie; + vcap_filter_rule_keys(vrule, keylist, ARRAY_SIZE(keylist), true); + err = vcap_set_rule_set_keyset(vrule, rule->keyset); + if (err) { + pr_err("%s:%d: could not set keyset %s in rule: %u\n", + __func__, __LINE__, + vcap_keyset_name(vctrl, rule->keyset), + vrule->id); + goto out; + } + + /* Some keysets do not have a type field, so ignore return value */ + vcap_rule_mod_key_u32(vrule, VCAP_KF_TYPE, rule->value, ~rule->mask); + + err = vcap_set_rule_set_actionset(vrule, erule->actionset); + if (err) + goto out; + + err = sparx5_tc_add_rule_counter(admin, vrule); + if (err) + goto out; + + err = vcap_val_rule(vrule, ETH_P_ALL); + if (err) { + pr_err("%s:%d: could not validate rule: %u\n", + __func__, __LINE__, vrule->id); + vcap_set_tc_exterr(fco, vrule); + goto out; + } + err = vcap_add_rule(vrule); + if (err) { + pr_err("%s:%d: could not add rule: %u\n", + __func__, __LINE__, vrule->id); + goto out; + } +out: + vcap_free_rule(vrule); + return err; +} + +static int sparx5_tc_add_remaining_rules(struct vcap_control *vctrl, + struct flow_cls_offload *fco, + struct vcap_rule *erule, + struct vcap_admin *admin, + struct sparx5_multiple_rules *multi) +{ + int idx, err = 0; + + for (idx = 0; idx < SPX5_MAX_RULE_SIZE; ++idx) { + if (!multi->rule[idx].selected) + continue; + + err = sparx5_tc_add_rule_copy(vctrl, fco, erule, admin, + &multi->rule[idx]); + if (err) + break; + } + return err; +} + static int sparx5_tc_flower_replace(struct net_device *ndev, struct flow_cls_offload *fco, struct vcap_admin *admin) { struct sparx5_port *port = netdev_priv(ndev); + struct sparx5_multiple_rules multi = {}; struct flow_action_entry *act; struct vcap_control *vctrl; struct flow_rule *frule; @@ -700,6 +893,15 @@ static int sparx5_tc_flower_replace(struct net_device *ndev, goto out; } } + + err = sparx5_tc_select_protocol_keyset(ndev, vrule, admin, l3_proto, + &multi); + if (err) { + NL_SET_ERR_MSG_MOD(fco->common.extack, + "No matching port keyset for filter protocol and keys"); + goto out; + } + /* provide the l3 protocol to guide the keyset selection */ err = vcap_val_rule(vrule, l3_proto); if (err) { @@ -710,6 +912,11 @@ static int sparx5_tc_flower_replace(struct net_device *ndev, if (err) NL_SET_ERR_MSG_MOD(fco->common.extack, "Could not add the filter"); + + if (l3_proto == ETH_P_ALL) + err = sparx5_tc_add_remaining_rules(vctrl, fco, vrule, admin, + &multi); + out: vcap_free_rule(vrule); return err; diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c index 0c4d4e6d51e6..a0c126ba9a87 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c @@ -7,11 +7,6 @@ * https://github.com/microchip-ung/sparx-5_reginfo */ -#include -#include - -#include "vcap_api.h" -#include "vcap_api_client.h" #include "vcap_api_debugfs.h" #include "sparx5_main_regs.h" #include "sparx5_main.h" @@ -279,6 +274,19 @@ static int sparx5_vcap_is2_get_port_keysets(struct net_device *ndev, return 0; } +/* Get the port keyset for the vcap lookup */ +int sparx5_vcap_get_port_keyset(struct net_device *ndev, + struct vcap_admin *admin, + int cid, + u16 l3_proto, + struct vcap_keyset_list *kslist) +{ + int lookup; + + lookup = sparx5_vcap_cid_to_lookup(cid); + return sparx5_vcap_is2_get_port_keysets(ndev, lookup, kslist, l3_proto); +} + /* API callback used for validating a field keyset (check the port keysets) */ static enum vcap_keyfield_set sparx5_vcap_validate_keyset(struct net_device *ndev, diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.h b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.h index 8a6b7e3d2618..0a0f2412c980 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.h +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.h @@ -10,6 +10,12 @@ #ifndef __SPARX5_VCAP_IMPL_H__ #define __SPARX5_VCAP_IMPL_H__ +#include +#include + +#include "vcap_api.h" +#include "vcap_api_client.h" + #define SPARX5_VCAP_CID_IS2_L0 VCAP_CID_INGRESS_STAGE2_L0 /* IS2 lookup 0 */ #define SPARX5_VCAP_CID_IS2_L1 VCAP_CID_INGRESS_STAGE2_L1 /* IS2 lookup 1 */ #define SPARX5_VCAP_CID_IS2_L2 VCAP_CID_INGRESS_STAGE2_L2 /* IS2 lookup 2 */ @@ -65,4 +71,11 @@ enum vcap_is2_port_sel_arp { VCAP_IS2_PS_ARP_ARP, }; +/* Get the port keyset for the vcap lookup */ +int sparx5_vcap_get_port_keyset(struct net_device *ndev, + struct vcap_admin *admin, + int cid, + u16 l3_proto, + struct vcap_keyset_list *kslist); + #endif /* __SPARX5_VCAP_IMPL_H__ */ From patchwork Wed Nov 23 15:25:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steen Hegelund X-Patchwork-Id: 25056 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2857392wrr; Wed, 23 Nov 2022 07:29:12 -0800 (PST) X-Google-Smtp-Source: AA0mqf6slSCeC5gaCDgprufpkCfjsadeXQAo62TvPUYhIPM4S7nPyeQpoIIGspMvJ/FTGq52Z+HB X-Received: by 2002:a17:903:3311:b0:183:ee9e:4988 with SMTP id jk17-20020a170903331100b00183ee9e4988mr8940265plb.56.1669217351914; Wed, 23 Nov 2022 07:29:11 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669217351; cv=none; d=google.com; s=arc-20160816; b=UpM/+2ztsUjIqkozBqGPg4/7YLcJkpON7s+Wax4gMZfnI3jurmxlIPiIqa3aIcEaul Aq0ZJYwKutZTsekUFKaHpphxgNz7Rw7cAGAyOfd0o2Xeapm8RJouYP7bmxIbe7CTC4kC JPiBzpXCuj5690H/rbTAVjosoISwvUWn0nV9yX6QL/TfqCgL4K4O79TGAJB+m6KBDux5 ehLzt0DrQdlo+OamXSDj/8YMcJ+QR+7kq7sisp5jpdP+4Y/ByccWDqvMsmhAv67L+tVl sZPAT2KcsFajVfFwgpeJWlVXQprt8+GTLPiHhdwENFGXCnirZOQiUXiJwdTDuTIHyhFN q9ag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=SbaLM7NJ0XkEzdEDC58XaG3v5GD8nsmg88doHvzzBII=; b=mh2wgxJHH0g063Tuwra9bgeYwL/kCZKkwu3iBeXRVPsIvpv+XpkIDHpaeL1b2YEiqg l+zXabHyr0u1XIbDpec7E1FNOLBNCOESRDzh70/wckqnSL8oPLv0/X0hSL5aVvvyGzQR LBxi2HdTqZmAIegT6OeKzaWBfkm0zGVngDaXXL/NXDm5mcOCPI4gikmgS+B+hpBmE9VH ayx8t3teC24+TzXcurwX3428m7RH5/yqeo8elFt2oUWelIRLoO9lmgBCgRTbTCrJIYnw ftxoQ1OwsAQWaDPK/wXBrq72PvlelILCZQApWoqo4qPxsKRjxbwE1HKuKgAkWNal3gb4 WOBQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@microchip.com header.s=mchp header.b=UkiNFf7v; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=microchip.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id y5-20020a170902700500b001891fd4ebf0si7806430plk.495.2022.11.23.07.28.58; Wed, 23 Nov 2022 07:29:11 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@microchip.com header.s=mchp header.b=UkiNFf7v; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=microchip.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237215AbiKWP1a (ORCPT + 99 others); Wed, 23 Nov 2022 10:27:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36118 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238248AbiKWP0T (ORCPT ); Wed, 23 Nov 2022 10:26:19 -0500 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6C9699CF6A; Wed, 23 Nov 2022 07:26:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1669217173; x=1700753173; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=TKg6z9yXyQb61xdfgwCuiBPWIQ4ZM4P9nYWrl7wtjag=; b=UkiNFf7vjhhQTmCuJb6H51yWY35/W5842L5+8JvHE1ND3CSvhHBtDNjd C76VOtgU3sWDxRu3Nc/UbavNzcHTNedT72L7h/HHVJ4rLVg7YCs0vU84r LRUF4iFMaarV9a9qpd9GaxDkeafOO6KJwh1TsUcP6d0oUFA5oK77zyv0H hCwVq+RlH89bDRMhLUOz3dV8Y8uFznulQUBgMWZv9H9f/p6Mlm/27Tpz9 +XA+uCD3zPuKejU0vzGSo7SZvPLhj4gEBLbfJaDtSNYB4aB/k+xe2G12C 58Vc0xhzcaBxwKM2hTTwFHug+oltomStmBNA2nd9bvH5E5r1b1IwVyO0a A==; X-IronPort-AV: E=Sophos;i="5.96,187,1665471600"; d="scan'208";a="184877216" Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa4.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 23 Nov 2022 08:26:12 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.12; Wed, 23 Nov 2022 08:26:01 -0700 Received: from den-dk-m31857.microchip.com (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.12 via Frontend Transport; Wed, 23 Nov 2022 08:25:58 -0700 From: Steen Hegelund To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni CC: Steen Hegelund , , Randy Dunlap , "Casper Andersson" , Russell King , Wan Jiabing , "Nathan Huckleberry" , , , , "Steen Hegelund" , Daniel Machon , Horatiu Vultur , Lars Povlsen Subject: [PATCH net-next v2 3/4] net: microchip: sparx5: Support for displaying a list of keysets Date: Wed, 23 Nov 2022 16:25:44 +0100 Message-ID: <20221123152545.1997266-4-steen.hegelund@microchip.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221123152545.1997266-1-steen.hegelund@microchip.com> References: <20221123152545.1997266-1-steen.hegelund@microchip.com> MIME-Version: 1.0 X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_PASS,T_SPF_TEMPERROR autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1750301253830033723?= X-GMAIL-MSGID: =?utf-8?q?1750301253830033723?= This will display a list of keyset in case the type_id field in the VCAP rule has been wildcarded. Signed-off-by: Steen Hegelund --- .../microchip/vcap/vcap_api_debugfs.c | 98 +++++++++++-------- .../microchip/vcap/vcap_api_debugfs_kunit.c | 20 +++- 2 files changed, 74 insertions(+), 44 deletions(-) diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c b/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c index d9c7ca988b76..5df00e940333 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c +++ b/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs.c @@ -192,22 +192,22 @@ static bool vcap_verify_keystream_keyset(struct vcap_control *vctrl, vcap_iter_init(&iter, vcap->sw_width, tgt, typefld->offset); vcap_decode_field(keystream, &iter, typefld->width, (u8 *)&value); - return (value == info->type_id); + return (value & mask) == (info->type_id & mask); } /* Verify that the typegroup information, subword count, keyset and type id - * are in sync and correct, return the keyset + * are in sync and correct, return the list of matching keysets */ -static enum -vcap_keyfield_set vcap_find_keystream_keyset(struct vcap_control *vctrl, - enum vcap_type vt, - u32 *keystream, - u32 *mskstream, - bool mask, int sw_max) +static int +vcap_find_keystream_keysets(struct vcap_control *vctrl, + enum vcap_type vt, + u32 *keystream, + u32 *mskstream, + bool mask, int sw_max, + struct vcap_keyset_list *kslist) { const struct vcap_set *keyfield_set; int sw_count, idx; - bool res; sw_count = vcap_find_keystream_typegroup_sw(vctrl, vt, keystream, mask, sw_max); @@ -219,11 +219,12 @@ vcap_keyfield_set vcap_find_keystream_keyset(struct vcap_control *vctrl, if (keyfield_set[idx].sw_per_item != sw_count) continue; - res = vcap_verify_keystream_keyset(vctrl, vt, keystream, - mskstream, idx); - if (res) - return idx; + if (vcap_verify_keystream_keyset(vctrl, vt, keystream, + mskstream, idx)) + vcap_keyset_list_add(kslist, idx); } + if (kslist->cnt > 0) + return 0; return -EINVAL; } @@ -296,13 +297,14 @@ vcap_find_actionstream_actionset(struct vcap_control *vctrl, return -EINVAL; } -/* Read key data from a VCAP address and discover if there is a rule keyset +/* Read key data from a VCAP address and discover if there are any rule keysets * here */ -static int vcap_addr_keyset(struct vcap_control *vctrl, - struct net_device *ndev, - struct vcap_admin *admin, - int addr) +static int vcap_addr_keysets(struct vcap_control *vctrl, + struct net_device *ndev, + struct vcap_admin *admin, + int addr, + struct vcap_keyset_list *kslist) { enum vcap_type vt = admin->vtype; int keyset_sw_regs, idx; @@ -320,9 +322,10 @@ static int vcap_addr_keyset(struct vcap_control *vctrl, } if (key == 0 && mask == 0) return -EINVAL; - /* Decode and locate the keyset */ - return vcap_find_keystream_keyset(vctrl, vt, admin->cache.keystream, - admin->cache.maskstream, false, 0); + /* Decode and locate the keysets */ + return vcap_find_keystream_keysets(vctrl, vt, admin->cache.keystream, + admin->cache.maskstream, false, 0, + kslist); } static int vcap_read_rule(struct vcap_rule_internal *ri) @@ -471,9 +474,11 @@ static int vcap_debugfs_show_rule_keyset(struct vcap_rule_internal *ri, struct vcap_control *vctrl = ri->vctrl; struct vcap_stream_iter kiter, miter; struct vcap_admin *admin = ri->admin; + enum vcap_keyfield_set keysets[10]; const struct vcap_field *keyfield; enum vcap_type vt = admin->vtype; const struct vcap_typegroup *tgt; + struct vcap_keyset_list matches; enum vcap_keyfield_set keyset; int idx, res, keyfield_count; u32 *maskstream; @@ -483,16 +488,22 @@ static int vcap_debugfs_show_rule_keyset(struct vcap_rule_internal *ri, keystream = admin->cache.keystream; maskstream = admin->cache.maskstream; - res = vcap_find_keystream_keyset(vctrl, vt, keystream, maskstream, - false, 0); + matches.keysets = keysets; + matches.cnt = 0; + matches.max = ARRAY_SIZE(keysets); + res = vcap_find_keystream_keysets(vctrl, vt, keystream, maskstream, + false, 0, &matches); if (res < 0) { - pr_err("%s:%d: could not find valid keyset: %d\n", + pr_err("%s:%d: could not find valid keysets: %d\n", __func__, __LINE__, res); return -EINVAL; } - keyset = res; - out->prf(out->dst, " keyset: %s\n", - vcap_keyset_name(vctrl, ri->data.keyset)); + keyset = matches.keysets[0]; + out->prf(out->dst, " keysets:"); + for (idx = 0; idx < matches.cnt; ++idx) + out->prf(out->dst, " %s", + vcap_keyset_name(vctrl, matches.keysets[idx])); + out->prf(out->dst, "\n"); out->prf(out->dst, " keyset_sw: %d\n", ri->keyset_sw); out->prf(out->dst, " keyset_sw_regs: %d\n", ri->keyset_sw_regs); keyfield_count = vcap_keyfield_count(vctrl, vt, keyset); @@ -647,11 +658,12 @@ static int vcap_show_admin_raw(struct vcap_control *vctrl, struct vcap_admin *admin, struct vcap_output_print *out) { + enum vcap_keyfield_set keysets[10]; enum vcap_type vt = admin->vtype; + struct vcap_keyset_list kslist; struct vcap_rule_internal *ri; const struct vcap_set *info; - int keyset; - int addr; + int addr, idx; int ret; if (list_empty(&admin->rules)) @@ -664,24 +676,32 @@ static int vcap_show_admin_raw(struct vcap_control *vctrl, ri = list_first_entry(&admin->rules, struct vcap_rule_internal, list); /* Go from higher to lower addresses searching for a keyset */ + kslist.keysets = keysets; + kslist.max = ARRAY_SIZE(keysets); for (addr = admin->last_valid_addr; addr >= admin->first_valid_addr; --addr) { - keyset = vcap_addr_keyset(vctrl, ri->ndev, admin, addr); - if (keyset < 0) + kslist.cnt = 0; + ret = vcap_addr_keysets(vctrl, ri->ndev, admin, addr, &kslist); + if (ret < 0) continue; - info = vcap_keyfieldset(vctrl, vt, keyset); + info = vcap_keyfieldset(vctrl, vt, kslist.keysets[0]); if (!info) continue; - if (addr % info->sw_per_item) + if (addr % info->sw_per_item) { pr_info("addr: %d X%d error rule, keyset: %s\n", addr, info->sw_per_item, - vcap_keyset_name(vctrl, keyset)); - else - out->prf(out->dst, " addr: %d, X%d rule, keyset: %s\n", - addr, - info->sw_per_item, - vcap_keyset_name(vctrl, keyset)); + vcap_keyset_name(vctrl, kslist.keysets[0])); + } else { + out->prf(out->dst, " addr: %d, X%d rule, keysets:", + addr, + info->sw_per_item); + for (idx = 0; idx < kslist.cnt; ++idx) + out->prf(out->dst, " %s", + vcap_keyset_name(vctrl, + kslist.keysets[idx])); + out->prf(out->dst, "\n"); + } } return 0; } diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs_kunit.c b/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs_kunit.c index ed455dad3a14..cf594668d5d9 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs_kunit.c +++ b/drivers/net/ethernet/microchip/vcap/vcap_api_debugfs_kunit.c @@ -316,24 +316,34 @@ static void vcap_api_addr_keyset_test(struct kunit *test) .actionstream = actdata, }, }; + enum vcap_keyfield_set keysets[10]; + struct vcap_keyset_list matches; int ret, idx, addr; vcap_test_api_init(&admin); /* Go from higher to lower addresses searching for a keyset */ + matches.keysets = keysets; + matches.cnt = 0; + matches.max = ARRAY_SIZE(keysets); for (idx = ARRAY_SIZE(keydata) - 1, addr = 799; idx > 0; --idx, --addr) { admin.cache.keystream = &keydata[idx]; admin.cache.maskstream = &mskdata[idx]; - ret = vcap_addr_keyset(&test_vctrl, &test_netdev, &admin, addr); + ret = vcap_addr_keysets(&test_vctrl, &test_netdev, &admin, + addr, &matches); KUNIT_EXPECT_EQ(test, -EINVAL, ret); } /* Finally we hit the start of the rule */ admin.cache.keystream = &keydata[idx]; admin.cache.maskstream = &mskdata[idx]; - ret = vcap_addr_keyset(&test_vctrl, &test_netdev, &admin, addr); - KUNIT_EXPECT_EQ(test, VCAP_KFS_MAC_ETYPE, ret); + matches.cnt = 0; + ret = vcap_addr_keysets(&test_vctrl, &test_netdev, &admin, + addr, &matches); + KUNIT_EXPECT_EQ(test, 0, ret); + KUNIT_EXPECT_EQ(test, matches.cnt, 1); + KUNIT_EXPECT_EQ(test, matches.keysets[0], VCAP_KFS_MAC_ETYPE); } static void vcap_api_show_admin_raw_test(struct kunit *test) @@ -362,7 +372,7 @@ static void vcap_api_show_admin_raw_test(struct kunit *test) .prf = (void *)test_prf, }; const char *test_expected = - " addr: 786, X6 rule, keyset: VCAP_KFS_MAC_ETYPE\n"; + " addr: 786, X6 rule, keysets: VCAP_KFS_MAC_ETYPE\n"; int ret; vcap_test_api_init(&admin); @@ -442,7 +452,7 @@ static const char * const test_admin_expect[] = { " chain_id: 0\n", " user: 0\n", " priority: 0\n", - " keyset: VCAP_KFS_MAC_ETYPE\n", + " keysets: VCAP_KFS_MAC_ETYPE\n", " keyset_sw: 6\n", " keyset_sw_regs: 2\n", " ETYPE_LEN_IS: W1: 1/1\n", From patchwork Wed Nov 23 15:25:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steen Hegelund X-Patchwork-Id: 25057 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2857571wrr; Wed, 23 Nov 2022 07:29:32 -0800 (PST) X-Google-Smtp-Source: AA0mqf5Dz3AVuW9IaxHIq55iko0Lr3ecRRnLzBqJ0I1j21rt74v+JYsV9v/HhyEwzHJ11oF96QiD X-Received: by 2002:a05:6402:142:b0:461:7fe6:9ea7 with SMTP id s2-20020a056402014200b004617fe69ea7mr25711695edu.94.1669217372405; Wed, 23 Nov 2022 07:29:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669217372; cv=none; d=google.com; s=arc-20160816; b=Evdm2nS0aShlwEjK2yWTaIXYg0uN919lykvdwj/uFsMMVULQVsd+2Fk2csxmgfSx/g U44WtXz6GEKD87vnpqmPzZdI4sMr/2F8nTy34lh0Ur9DaEH2KSfr4i3tRNtUEY+zCB8C kozpARc4N7UD9hNhPQP4jz25/7iO0d3IHdIy/XdSwDQ4fyp8Q7hAk5xHQNL61UtnOXXE oRAd1zsfSnhfRZ96JvoB8vO6uqwEhXMbyX+DYlrntgBE6oHoPcrKnwtjZmhadFnIfIbt 8qrdxCeB4n77xe2Du8g4LVmgRDR/ktm0q9vjdqL3JyXqZFkOaGvXc8MKk7+V3plh5dIG Ju3g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=0b3UknLLpjOfgoJ833cJIzmHRhmWWEXrYbGeTQL8zEw=; b=XoxY73DUmkws4IbJD8+y0vjakZ7t48E1CA9LzdTeGJ2CK/U4B1+C9M2fM21Fkc5WBa 9G4EBeHNC1dMbFO9fGDZKeiru83NGeBp6tCy23Vkz5igLZgczjtN+TQP49viu3bcmVTp nPXlhxg35XmvMdOxrraXuRx26dT9UhwzRGbTtO5VK2Rj8cspK69P9bMnhPkKoetbDrOM VnBcmOOTIEWJ1GsEsUnLmEelZ1x3l1pcmSIzpHGvESgG689v/YAA0w26e7UjT2tvx3K9 R1zSdITQ/0nygZP9t19a8TCzvsY1x/BXWUO/NEczr4Gn7NhAjBLWrt/B8rChNk3OfYGQ A2dQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@microchip.com header.s=mchp header.b=IAd51jm1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=microchip.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id di19-20020a170906731300b007aee592fd06si15957882ejc.203.2022.11.23.07.29.08; Wed, 23 Nov 2022 07:29:32 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@microchip.com header.s=mchp header.b=IAd51jm1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=microchip.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237965AbiKWP1i (ORCPT + 99 others); Wed, 23 Nov 2022 10:27:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36376 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237852AbiKWP0r (ORCPT ); Wed, 23 Nov 2022 10:26:47 -0500 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 523ACA6590; Wed, 23 Nov 2022 07:26:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1669217190; x=1700753190; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=aWK/w3O8H43VBVicVuiR2cJT/wFQ8uPk13PWRF6aQ9M=; b=IAd51jm1doyBzUtRUXL4G12lJ3RkisiBtZtpalUnWFYwRv5w9KM/JhoY Xb7mgD9mxKXDK7GsWrcNAtbgJTI3b0lqOsQd+IgRIuQtyZGObS5IDau4m y53TrO1BDhe0zXeIvXh3dTPkR1yjNuIY4dNRZnS/FE1cXJyxpQBEKAkFi 8JM4j1x2BN1sTG8YS1eLqUh+QqSsLR/vhD6GiS0B2InDYqyeER9F92SYn tBYyw0ggiHfmE8817Y8g6ARfuh1sitCMSfMDGOBPkLmAWGXXA9XGsGcNM ypzPh9kt6cvLO49gaBU1Cd77Q3iRoEgygjhd3pMS/PjIcdk8D1WkCGtBb A==; X-IronPort-AV: E=Sophos;i="5.96,187,1665471600"; d="scan'208";a="184877312" Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa4.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 23 Nov 2022 08:26:29 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.12; Wed, 23 Nov 2022 08:26:05 -0700 Received: from den-dk-m31857.microchip.com (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.12 via Frontend Transport; Wed, 23 Nov 2022 08:26:02 -0700 From: Steen Hegelund To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni CC: Steen Hegelund , , Randy Dunlap , "Casper Andersson" , Russell King , Wan Jiabing , "Nathan Huckleberry" , , , , "Steen Hegelund" , Daniel Machon , Horatiu Vultur , Lars Povlsen Subject: [PATCH net-next v2 4/4] net: microchip: sparx5: Add VCAP filter keys KUNIT test Date: Wed, 23 Nov 2022 16:25:45 +0100 Message-ID: <20221123152545.1997266-5-steen.hegelund@microchip.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221123152545.1997266-1-steen.hegelund@microchip.com> References: <20221123152545.1997266-1-steen.hegelund@microchip.com> MIME-Version: 1.0 X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_PASS,T_SPF_TEMPERROR autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1750301275395122352?= X-GMAIL-MSGID: =?utf-8?q?1750301275395122352?= This tests the filtering of keys, either dropping unsupported keys or dropping keys specified in a list. Signed-off-by: Steen Hegelund --- .../ethernet/microchip/vcap/vcap_api_kunit.c | 194 ++++++++++++++++++ 1 file changed, 194 insertions(+) diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c b/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c index 875068e484c9..76a31215ebfb 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c +++ b/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c @@ -1954,6 +1954,198 @@ static void vcap_api_next_lookup_advanced_test(struct kunit *test) KUNIT_EXPECT_EQ(test, true, ret); } +static void vcap_api_filter_unsupported_keys_test(struct kunit *test) +{ + struct vcap_admin admin = { + .vtype = VCAP_TYPE_IS2, + }; + struct vcap_rule_internal ri = { + .admin = &admin, + .vctrl = &test_vctrl, + .data.keyset = VCAP_KFS_MAC_ETYPE, + }; + enum vcap_key_field keylist[] = { + VCAP_KF_TYPE, + VCAP_KF_LOOKUP_FIRST_IS, + VCAP_KF_ARP_ADDR_SPACE_OK_IS, /* arp keys are not in keyset */ + VCAP_KF_ARP_PROTO_SPACE_OK_IS, + VCAP_KF_ARP_LEN_OK_IS, + VCAP_KF_ARP_TGT_MATCH_IS, + VCAP_KF_ARP_SENDER_MATCH_IS, + VCAP_KF_ARP_OPCODE_UNKNOWN_IS, + VCAP_KF_ARP_OPCODE, + VCAP_KF_8021Q_DEI_CLS, + VCAP_KF_8021Q_PCP_CLS, + VCAP_KF_8021Q_VID_CLS, + VCAP_KF_L2_MC_IS, + VCAP_KF_L2_BC_IS, + }; + enum vcap_key_field expected[] = { + VCAP_KF_TYPE, + VCAP_KF_LOOKUP_FIRST_IS, + VCAP_KF_8021Q_DEI_CLS, + VCAP_KF_8021Q_PCP_CLS, + VCAP_KF_8021Q_VID_CLS, + VCAP_KF_L2_MC_IS, + VCAP_KF_L2_BC_IS, + }; + struct vcap_client_keyfield *ckf, *next; + bool ret; + int idx; + + /* Add all keys to the rule */ + INIT_LIST_HEAD(&ri.data.keyfields); + for (idx = 0; idx < ARRAY_SIZE(keylist); idx++) { + ckf = kzalloc(sizeof(*ckf), GFP_KERNEL); + if (ckf) { + ckf->ctrl.key = keylist[idx]; + list_add_tail(&ckf->ctrl.list, &ri.data.keyfields); + } + } + + KUNIT_EXPECT_EQ(test, 14, ARRAY_SIZE(keylist)); + + /* Drop unsupported keys from the rule */ + ret = vcap_filter_rule_keys(&ri.data, NULL, 0, true); + + KUNIT_EXPECT_EQ(test, 0, ret); + + /* Check remaining keys in the rule */ + idx = 0; + list_for_each_entry_safe(ckf, next, &ri.data.keyfields, ctrl.list) { + KUNIT_EXPECT_EQ(test, expected[idx], ckf->ctrl.key); + list_del(&ckf->ctrl.list); + kfree(ckf); + ++idx; + } + KUNIT_EXPECT_EQ(test, 7, idx); +} + +static void vcap_api_filter_keylist_test(struct kunit *test) +{ + struct vcap_admin admin = { + .vtype = VCAP_TYPE_IS0, + }; + struct vcap_rule_internal ri = { + .admin = &admin, + .vctrl = &test_vctrl, + .data.keyset = VCAP_KFS_NORMAL_7TUPLE, + }; + enum vcap_key_field keylist[] = { + VCAP_KF_TYPE, + VCAP_KF_LOOKUP_FIRST_IS, + VCAP_KF_LOOKUP_GEN_IDX_SEL, + VCAP_KF_LOOKUP_GEN_IDX, + VCAP_KF_IF_IGR_PORT_MASK_SEL, + VCAP_KF_IF_IGR_PORT_MASK, + VCAP_KF_L2_MC_IS, + VCAP_KF_L2_BC_IS, + VCAP_KF_8021Q_VLAN_TAGS, + VCAP_KF_8021Q_TPID0, + VCAP_KF_8021Q_PCP0, + VCAP_KF_8021Q_DEI0, + VCAP_KF_8021Q_VID0, + VCAP_KF_8021Q_TPID1, + VCAP_KF_8021Q_PCP1, + VCAP_KF_8021Q_DEI1, + VCAP_KF_8021Q_VID1, + VCAP_KF_8021Q_TPID2, + VCAP_KF_8021Q_PCP2, + VCAP_KF_8021Q_DEI2, + VCAP_KF_8021Q_VID2, + VCAP_KF_L2_DMAC, + VCAP_KF_L2_SMAC, + VCAP_KF_IP_MC_IS, + VCAP_KF_ETYPE_LEN_IS, + VCAP_KF_ETYPE, + VCAP_KF_IP_SNAP_IS, + VCAP_KF_IP4_IS, + VCAP_KF_L3_FRAGMENT_TYPE, + VCAP_KF_L3_FRAG_INVLD_L4_LEN, + VCAP_KF_L3_OPTIONS_IS, + VCAP_KF_L3_DSCP, + VCAP_KF_L3_IP6_DIP, + VCAP_KF_L3_IP6_SIP, + VCAP_KF_TCP_UDP_IS, + VCAP_KF_TCP_IS, + VCAP_KF_L4_SPORT, + VCAP_KF_L4_RNG, + }; + enum vcap_key_field droplist[] = { + VCAP_KF_8021Q_TPID1, + VCAP_KF_8021Q_PCP1, + VCAP_KF_8021Q_DEI1, + VCAP_KF_8021Q_VID1, + VCAP_KF_8021Q_TPID2, + VCAP_KF_8021Q_PCP2, + VCAP_KF_8021Q_DEI2, + VCAP_KF_8021Q_VID2, + VCAP_KF_L3_IP6_DIP, + VCAP_KF_L3_IP6_SIP, + VCAP_KF_L4_SPORT, + VCAP_KF_L4_RNG, + }; + enum vcap_key_field expected[] = { + VCAP_KF_TYPE, + VCAP_KF_LOOKUP_FIRST_IS, + VCAP_KF_LOOKUP_GEN_IDX_SEL, + VCAP_KF_LOOKUP_GEN_IDX, + VCAP_KF_IF_IGR_PORT_MASK_SEL, + VCAP_KF_IF_IGR_PORT_MASK, + VCAP_KF_L2_MC_IS, + VCAP_KF_L2_BC_IS, + VCAP_KF_8021Q_VLAN_TAGS, + VCAP_KF_8021Q_TPID0, + VCAP_KF_8021Q_PCP0, + VCAP_KF_8021Q_DEI0, + VCAP_KF_8021Q_VID0, + VCAP_KF_L2_DMAC, + VCAP_KF_L2_SMAC, + VCAP_KF_IP_MC_IS, + VCAP_KF_ETYPE_LEN_IS, + VCAP_KF_ETYPE, + VCAP_KF_IP_SNAP_IS, + VCAP_KF_IP4_IS, + VCAP_KF_L3_FRAGMENT_TYPE, + VCAP_KF_L3_FRAG_INVLD_L4_LEN, + VCAP_KF_L3_OPTIONS_IS, + VCAP_KF_L3_DSCP, + VCAP_KF_TCP_UDP_IS, + VCAP_KF_TCP_IS, + }; + struct vcap_client_keyfield *ckf, *next; + bool ret; + int idx; + + /* Add all keys to the rule */ + INIT_LIST_HEAD(&ri.data.keyfields); + for (idx = 0; idx < ARRAY_SIZE(keylist); idx++) { + ckf = kzalloc(sizeof(*ckf), GFP_KERNEL); + if (ckf) { + ckf->ctrl.key = keylist[idx]; + list_add_tail(&ckf->ctrl.list, &ri.data.keyfields); + } + } + + KUNIT_EXPECT_EQ(test, 38, ARRAY_SIZE(keylist)); + + /* Drop listed keys from the rule */ + ret = vcap_filter_rule_keys(&ri.data, droplist, ARRAY_SIZE(droplist), + false); + + KUNIT_EXPECT_EQ(test, 0, ret); + + /* Check remaining keys in the rule */ + idx = 0; + list_for_each_entry_safe(ckf, next, &ri.data.keyfields, ctrl.list) { + KUNIT_EXPECT_EQ(test, expected[idx], ckf->ctrl.key); + list_del(&ckf->ctrl.list); + kfree(ckf); + ++idx; + } + KUNIT_EXPECT_EQ(test, 26, idx); +} + static struct kunit_suite vcap_api_rule_remove_test_suite = { .name = "VCAP_API_Rule_Remove_Testsuite", .test_cases = vcap_api_rule_remove_test_cases, @@ -1984,6 +2176,8 @@ static struct kunit_suite vcap_api_rule_counter_test_suite = { static struct kunit_case vcap_api_support_test_cases[] = { KUNIT_CASE(vcap_api_next_lookup_basic_test), KUNIT_CASE(vcap_api_next_lookup_advanced_test), + KUNIT_CASE(vcap_api_filter_unsupported_keys_test), + KUNIT_CASE(vcap_api_filter_keylist_test), {} };