[dpdk-dev,11/15] testpmd: add and update commands for flow director

Message ID 1422509365-13596-12-git-send-email-jingjing.wu@intel.com (mailing list archive)
State Accepted, archived
Headers

Commit Message

Jingjing Wu Jan. 29, 2015, 5:29 a.m. UTC
Add new command to set flow director's mask:
  - flow_director_mask
Update arguments of commands:
  - flow_director_filter
  - flow_director_flex_mask
  - flow_director_flex_payload

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c | 182 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 164 insertions(+), 18 deletions(-)
  

Patch

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 4beb404..3671d25 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -701,25 +701,26 @@  static void cmd_help_long_parsed(void *parsed_result,
 			"get_flex_filter (port_id) index (idx)\n"
 			"    get info of a flex filter.\n\n"
 
-			"flow_director_filter (port_id) (add|del)"
+			"flow_director_filter (port_id) (add|del|update)"
 			" flow (ip4|ip4-frag|ip6|ip6-frag)"
 			" src (src_ip_address) dst (dst_ip_address)"
-			" flexbytes (flexbytes_value)"
+			" vlan (vlan_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) queue (queue_id) fd_id (fd_id_value)\n"
 			"    Add/Del an IP type flow director filter.\n\n"
 
-			"flow_director_filter (port_id) (add|del)"
+			"flow_director_filter (port_id) (add|del|update)"
 			" flow (udp4|tcp4|udp6|tcp6)"
 			" src (src_ip_address) (src_port)"
 			" dst (dst_ip_address) (dst_port)"
-			" flexbytes (flexbytes_value)"
+			" vlan (vlan_value) flexbytes (flexbytes_value)"
 			" (drop|fwd) queue (queue_id) fd_id (fd_id_value)\n"
 			"    Add/Del an UDP/TCP type flow director filter.\n\n"
 
-			"flow_director_filter (port_id) (add|del)"
+			"flow_director_filter (port_id) (add|del|update)"
 			" flow (sctp4|sctp6)"
-			" src (src_ip_address) dst (dst_ip_address)"
-			" tag (verification_tag)"
+			" src (src_ip_address) (src_port)"
+			" dst (dst_ip_address) (dst_port)"
+			" tag (verification_tag) vlan (vlan_value)"
 			" flexbytes (flexbytes_value) (drop|fwd)"
 			" queue (queue_id) fd_id (fd_id_value)\n"
 			"    Add/Del a SCTP type flow director filter.\n\n"
@@ -727,13 +728,18 @@  static void cmd_help_long_parsed(void *parsed_result,
 			"flush_flow_director (port_id)\n"
 			"    Flush all flow director entries of a device.\n\n"
 
+			"flow_director_mask (port_id) vlan (vlan_value)"
+			" src_mask (ipv4_src) (ipv6_src) (src_port)"
+			" dst_mask (ipv4_dst) (ipv6_dst) (dst_port)\n"
+			"    Set flow director mask.\n\n"
+
 			"flow_director_flex_mask (port_id)"
-			" flow (ip4|ip4-frag|tcp4|udp4|sctp4|ip6|ip6-frag|tcp6|udp6|sctp6|all)"
+			" flow (raw|ip4|ip4-frag|tcp4|udp4|sctp4|ip6|ip6-frag|tcp6|udp6|sctp6|all)"
 			" (mask)\n"
 			"    Configure mask of flex payload.\n\n"
 
 			"flow_director_flex_payload (port_id)"
-			" (l2|l3|l4) (config)\n"
+			" (raw|l2|l3|l4) (config)\n"
 			"    Configure flex payload selection.\n\n"
 		);
 	}
@@ -8084,6 +8090,8 @@  struct cmd_flow_director_result {
 	uint16_t port_dst;
 	cmdline_fixed_string_t verify_tag;
 	uint32_t verify_tag_value;
+	cmdline_fixed_string_t vlan;
+	uint16_t vlan_value;
 	cmdline_fixed_string_t flexbytes;
 	cmdline_fixed_string_t flexbytes_value;
 	cmdline_fixed_string_t drop;
@@ -8139,6 +8147,7 @@  str2flowtype(char *string)
 		char str[32];
 		enum rte_eth_flow_type type;
 	} flowtype_str[] = {
+		{"raw", RTE_ETH_FLOW_TYPE_RAW},
 		{"ip4", RTE_ETH_FLOW_TYPE_IPV4_OTHER},
 		{"ip4-frag", RTE_ETH_FLOW_TYPE_FRAG_IPV4},
 		{"udp4", RTE_ETH_FLOW_TYPE_UDPV4},
@@ -8209,6 +8218,7 @@  cmd_flow_director_filter_parsed(void *parsed_result,
 	entry.input.flow_type = str2flowtype(res->flow_type);
 	switch (entry.input.flow_type) {
 	case RTE_ETH_FLOW_TYPE_IPV4_OTHER:
+	case RTE_ETH_FLOW_TYPE_FRAG_IPV4:
 	case RTE_ETH_FLOW_TYPE_UDPV4:
 	case RTE_ETH_FLOW_TYPE_TCPV4:
 		IPV4_ADDR_TO_UINT(res->ip_dst,
@@ -8231,6 +8241,7 @@  cmd_flow_director_filter_parsed(void *parsed_result,
 				rte_cpu_to_be_32(res->verify_tag_value);
 		break;
 	case RTE_ETH_FLOW_TYPE_IPV6_OTHER:
+	case RTE_ETH_FLOW_TYPE_FRAG_IPV6:
 	case RTE_ETH_FLOW_TYPE_UDPV6:
 	case RTE_ETH_FLOW_TYPE_TCPV6:
 		IPV6_ADDR_TO_ARRAY(res->ip_dst,
@@ -8260,6 +8271,8 @@  cmd_flow_director_filter_parsed(void *parsed_result,
 		   flexbytes,
 		   RTE_ETH_FDIR_MAX_FLEXLEN);
 
+	entry.input.flow_ext.vlan_tci = rte_cpu_to_be_16(res->vlan_value);
+
 	entry.action.flex_off = 0;  /*use 0 by default */
 	if (!strcmp(res->drop, "drop"))
 		entry.action.behavior = RTE_ETH_FDIR_REJECT;
@@ -8272,9 +8285,12 @@  cmd_flow_director_filter_parsed(void *parsed_result,
 	if (!strcmp(res->ops, "add"))
 		ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
 					     RTE_ETH_FILTER_ADD, &entry);
-	else
+	else if (!strcmp(res->ops, "del"))
 		ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
 					     RTE_ETH_FILTER_DELETE, &entry);
+	else
+		ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
+					     RTE_ETH_FILTER_UPDATE, &entry);
 	if (ret < 0)
 		printf("flow director programming error: (%s)\n",
 			strerror(-ret));
@@ -8288,7 +8304,7 @@  cmdline_parse_token_num_t cmd_flow_director_port_id =
 			      port_id, UINT8);
 cmdline_parse_token_string_t cmd_flow_director_ops =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
-				 ops, "add#del");
+				 ops, "add#del#update");
 cmdline_parse_token_string_t cmd_flow_director_flow =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
 				 flow, "flow");
@@ -8321,6 +8337,12 @@  cmdline_parse_token_string_t cmd_flow_director_verify_tag =
 cmdline_parse_token_num_t cmd_flow_director_verify_tag_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
 			      verify_tag_value, UINT32);
+cmdline_parse_token_string_t cmd_flow_director_vlan =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+				 vlan, "vlan");
+cmdline_parse_token_num_t cmd_flow_director_vlan_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+			      vlan_value, UINT16);
 cmdline_parse_token_string_t cmd_flow_director_flexbytes =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
 				 flexbytes, "flexbytes");
@@ -8357,6 +8379,8 @@  cmdline_parse_inst_t cmd_add_del_ip_flow_director = {
 		(void *)&cmd_flow_director_ip_src,
 		(void *)&cmd_flow_director_dst,
 		(void *)&cmd_flow_director_ip_dst,
+		(void *)&cmd_flow_director_vlan,
+		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
 		(void *)&cmd_flow_director_flexbytes_value,
 		(void *)&cmd_flow_director_drop,
@@ -8384,6 +8408,8 @@  cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
 		(void *)&cmd_flow_director_dst,
 		(void *)&cmd_flow_director_ip_dst,
 		(void *)&cmd_flow_director_port_dst,
+		(void *)&cmd_flow_director_vlan,
+		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
 		(void *)&cmd_flow_director_flexbytes_value,
 		(void *)&cmd_flow_director_drop,
@@ -8407,10 +8433,14 @@  cmdline_parse_inst_t cmd_add_del_sctp_flow_director = {
 		(void *)&cmd_flow_director_flow_type,
 		(void *)&cmd_flow_director_src,
 		(void *)&cmd_flow_director_ip_src,
+		(void *)&cmd_flow_director_port_dst,
 		(void *)&cmd_flow_director_dst,
 		(void *)&cmd_flow_director_ip_dst,
+		(void *)&cmd_flow_director_port_dst,
 		(void *)&cmd_flow_director_verify_tag,
 		(void *)&cmd_flow_director_verify_tag_value,
+		(void *)&cmd_flow_director_vlan,
+		(void *)&cmd_flow_director_vlan_value,
 		(void *)&cmd_flow_director_flexbytes,
 		(void *)&cmd_flow_director_flexbytes_value,
 		(void *)&cmd_flow_director_drop,
@@ -8467,6 +8497,112 @@  cmdline_parse_inst_t cmd_flush_flow_director = {
 	},
 };
 
+/* *** deal with flow director mask *** */
+struct cmd_flow_director_mask_result {
+	cmdline_fixed_string_t flow_director_mask;
+	uint8_t port_id;
+	cmdline_fixed_string_t vlan;
+	uint16_t vlan_value;
+	cmdline_fixed_string_t src_mask;
+	cmdline_ipaddr_t ipv4_src;
+	cmdline_ipaddr_t ipv6_src;
+	uint16_t port_src;
+	cmdline_fixed_string_t dst_mask;
+	cmdline_ipaddr_t ipv4_dst;
+	cmdline_ipaddr_t ipv6_dst;
+	uint16_t port_dst;
+};
+
+static void
+cmd_flow_director_mask_parsed(void *parsed_result,
+			  __attribute__((unused)) struct cmdline *cl,
+			  __attribute__((unused)) void *data)
+{
+	struct cmd_flow_director_mask_result *res = parsed_result;
+	struct rte_eth_fdir_masks *mask;
+	struct rte_port *port;
+
+	if (res->port_id > nb_ports) {
+		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+		return;
+	}
+
+	port = &ports[res->port_id];
+	/** Check if the port is not started **/
+	if (port->port_status != RTE_PORT_STOPPED) {
+		printf("Please stop port %d first\n", res->port_id);
+		return;
+	}
+	mask = &port->dev_conf.fdir_conf.mask;
+
+	mask->vlan_tci_mask = res->vlan_value;
+	IPV4_ADDR_TO_UINT(res->ipv4_src, mask->ipv4_mask.src_ip);
+	IPV4_ADDR_TO_UINT(res->ipv4_dst, mask->ipv4_mask.dst_ip);
+	IPV6_ADDR_TO_ARRAY(res->ipv6_src, mask->ipv6_mask.src_ip);
+	IPV6_ADDR_TO_ARRAY(res->ipv6_dst, mask->ipv6_mask.dst_ip);
+	mask->src_port_mask = res->port_src;
+	mask->dst_port_mask = res->port_dst;
+
+	cmd_reconfig_device_queue(res->port_id, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_flow_director_mask =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
+				 flow_director_mask, "flow_director_mask");
+cmdline_parse_token_num_t cmd_flow_director_mask_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
+			      port_id, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_mask_vlan =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
+				 vlan, "vlan");
+cmdline_parse_token_num_t cmd_flow_director_mask_vlan_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
+			      vlan_value, UINT16);
+cmdline_parse_token_string_t cmd_flow_director_mask_src =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
+				 src_mask, "src_mask");
+cmdline_parse_token_ipaddr_t cmd_flow_director_mask_ipv4_src =
+	TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_mask_result,
+				 ipv4_src);
+cmdline_parse_token_ipaddr_t cmd_flow_director_mask_ipv6_src =
+	TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_mask_result,
+				 ipv6_src);
+cmdline_parse_token_num_t cmd_flow_director_mask_port_src =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
+			      port_src, UINT16);
+cmdline_parse_token_string_t cmd_flow_director_mask_dst =
+	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
+				 dst_mask, "dst_mask");
+cmdline_parse_token_ipaddr_t cmd_flow_director_mask_ipv4_dst =
+	TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_mask_result,
+				 ipv4_dst);
+cmdline_parse_token_ipaddr_t cmd_flow_director_mask_ipv6_dst =
+	TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_mask_result,
+				 ipv6_dst);
+cmdline_parse_token_num_t cmd_flow_director_mask_port_dst =
+	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
+			      port_dst, UINT16);
+cmdline_parse_inst_t cmd_set_flow_director_mask = {
+	.f = cmd_flow_director_mask_parsed,
+	.data = NULL,
+	.help_str = "set flow director's mask on NIC",
+	.tokens = {
+		(void *)&cmd_flow_director_mask,
+		(void *)&cmd_flow_director_mask_port_id,
+		(void *)&cmd_flow_director_mask_vlan,
+		(void *)&cmd_flow_director_mask_vlan_value,
+		(void *)&cmd_flow_director_mask_src,
+		(void *)&cmd_flow_director_mask_ipv4_src,
+		(void *)&cmd_flow_director_mask_ipv6_src,
+		(void *)&cmd_flow_director_mask_port_src,
+		(void *)&cmd_flow_director_mask_dst,
+		(void *)&cmd_flow_director_mask_ipv4_dst,
+		(void *)&cmd_flow_director_mask_ipv6_dst,
+		(void *)&cmd_flow_director_mask_port_dst,
+		NULL,
+	},
+};
+
 /* *** deal with flow director mask on flexible payload *** */
 struct cmd_flow_director_flex_mask_result {
 	cmdline_fixed_string_t flow_director_flexmask;
@@ -8482,6 +8618,7 @@  cmd_flow_director_flex_mask_parsed(void *parsed_result,
 			  __attribute__((unused)) void *data)
 {
 	struct cmd_flow_director_flex_mask_result *res = parsed_result;
+	struct rte_eth_fdir_info fdir_info;
 	struct rte_eth_fdir_flex_mask flex_mask;
 	struct rte_port *port;
 	enum rte_eth_flow_type i;
@@ -8507,14 +8644,20 @@  cmd_flow_director_flex_mask_parsed(void *parsed_result,
 		printf("error: Cannot parse mask input.\n");
 		return;
 	}
+
 	if (!strcmp(res->flow_type, "all")) {
-		for (i = RTE_ETH_FLOW_TYPE_UDPV4;
+		memset(&fdir_info, 0, sizeof(fdir_info));
+		rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
+				       RTE_ETH_FILTER_INFO, &fdir_info);
+		for (i = RTE_ETH_FLOW_TYPE_RAW;
 		     i <= RTE_ETH_FLOW_TYPE_FRAG_IPV6;
 		     i++) {
-			flex_mask.flow_type = i;
-			fdir_set_flex_mask(res->port_id, &flex_mask);
+			if (fdir_info.flow_types_mask[0] & (1 << i)) {
+				flex_mask.flow_type = i;
+				fdir_set_flex_mask(res->port_id, &flex_mask);
+			}
 		}
-		cmd_reconfig_device_queue(res->port_id, 1, 0);
+		cmd_reconfig_device_queue(res->port_id, 1, 1);
 		return;
 	}
 	flex_mask.flow_type = str2flowtype(res->flow_type);
@@ -8535,7 +8678,7 @@  cmdline_parse_token_string_t cmd_flow_director_flexmask_flow =
 cmdline_parse_token_string_t cmd_flow_director_flexmask_flow_type =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
 				 flow_type,
-				"ip4#ip4-frag#tcp4#udp4#sctp4#"
+				"raw#ip4#ip4-frag#tcp4#udp4#sctp4#"
 				"ip6#ip6-frag#tcp6#udp6#sctp6#all");
 cmdline_parse_token_string_t cmd_flow_director_flexmask_mask =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
@@ -8625,7 +8768,9 @@  cmd_flow_director_flxpld_parsed(void *parsed_result,
 
 	memset(&flex_cfg, 0, sizeof(struct rte_eth_flex_payload_cfg));
 
-	if (!strcmp(res->payload_layer, "l2"))
+	if (!strcmp(res->payload_layer, "raw"))
+		flex_cfg.type = RTE_ETH_RAW_PAYLOAD;
+	else if (!strcmp(res->payload_layer, "l2"))
 		flex_cfg.type = RTE_ETH_L2_PAYLOAD;
 	else if (!strcmp(res->payload_layer, "l3"))
 		flex_cfg.type = RTE_ETH_L3_PAYLOAD;
@@ -8652,7 +8797,7 @@  cmdline_parse_token_num_t cmd_flow_director_flexpayload_port_id =
 			      port_id, UINT8);
 cmdline_parse_token_string_t cmd_flow_director_flexpayload_payload_layer =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flexpayload_result,
-				 payload_layer, "l2#l3#l4");
+				 payload_layer, "raw#l2#l3#l4");
 cmdline_parse_token_string_t cmd_flow_director_flexpayload_payload_cfg =
 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flexpayload_result,
 				 payload_cfg, NULL);
@@ -8805,6 +8950,7 @@  cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_add_del_udp_flow_director,
 	(cmdline_parse_inst_t *)&cmd_add_del_sctp_flow_director,
 	(cmdline_parse_inst_t *)&cmd_flush_flow_director,
+	(cmdline_parse_inst_t *)&cmd_set_flow_director_mask,
 	(cmdline_parse_inst_t *)&cmd_set_flow_director_flex_mask,
 	(cmdline_parse_inst_t *)&cmd_set_flow_director_flex_payload,
 	NULL,