Commit 14b639ca authored by Steen Hegelund's avatar Steen Hegelund Committed by David S. Miller
Browse files

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: default avatarSteen Hegelund <steen.hegelund@microchip.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0ca60948
Loading
Loading
Loading
Loading
+59 −39
Original line number Diff line number Diff line
@@ -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,
static int
vcap_find_keystream_keysets(struct vcap_control *vctrl,
			    enum vcap_type vt,
			    u32 *keystream,
			    u32 *mskstream,
					     bool mask, int sw_max)
			    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,
static int vcap_addr_keysets(struct vcap_control *vctrl,
			     struct net_device *ndev,
			     struct vcap_admin *admin,
			    int addr)
			     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",
				vcap_keyset_name(vctrl, kslist.keysets[0]));
		} else {
			out->prf(out->dst, "  addr: %d, X%d rule, keysets:",
				 addr,
			   info->sw_per_item,
			   vcap_keyset_name(vctrl, keyset));
				 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;
}
+15 −5
Original line number Diff line number Diff line
@@ -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",