net: microchip: sparx5: Support for displaying a list of keysets
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 <steen.hegelund@microchip.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
0ca6094848
commit
14b639caa6
@ -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;
|
||||
}
|
||||
|
@ -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",
|
||||
|
Loading…
x
Reference in New Issue
Block a user