[dpdk-dev] [PATCH v2 5/5] app/testpmd: allow to configure RSS hash key

Ivan Boule ivan.boule at 6wind.com
Fri May 16 10:58:43 CEST 2014


Add the command "port config X rss-hash-key key" in the 'testpmd'
application to configure the RSS hash key used to compute the RSS
hash of input [IP] packets received on port X.

Signed-off-by: Ivan Boule <ivan.boule at 6wind.com>
---
 app/test-pmd/cmdline.c |   96 +++++++++++++++++++++++++++++++++++++++++++++++-
 app/test-pmd/config.c  |   28 ++++++++++++++
 app/test-pmd/testpmd.h |    1 +
 3 files changed, 124 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 0b6749c..7b4f090 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -1192,6 +1192,99 @@ cmdline_parse_inst_t cmd_config_rss = {
 	},
 };
 
+/* *** configure rss hash key *** */
+struct cmd_config_rss_hash_key {
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t config;
+	uint8_t port_id;
+	cmdline_fixed_string_t rss_hash_key;
+	cmdline_fixed_string_t key;
+};
+
+#define RSS_HASH_KEY_LENGTH 40
+static uint8_t
+hexa_digit_to_value(char hexa_digit)
+{
+	if ((hexa_digit >= '0') && (hexa_digit <= '9'))
+		return (uint8_t) (hexa_digit - '0');
+	if ((hexa_digit >= 'a') && (hexa_digit <= 'f'))
+		return (uint8_t) ((hexa_digit - 'a') + 10);
+	if ((hexa_digit >= 'A') && (hexa_digit <= 'F'))
+		return (uint8_t) ((hexa_digit - 'A') + 10);
+	/* Invalid hexa digit */
+	return 0xFF;
+}
+
+static uint8_t
+parse_and_check_key_hexa_digit(char *key, int idx)
+{
+	uint8_t hexa_v;
+
+	hexa_v = hexa_digit_to_value(key[idx]);
+	if (hexa_v == 0xFF)
+		printf("invalid key: character %c at position %d is not a "
+		       "valid hexa digit\n", key[idx], idx);
+	return hexa_v;
+}
+
+static void
+cmd_config_rss_hash_key_parsed(void *parsed_result,
+			       __attribute__((unused)) struct cmdline *cl,
+			       __attribute__((unused)) void *data)
+{
+	struct cmd_config_rss_hash_key *res = parsed_result;
+	uint8_t hash_key[RSS_HASH_KEY_LENGTH];
+	uint8_t xdgt0;
+	uint8_t xdgt1;
+	int i;
+
+	/* Check the length of the RSS hash key */
+	if (strlen(res->key) != (RSS_HASH_KEY_LENGTH * 2)) {
+		printf("key length: %d invalid - key must be a string of %d"
+		       "hexa-decimal numbers\n", (int) strlen(res->key),
+		       RSS_HASH_KEY_LENGTH * 2);
+		return;
+	}
+	/* Translate RSS hash key into binary representation */
+	for (i = 0; i < RSS_HASH_KEY_LENGTH; i++) {
+		xdgt0 = parse_and_check_key_hexa_digit(res->key, (i * 2));
+		if (xdgt0 == 0xFF)
+			return;
+		xdgt1 = parse_and_check_key_hexa_digit(res->key, (i * 2) + 1);
+		if (xdgt1 == 0xFF)
+			return;
+		hash_key[i]= (uint8_t) ((xdgt0 * 16) + xdgt1);
+	}
+	port_rss_hash_key_update(res->port_id, hash_key);
+}
+
+cmdline_parse_token_string_t cmd_config_rss_hash_key_port =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, port, "port");
+cmdline_parse_token_string_t cmd_config_rss_hash_key_config =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, config,
+				 "config");
+cmdline_parse_token_string_t cmd_config_rss_hash_key_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_config_rss_hash_key, port_id, UINT8);
+cmdline_parse_token_string_t cmd_config_rss_hash_key_rss_hash_key =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key,
+				 rss_hash_key, "rss-hash-key");
+cmdline_parse_token_string_t cmd_config_rss_hash_key_value =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, key, NULL);
+
+cmdline_parse_inst_t cmd_config_rss_hash_key = {
+	.f = cmd_config_rss_hash_key_parsed,
+	.data = NULL,
+	.help_str = "port config X rss-hash-key 80 hexa digits",
+	.tokens = {
+		(void *)&cmd_config_rss_hash_key_port,
+		(void *)&cmd_config_rss_hash_key_config,
+		(void *)&cmd_config_rss_hash_key_port_id,
+		(void *)&cmd_config_rss_hash_key_rss_hash_key,
+		(void *)&cmd_config_rss_hash_key_value,
+		NULL,
+	},
+};
+
 /* *** Configure RSS RETA *** */
 struct cmd_config_rss_reta {
 	cmdline_fixed_string_t port;
@@ -1413,7 +1506,7 @@ cmdline_parse_inst_t cmd_showport_rss_hash = {
 
 cmdline_parse_inst_t cmd_showport_rss_hash_key = {
 	.f = cmd_showport_rss_hash_parsed,
-	.data = "show_rss_key",
+	.data = (void *)1,
 	.help_str = "show port X rss-hash key (X = port number)\n",
 	.tokens = {
 		(void *)&cmd_showport_rss_hash_show,
@@ -5322,6 +5415,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_reset_mirror_rule,
 	(cmdline_parse_inst_t *)&cmd_showport_rss_hash,
 	(cmdline_parse_inst_t *)&cmd_showport_rss_hash_key,
+	(cmdline_parse_inst_t *)&cmd_config_rss_hash_key,
 	(cmdline_parse_inst_t *)&cmd_dump,
 	(cmdline_parse_inst_t *)&cmd_dump_one,
 	NULL,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 614f28f..6feda7a 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -746,6 +746,34 @@ port_rss_hash_conf_show(portid_t port_id, int show_rss_key)
 	printf("\n");
 }
 
+void
+port_rss_hash_key_update(portid_t port_id, uint8_t *hash_key)
+{
+	struct rte_eth_rss_conf rss_conf;
+	int diag;
+
+	rss_conf.rss_key = NULL;
+	diag = rte_eth_dev_rss_hash_conf_get(port_id, &rss_conf);
+	if (diag == 0) {
+		rss_conf.rss_key = hash_key;
+		diag = rte_eth_dev_rss_hash_update(port_id, &rss_conf);
+	}
+	if (diag == 0)
+		return;
+
+	switch (diag) {
+	case -ENODEV:
+		printf("port index %d invalid\n", port_id);
+		break;
+	case -ENOTSUP:
+		printf("operation not supported by device\n");
+		break;
+	default:
+		printf("operation failed - diag=%d\n", diag);
+		break;
+	}
+}
+
 /*
  * Setup forwarding configuration for each logical core.
  */
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index b9d47c4..66c7736 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -524,6 +524,7 @@ void set_vf_rx_vlan(portid_t port_id, uint16_t vlan_id,
 		uint64_t vf_mask, uint8_t on);
 
 void port_rss_hash_conf_show(portid_t port_id, int show_rss_key);
+void port_rss_hash_key_update(portid_t port_id, uint8_t *hash_key);
 
 /*
  * Work-around of a compilation error with ICC on invocations of the
-- 
1.7.10.4



More information about the dev mailing list