DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v1 1/3] librte_pipeline: add support for DSCP action
@ 2019-02-12  9:31 Sheehan,Georgina
  2019-02-12  9:31 ` [dpdk-dev] [PATCH v1 2/3] pipeline: add implementation " Sheehan,Georgina
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Sheehan,Georgina @ 2019-02-12  9:31 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu, Georgina Sheehan

From: Georgina Sheehan <georgina.sheehan@intel.com>

This allows the application to change the DSCP value of incoming packets

Signed-off-by: Georgina Sheehan <georgina.sheehan@intel.com>
---
 lib/librte_pipeline/rte_table_action.c | 133 +++++++++++++++++++++++++
 lib/librte_pipeline/rte_table_action.h |  20 ++++
 2 files changed, 153 insertions(+)

diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c
index 8a2bb13dc..8f11a17e6 100644
--- a/lib/librte_pipeline/rte_table_action.c
+++ b/lib/librte_pipeline/rte_table_action.c
@@ -2119,6 +2119,87 @@ pkt4_work_decap(struct rte_mbuf *mbuf0,
 	mbuf3->pkt_len = pkt_len3 - n3;
 }
 
+/**
+ * RTE_TABLE_ACTION_DSCP
+ */
+
+struct dscp_data {
+	uint8_t dscp_val;
+} __attribute__((__packed__));
+
+static int
+dscp_apply(void *data,
+	struct rte_table_action_dscp_params *p)
+{
+	struct dscp_data *d = data;
+
+	d->dscp_val = (p->dscp_val & 0x3f) << 2;
+
+	return 0;
+}
+
+static __rte_always_inline uint16_t
+dscp_ipv4_checksum_update(uint16_t cksum0,
+	uint8_t dscp_old,
+	uint8_t dscp_new)
+{
+	int32_t cksum1;
+	cksum1 = cksum0;
+	cksum1 = ~cksum1 & 0xFFFF;
+
+	/* Subtract ip0 (one's complement logic) */
+	cksum1 -= ((uint16_t)dscp_old & 0xFFFF);
+	cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
+	cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
+
+	/* Add ip1 (one's complement logic) */
+	cksum1 += ((uint16_t)dscp_new & 0xFFFF);
+	cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
+	cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
+
+	return (uint16_t)(~cksum1);
+}
+
+static __rte_always_inline void
+pkt_ipv4_work_dscp(struct ipv4_hdr *ip, struct dscp_data *data)
+{
+	uint16_t ip_cksum;
+	uint8_t dscp;
+
+	ip->hdr_checksum = ntohs(ip->hdr_checksum);
+
+	dscp = ip->type_of_service & 0x3;
+	dscp = ip->type_of_service | data->dscp_val;
+
+	ip_cksum = dscp_ipv4_checksum_update(ip->hdr_checksum,
+		ip->type_of_service, dscp);
+
+	ip->type_of_service = dscp;
+
+	ip_cksum = ntohs(ip_cksum);
+
+	ip->hdr_checksum = ip_cksum;
+}
+
+static __rte_always_inline void
+pkt_ipv6_work_dscp(struct ipv6_hdr *ip, struct dscp_data *data)
+{
+	ip->vtc_flow = rte_ntohl(ip->vtc_flow);
+
+	uint32_t dscp = data->dscp_val;
+
+	dscp = dscp << 20;
+
+	uint32_t vtc_flow;
+
+	vtc_flow = ip->vtc_flow & 0xF03FFFFF;
+	vtc_flow = ip->vtc_flow | dscp;
+
+	vtc_flow = rte_htonl(vtc_flow);
+
+	ip->vtc_flow = vtc_flow;
+}
+
 /**
  * Action profile
  */
@@ -2138,6 +2219,7 @@ action_valid(enum rte_table_action_type action)
 	case RTE_TABLE_ACTION_SYM_CRYPTO:
 	case RTE_TABLE_ACTION_TAG:
 	case RTE_TABLE_ACTION_DECAP:
+	case RTE_TABLE_ACTION_DSCP:
 		return 1;
 	default:
 		return 0;
@@ -2158,6 +2240,7 @@ struct ap_config {
 	struct rte_table_action_ttl_config ttl;
 	struct rte_table_action_stats_config stats;
 	struct rte_table_action_sym_crypto_config sym_crypto;
+	struct rte_table_action_dscp_config dscp;
 };
 
 static size_t
@@ -2180,6 +2263,8 @@ action_cfg_size(enum rte_table_action_type action)
 		return sizeof(struct rte_table_action_stats_config);
 	case RTE_TABLE_ACTION_SYM_CRYPTO:
 		return sizeof(struct rte_table_action_sym_crypto_config);
+	case RTE_TABLE_ACTION_DSCP:
+		return sizeof(struct rte_table_action_dscp_config);
 	default:
 		return 0;
 	}
@@ -2213,6 +2298,9 @@ action_cfg_get(struct ap_config *ap_config,
 
 	case RTE_TABLE_ACTION_SYM_CRYPTO:
 		return &ap_config->sym_crypto;
+
+	case RTE_TABLE_ACTION_DSCP:
+		return &ap_config->dscp;
 	default:
 		return NULL;
 	}
@@ -2278,6 +2366,9 @@ action_data_size(enum rte_table_action_type action,
 	case RTE_TABLE_ACTION_DECAP:
 		return sizeof(struct decap_data);
 
+	case RTE_TABLE_ACTION_DSCP:
+		return sizeof(struct dscp_data);
+
 	default:
 		return 0;
 	}
@@ -2543,6 +2634,10 @@ rte_table_action_apply(struct rte_table_action *action,
 		return decap_apply(action_data,
 			action_params);
 
+	case RTE_TABLE_ACTION_DSCP:
+		return dscp_apply(action_data,
+			action_params);
+
 	default:
 		return -EINVAL;
 	}
@@ -2939,6 +3034,17 @@ pkt_work(struct rte_mbuf *mbuf,
 		pkt_work_tag(mbuf, data);
 	}
 
+	if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DSCP)) {
+		void *data =
+			action_data_get(table_entry, action,
+				RTE_TABLE_ACTION_DSCP);
+
+		if (cfg->common.ip_version)
+			pkt_ipv4_work_dscp(ip, data);
+		else
+			pkt_ipv6_work_dscp(ip, data);
+	}
+
 	return drop_mask;
 }
 
@@ -3283,6 +3389,33 @@ pkt4_work(struct rte_mbuf **mbufs,
 			data0, data1, data2, data3);
 	}
 
+	if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DSCP)) {
+		void *data0 =
+			action_data_get(table_entry0, action,
+				RTE_TABLE_ACTION_DSCP);
+		void *data1 =
+			action_data_get(table_entry1, action,
+				RTE_TABLE_ACTION_DSCP);
+		void *data2 =
+			action_data_get(table_entry2, action,
+				RTE_TABLE_ACTION_DSCP);
+		void *data3 =
+			action_data_get(table_entry3, action,
+				RTE_TABLE_ACTION_DSCP);
+
+		if (cfg->common.ip_version) {
+			pkt_ipv4_work_dscp(ip0, data0);
+			pkt_ipv4_work_dscp(ip1, data1);
+			pkt_ipv4_work_dscp(ip2, data2);
+			pkt_ipv4_work_dscp(ip3, data3);
+		} else {
+			pkt_ipv6_work_dscp(ip0, data0);
+			pkt_ipv6_work_dscp(ip1, data1);
+			pkt_ipv6_work_dscp(ip2, data2);
+			pkt_ipv6_work_dscp(ip3, data3);
+		}
+	}
+
 	return drop_mask0 |
 		(drop_mask1 << 1) |
 		(drop_mask2 << 2) |
diff --git a/lib/librte_pipeline/rte_table_action.h b/lib/librte_pipeline/rte_table_action.h
index c96061291..28db53303 100644
--- a/lib/librte_pipeline/rte_table_action.h
+++ b/lib/librte_pipeline/rte_table_action.h
@@ -102,6 +102,9 @@ enum rte_table_action_type {
 
 	/** Packet decapsulations. */
 	RTE_TABLE_ACTION_DECAP,
+
+	/** Differentiated Services Code Point (DSCP) **/
+	RTE_TABLE_ACTION_DSCP,
 };
 
 /** Common action configuration (per table action profile). */
@@ -794,6 +797,23 @@ struct rte_table_action_decap_params {
 	uint16_t n;
 };
 
+/**
+ * RTE_TABLE_ACTION_DSCP
+ */
+/** DSCP action configuration (per table action profile). */
+struct rte_table_action_dscp_config {
+	/** dscp length  */
+	uint8_t dscp_len;
+
+};
+
+/** DSCP action parameters (per table rule). */
+struct rte_table_action_dscp_params {
+	/** dscp value to be set */
+	uint8_t dscp_val;
+
+};
+
 /**
  * Table action profile.
  */
-- 
2.17.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [dpdk-dev] [PATCH v1 2/3] pipeline: add implementation for DSCP action
  2019-02-12  9:31 [dpdk-dev] [PATCH v1 1/3] librte_pipeline: add support for DSCP action Sheehan,Georgina
@ 2019-02-12  9:31 ` Sheehan,Georgina
  2019-02-12  9:31 ` [dpdk-dev] [PATCH v1 3/3] net/softnic: add support " Sheehan,Georgina
  2019-02-12 14:03 ` [dpdk-dev] [PATCH v2 1/3] librte_pipeline: " Sheehan,Georgina
  2 siblings, 0 replies; 8+ messages in thread
From: Sheehan,Georgina @ 2019-02-12  9:31 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu, Georgina Sheehan

From: Georgina Sheehan <georgina.sheehan@intel.com>

This allows the application to change the DSCP value of incoming packets

Signed-off-by: Georgina Sheehan <georgina.sheehan@intel.com>
---
 examples/ip_pipeline/action.c   | 11 +++++++
 examples/ip_pipeline/action.h   |  1 +
 examples/ip_pipeline/cli.c      | 52 ++++++++++++++++++++++++++++++++-
 examples/ip_pipeline/pipeline.h |  1 +
 examples/ip_pipeline/thread.c   | 10 +++++++
 5 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/examples/ip_pipeline/action.c b/examples/ip_pipeline/action.c
index d2104aad6..625c870a2 100644
--- a/examples/ip_pipeline/action.c
+++ b/examples/ip_pipeline/action.c
@@ -366,6 +366,17 @@ table_action_profile_create(const char *name,
 		}
 	}
 
+	if (params->action_mask & (1LLU << RTE_TABLE_ACTION_DSCP)) {
+		status = rte_table_action_profile_action_register(ap,
+				RTE_TABLE_ACTION_DSCP,
+				&params->dscp);
+
+		if (status) {
+			rte_table_action_profile_free(ap);
+			return NULL;
+		}
+	}
+
 	status = rte_table_action_profile_freeze(ap);
 	if (status) {
 		rte_table_action_profile_free(ap);
diff --git a/examples/ip_pipeline/action.h b/examples/ip_pipeline/action.h
index cde17e69a..ea8f81c56 100644
--- a/examples/ip_pipeline/action.h
+++ b/examples/ip_pipeline/action.h
@@ -54,6 +54,7 @@ struct table_action_profile_params {
 	struct rte_table_action_ttl_config ttl;
 	struct rte_table_action_stats_config stats;
 	struct rte_table_action_sym_crypto_config sym_crypto;
+	struct rte_table_action_dscp_config dscp;
 };
 
 struct table_action_profile {
diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
index a92467e63..ca3083a48 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -1045,7 +1045,8 @@ static const char cmd_table_action_profile_help[] =
 "   [time]\n"
 "   [sym_crypto dev <CRYPTODEV_NAME> offset <op_offset>]\n"
 "   [tag]\n"
-"   [decap]\n";
+"   [decap]\n"
+"   [dscp]\n";
 
 static void
 cmd_table_action_profile(char **tokens,
@@ -1458,6 +1459,17 @@ cmd_table_action_profile(char **tokens,
 		t0 += 1;
 	} /* decap */
 
+	if ((t0 < n_tokens) && (strcmp(tokens[t0], "dscp") == 0)) {
+		if (n_tokens < t0 + 1) {
+			snprintf(out, out_size, MSG_ARG_MISMATCH,
+				"table action profile dscp");
+			return;
+		}
+
+		p.action_mask |= 1LLU << RTE_TABLE_ACTION_DSCP;
+		t0 += 1;
+	} /** DSCP **/
+
 	if (t0 < n_tokens) {
 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
 		return;
@@ -3116,6 +3128,7 @@ parse_match(char **tokens,
  *       data_offset <data_offset>]
  *    [tag <tag>]
  *    [decap <n>]
+ *    [dscp <n>]
  *
  * where:
  *    <pa> ::= g | y | r | drop
@@ -4108,6 +4121,26 @@ parse_table_action_decap(char **tokens,
 	return 2;
 }
 
+static uint32_t
+parse_table_action_dscp(char **tokens,
+		uint32_t n_tokens,
+		struct table_rule_action *a)
+{
+	if ((n_tokens < 2) ||
+		strcmp(tokens[0], "dscp"))
+		return 0;
+
+	uint8_t dscp_val;
+
+	if (parser_read_uint8(&dscp_val, tokens[1]))
+		return 0;
+
+	a->dscp.dscp_val = dscp_val;
+
+	a->action_mask |= 1 << RTE_TABLE_ACTION_DSCP;
+	return 2;
+}
+
 static uint32_t
 parse_table_action(char **tokens,
 	uint32_t n_tokens,
@@ -4293,6 +4326,20 @@ parse_table_action(char **tokens,
 		n_tokens -= n;
 	}
 
+	if (n_tokens && (strcmp(tokens[0], "dscp") == 0)) {
+		uint32_t n;
+
+		n = parse_table_action_dscp(tokens, n_tokens, a);
+		if (n == 0) {
+			snprintf(out, out_size, MSG_ARG_INVALID,
+				"action dscp");
+			return 0;
+		}
+
+		tokens += n;
+		n_tokens -= n;
+	}
+
 	if (n_tokens0 - n_tokens == 1) {
 		snprintf(out, out_size, MSG_ARG_INVALID, "action");
 		return 0;
@@ -5056,6 +5103,9 @@ table_rule_show(const char *pipeline_name,
 		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP))
 			fprintf(f, "decap %u ", a->decap.n);
 
+		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_DSCP))
+			fprintf(f, "dscp ");
+
 		/* end */
 		fprintf(f, "\n");
 	}
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index 278775c2d..670174ed4 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -290,6 +290,7 @@ struct table_rule_action {
 	struct rte_table_action_sym_crypto_params sym_crypto;
 	struct rte_table_action_tag_params tag;
 	struct rte_table_action_decap_params decap;
+	struct rte_table_action_dscp_params dscp;
 };
 
 struct table_rule {
diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
index 272fbbeed..c9facb53e 100644
--- a/examples/ip_pipeline/thread.c
+++ b/examples/ip_pipeline/thread.c
@@ -2751,6 +2751,16 @@ action_convert(struct rte_table_action *a,
 			return status;
 	}
 
+	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_DSCP)) {
+		status = rte_table_action_apply(a,
+			data,
+			RTE_TABLE_ACTION_DSCP,
+			&action->dscp);
+
+		if (status)
+			return status;
+	}
+
 	return 0;
 }
 
-- 
2.17.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [dpdk-dev] [PATCH v1 3/3] net/softnic: add support for DSCP action
  2019-02-12  9:31 [dpdk-dev] [PATCH v1 1/3] librte_pipeline: add support for DSCP action Sheehan,Georgina
  2019-02-12  9:31 ` [dpdk-dev] [PATCH v1 2/3] pipeline: add implementation " Sheehan,Georgina
@ 2019-02-12  9:31 ` Sheehan,Georgina
  2019-02-12 14:03 ` [dpdk-dev] [PATCH v2 1/3] librte_pipeline: " Sheehan,Georgina
  2 siblings, 0 replies; 8+ messages in thread
From: Sheehan,Georgina @ 2019-02-12  9:31 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu, Georgina Sheehan

From: Georgina Sheehan <georgina.sheehan@intel.com>

This allows the application to change the DSCP value of incoming packets

Signed-off-by: Georgina Sheehan <georgina.sheehan@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_action.c  | 14 ++++++++
 drivers/net/softnic/rte_eth_softnic_cli.c     | 34 +++++++++++++++++++
 .../net/softnic/rte_eth_softnic_internals.h   |  2 ++
 drivers/net/softnic/rte_eth_softnic_thread.c  | 10 ++++++
 4 files changed, 60 insertions(+)

diff --git a/drivers/net/softnic/rte_eth_softnic_action.c b/drivers/net/softnic/rte_eth_softnic_action.c
index 92c744dc9..98d03d5ef 100644
--- a/drivers/net/softnic/rte_eth_softnic_action.c
+++ b/drivers/net/softnic/rte_eth_softnic_action.c
@@ -397,12 +397,26 @@ softnic_table_action_profile_create(struct pmd_internals *p,
 		}
 	}
 
+	if (params->action_mask & (1LLU << RTE_TABLE_ACTION_DSCP)) {
+		status = rte_table_action_profile_action_register(ap,
+			RTE_TABLE_ACTION_DSCP,
+			&params->dscp);
+
+		if (status) {
+			rte_table_action_profile_free(ap);
+			return NULL;
+		}
+	}
+
+
 	status = rte_table_action_profile_freeze(ap);
 	if (status) {
 		rte_table_action_profile_free(ap);
 		return NULL;
 	}
 
+
+
 	/* Node allocation */
 	profile = calloc(1, sizeof(struct softnic_table_action_profile));
 	if (profile == NULL) {
diff --git a/drivers/net/softnic/rte_eth_softnic_cli.c b/drivers/net/softnic/rte_eth_softnic_cli.c
index 76136c2e2..d576cdbfb 100644
--- a/drivers/net/softnic/rte_eth_softnic_cli.c
+++ b/drivers/net/softnic/rte_eth_softnic_cli.c
@@ -1358,6 +1358,7 @@ cmd_port_in_action_profile(struct pmd_internals *softnic,
  *  [time]
  *  [tag]
  *  [decap]
+ *  [dscp]
  *
  */
 static void
@@ -1787,6 +1788,17 @@ cmd_table_action_profile(struct pmd_internals *softnic,
 		t0 += 5;
 	} /* sym_crypto */
 
+	if (t0 < n_tokens && (strcmp(tokens[t0], "dscp") == 0)) {
+		if (n_tokens < t0 + 1) {
+			snprintf(out, out_size, MSG_ARG_MISMATCH,
+				"table action profile dscp");
+			return;
+		}
+
+		p.action_mask |= 1LLU << RTE_TABLE_ACTION_DSCP;
+		t0 += 1;
+	} /** DSCP **/
+
 	if (t0 < n_tokens) {
 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
 		return;
@@ -3432,6 +3444,7 @@ parse_match(char **tokens,
  *          aead_algo <algo> aead_key <key> aead_iv <iv> aead_aad <aad>
  *          digest_size <size>
  *       data_offset <data_offset>]
+ *    [dscp <n>]
  *
  * where:
  *    <pa> ::= g | y | r | drop
@@ -4431,6 +4444,27 @@ parse_table_action_decap(char **tokens,
 	return 2;
 }
 
+static uint32_t
+parse_table_action_dscp(char **tokens,
+		uint32_t n_tokens,
+		struct softnic_table_rule_action *a)
+{
+	if (n_tokens < 2 ||
+		strcmp(tokens[0], "dscp"))
+		return 0;
+
+	uint8_t dscp_val;
+
+	if (softnic_parser_read_uint8(&dscp_val, tokens[1]))
+		return 0;
+
+	a->dscp.dscp_val = dscp_val;
+
+	a->action_mask |= 1 << RTE_TABLE_ACTION_DSCP;
+
+	return 2;
+}
+
 static uint32_t
 parse_table_action(char **tokens,
 	uint32_t n_tokens,
diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 415434d0d..67ba3ecf3 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -333,6 +333,7 @@ struct softnic_table_action_profile_params {
 	struct rte_table_action_ttl_config ttl;
 	struct rte_table_action_stats_config stats;
 	struct rte_table_action_sym_crypto_config sym_crypto;
+	struct rte_table_action_dscp_config dscp;
 };
 
 struct softnic_table_action_profile {
@@ -962,6 +963,7 @@ struct softnic_table_rule_action {
 	struct rte_table_action_tag_params tag;
 	struct rte_table_action_decap_params decap;
 	struct rte_table_action_sym_crypto_params sym_crypto;
+	struct rte_table_action_dscp_params dscp;
 };
 
 struct rte_flow {
diff --git a/drivers/net/softnic/rte_eth_softnic_thread.c b/drivers/net/softnic/rte_eth_softnic_thread.c
index 57989a5aa..e73d4a704 100644
--- a/drivers/net/softnic/rte_eth_softnic_thread.c
+++ b/drivers/net/softnic/rte_eth_softnic_thread.c
@@ -2598,6 +2598,16 @@ action_convert(struct rte_table_action *a,
 			return status;
 	}
 
+	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_DSCP)) {
+		status = rte_table_action_apply(a,
+			data,
+			RTE_TABLE_ACTION_DSCP,
+			&action->dscp);
+
+		if (status)
+			return status;
+	}
+
 	return 0;
 }
 
-- 
2.17.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [dpdk-dev] [PATCH v2 1/3] librte_pipeline: add support for DSCP action
  2019-02-12  9:31 [dpdk-dev] [PATCH v1 1/3] librte_pipeline: add support for DSCP action Sheehan,Georgina
  2019-02-12  9:31 ` [dpdk-dev] [PATCH v1 2/3] pipeline: add implementation " Sheehan,Georgina
  2019-02-12  9:31 ` [dpdk-dev] [PATCH v1 3/3] net/softnic: add support " Sheehan,Georgina
@ 2019-02-12 14:03 ` Sheehan,Georgina
  2019-02-12 14:03   ` [dpdk-dev] [PATCH v2 2/3] pipeline: add implementation " Sheehan,Georgina
                     ` (2 more replies)
  2 siblings, 3 replies; 8+ messages in thread
From: Sheehan,Georgina @ 2019-02-12 14:03 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu, Georgina Sheehan

From: Georgina Sheehan <georgina.sheehan@intel.com>

This allows the application to change the DSCP value of incoming packets

v2: Added in call of function parse_table_action_dscp in softnic cli file

Signed-off-by: Georgina Sheehan <georgina.sheehan@intel.com>
---
 lib/librte_pipeline/rte_table_action.c | 133 +++++++++++++++++++++++++
 lib/librte_pipeline/rte_table_action.h |  20 ++++
 2 files changed, 153 insertions(+)

diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c
index 8a2bb13dc..8f11a17e6 100644
--- a/lib/librte_pipeline/rte_table_action.c
+++ b/lib/librte_pipeline/rte_table_action.c
@@ -2119,6 +2119,87 @@ pkt4_work_decap(struct rte_mbuf *mbuf0,
 	mbuf3->pkt_len = pkt_len3 - n3;
 }
 
+/**
+ * RTE_TABLE_ACTION_DSCP
+ */
+
+struct dscp_data {
+	uint8_t dscp_val;
+} __attribute__((__packed__));
+
+static int
+dscp_apply(void *data,
+	struct rte_table_action_dscp_params *p)
+{
+	struct dscp_data *d = data;
+
+	d->dscp_val = (p->dscp_val & 0x3f) << 2;
+
+	return 0;
+}
+
+static __rte_always_inline uint16_t
+dscp_ipv4_checksum_update(uint16_t cksum0,
+	uint8_t dscp_old,
+	uint8_t dscp_new)
+{
+	int32_t cksum1;
+	cksum1 = cksum0;
+	cksum1 = ~cksum1 & 0xFFFF;
+
+	/* Subtract ip0 (one's complement logic) */
+	cksum1 -= ((uint16_t)dscp_old & 0xFFFF);
+	cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
+	cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
+
+	/* Add ip1 (one's complement logic) */
+	cksum1 += ((uint16_t)dscp_new & 0xFFFF);
+	cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
+	cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
+
+	return (uint16_t)(~cksum1);
+}
+
+static __rte_always_inline void
+pkt_ipv4_work_dscp(struct ipv4_hdr *ip, struct dscp_data *data)
+{
+	uint16_t ip_cksum;
+	uint8_t dscp;
+
+	ip->hdr_checksum = ntohs(ip->hdr_checksum);
+
+	dscp = ip->type_of_service & 0x3;
+	dscp = ip->type_of_service | data->dscp_val;
+
+	ip_cksum = dscp_ipv4_checksum_update(ip->hdr_checksum,
+		ip->type_of_service, dscp);
+
+	ip->type_of_service = dscp;
+
+	ip_cksum = ntohs(ip_cksum);
+
+	ip->hdr_checksum = ip_cksum;
+}
+
+static __rte_always_inline void
+pkt_ipv6_work_dscp(struct ipv6_hdr *ip, struct dscp_data *data)
+{
+	ip->vtc_flow = rte_ntohl(ip->vtc_flow);
+
+	uint32_t dscp = data->dscp_val;
+
+	dscp = dscp << 20;
+
+	uint32_t vtc_flow;
+
+	vtc_flow = ip->vtc_flow & 0xF03FFFFF;
+	vtc_flow = ip->vtc_flow | dscp;
+
+	vtc_flow = rte_htonl(vtc_flow);
+
+	ip->vtc_flow = vtc_flow;
+}
+
 /**
  * Action profile
  */
@@ -2138,6 +2219,7 @@ action_valid(enum rte_table_action_type action)
 	case RTE_TABLE_ACTION_SYM_CRYPTO:
 	case RTE_TABLE_ACTION_TAG:
 	case RTE_TABLE_ACTION_DECAP:
+	case RTE_TABLE_ACTION_DSCP:
 		return 1;
 	default:
 		return 0;
@@ -2158,6 +2240,7 @@ struct ap_config {
 	struct rte_table_action_ttl_config ttl;
 	struct rte_table_action_stats_config stats;
 	struct rte_table_action_sym_crypto_config sym_crypto;
+	struct rte_table_action_dscp_config dscp;
 };
 
 static size_t
@@ -2180,6 +2263,8 @@ action_cfg_size(enum rte_table_action_type action)
 		return sizeof(struct rte_table_action_stats_config);
 	case RTE_TABLE_ACTION_SYM_CRYPTO:
 		return sizeof(struct rte_table_action_sym_crypto_config);
+	case RTE_TABLE_ACTION_DSCP:
+		return sizeof(struct rte_table_action_dscp_config);
 	default:
 		return 0;
 	}
@@ -2213,6 +2298,9 @@ action_cfg_get(struct ap_config *ap_config,
 
 	case RTE_TABLE_ACTION_SYM_CRYPTO:
 		return &ap_config->sym_crypto;
+
+	case RTE_TABLE_ACTION_DSCP:
+		return &ap_config->dscp;
 	default:
 		return NULL;
 	}
@@ -2278,6 +2366,9 @@ action_data_size(enum rte_table_action_type action,
 	case RTE_TABLE_ACTION_DECAP:
 		return sizeof(struct decap_data);
 
+	case RTE_TABLE_ACTION_DSCP:
+		return sizeof(struct dscp_data);
+
 	default:
 		return 0;
 	}
@@ -2543,6 +2634,10 @@ rte_table_action_apply(struct rte_table_action *action,
 		return decap_apply(action_data,
 			action_params);
 
+	case RTE_TABLE_ACTION_DSCP:
+		return dscp_apply(action_data,
+			action_params);
+
 	default:
 		return -EINVAL;
 	}
@@ -2939,6 +3034,17 @@ pkt_work(struct rte_mbuf *mbuf,
 		pkt_work_tag(mbuf, data);
 	}
 
+	if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DSCP)) {
+		void *data =
+			action_data_get(table_entry, action,
+				RTE_TABLE_ACTION_DSCP);
+
+		if (cfg->common.ip_version)
+			pkt_ipv4_work_dscp(ip, data);
+		else
+			pkt_ipv6_work_dscp(ip, data);
+	}
+
 	return drop_mask;
 }
 
@@ -3283,6 +3389,33 @@ pkt4_work(struct rte_mbuf **mbufs,
 			data0, data1, data2, data3);
 	}
 
+	if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DSCP)) {
+		void *data0 =
+			action_data_get(table_entry0, action,
+				RTE_TABLE_ACTION_DSCP);
+		void *data1 =
+			action_data_get(table_entry1, action,
+				RTE_TABLE_ACTION_DSCP);
+		void *data2 =
+			action_data_get(table_entry2, action,
+				RTE_TABLE_ACTION_DSCP);
+		void *data3 =
+			action_data_get(table_entry3, action,
+				RTE_TABLE_ACTION_DSCP);
+
+		if (cfg->common.ip_version) {
+			pkt_ipv4_work_dscp(ip0, data0);
+			pkt_ipv4_work_dscp(ip1, data1);
+			pkt_ipv4_work_dscp(ip2, data2);
+			pkt_ipv4_work_dscp(ip3, data3);
+		} else {
+			pkt_ipv6_work_dscp(ip0, data0);
+			pkt_ipv6_work_dscp(ip1, data1);
+			pkt_ipv6_work_dscp(ip2, data2);
+			pkt_ipv6_work_dscp(ip3, data3);
+		}
+	}
+
 	return drop_mask0 |
 		(drop_mask1 << 1) |
 		(drop_mask2 << 2) |
diff --git a/lib/librte_pipeline/rte_table_action.h b/lib/librte_pipeline/rte_table_action.h
index c96061291..28db53303 100644
--- a/lib/librte_pipeline/rte_table_action.h
+++ b/lib/librte_pipeline/rte_table_action.h
@@ -102,6 +102,9 @@ enum rte_table_action_type {
 
 	/** Packet decapsulations. */
 	RTE_TABLE_ACTION_DECAP,
+
+	/** Differentiated Services Code Point (DSCP) **/
+	RTE_TABLE_ACTION_DSCP,
 };
 
 /** Common action configuration (per table action profile). */
@@ -794,6 +797,23 @@ struct rte_table_action_decap_params {
 	uint16_t n;
 };
 
+/**
+ * RTE_TABLE_ACTION_DSCP
+ */
+/** DSCP action configuration (per table action profile). */
+struct rte_table_action_dscp_config {
+	/** dscp length  */
+	uint8_t dscp_len;
+
+};
+
+/** DSCP action parameters (per table rule). */
+struct rte_table_action_dscp_params {
+	/** dscp value to be set */
+	uint8_t dscp_val;
+
+};
+
 /**
  * Table action profile.
  */
-- 
2.17.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [dpdk-dev] [PATCH v2 2/3] pipeline: add implementation for DSCP action
  2019-02-12 14:03 ` [dpdk-dev] [PATCH v2 1/3] librte_pipeline: " Sheehan,Georgina
@ 2019-02-12 14:03   ` Sheehan,Georgina
  2019-02-28 19:24     ` Dumitrescu, Cristian
  2019-02-12 14:03   ` [dpdk-dev] [PATCH v2 3/3] net/softnic: add support " Sheehan,Georgina
  2019-02-28 19:21   ` [dpdk-dev] [PATCH v2 1/3] librte_pipeline: " Dumitrescu, Cristian
  2 siblings, 1 reply; 8+ messages in thread
From: Sheehan,Georgina @ 2019-02-12 14:03 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu, Georgina Sheehan

From: Georgina Sheehan <georgina.sheehan@intel.com>

This allows the application to change the DSCP value of incoming packets

v2: Added in call of function parse_table_action_dscp in softnic cli file

Signed-off-by: Georgina Sheehan <georgina.sheehan@intel.com>
---
 examples/ip_pipeline/action.c   | 11 +++++++
 examples/ip_pipeline/action.h   |  1 +
 examples/ip_pipeline/cli.c      | 52 ++++++++++++++++++++++++++++++++-
 examples/ip_pipeline/pipeline.h |  1 +
 examples/ip_pipeline/thread.c   | 10 +++++++
 5 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/examples/ip_pipeline/action.c b/examples/ip_pipeline/action.c
index d2104aad6..625c870a2 100644
--- a/examples/ip_pipeline/action.c
+++ b/examples/ip_pipeline/action.c
@@ -366,6 +366,17 @@ table_action_profile_create(const char *name,
 		}
 	}
 
+	if (params->action_mask & (1LLU << RTE_TABLE_ACTION_DSCP)) {
+		status = rte_table_action_profile_action_register(ap,
+				RTE_TABLE_ACTION_DSCP,
+				&params->dscp);
+
+		if (status) {
+			rte_table_action_profile_free(ap);
+			return NULL;
+		}
+	}
+
 	status = rte_table_action_profile_freeze(ap);
 	if (status) {
 		rte_table_action_profile_free(ap);
diff --git a/examples/ip_pipeline/action.h b/examples/ip_pipeline/action.h
index cde17e69a..ea8f81c56 100644
--- a/examples/ip_pipeline/action.h
+++ b/examples/ip_pipeline/action.h
@@ -54,6 +54,7 @@ struct table_action_profile_params {
 	struct rte_table_action_ttl_config ttl;
 	struct rte_table_action_stats_config stats;
 	struct rte_table_action_sym_crypto_config sym_crypto;
+	struct rte_table_action_dscp_config dscp;
 };
 
 struct table_action_profile {
diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
index a92467e63..ca3083a48 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -1045,7 +1045,8 @@ static const char cmd_table_action_profile_help[] =
 "   [time]\n"
 "   [sym_crypto dev <CRYPTODEV_NAME> offset <op_offset>]\n"
 "   [tag]\n"
-"   [decap]\n";
+"   [decap]\n"
+"   [dscp]\n";
 
 static void
 cmd_table_action_profile(char **tokens,
@@ -1458,6 +1459,17 @@ cmd_table_action_profile(char **tokens,
 		t0 += 1;
 	} /* decap */
 
+	if ((t0 < n_tokens) && (strcmp(tokens[t0], "dscp") == 0)) {
+		if (n_tokens < t0 + 1) {
+			snprintf(out, out_size, MSG_ARG_MISMATCH,
+				"table action profile dscp");
+			return;
+		}
+
+		p.action_mask |= 1LLU << RTE_TABLE_ACTION_DSCP;
+		t0 += 1;
+	} /** DSCP **/
+
 	if (t0 < n_tokens) {
 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
 		return;
@@ -3116,6 +3128,7 @@ parse_match(char **tokens,
  *       data_offset <data_offset>]
  *    [tag <tag>]
  *    [decap <n>]
+ *    [dscp <n>]
  *
  * where:
  *    <pa> ::= g | y | r | drop
@@ -4108,6 +4121,26 @@ parse_table_action_decap(char **tokens,
 	return 2;
 }
 
+static uint32_t
+parse_table_action_dscp(char **tokens,
+		uint32_t n_tokens,
+		struct table_rule_action *a)
+{
+	if ((n_tokens < 2) ||
+		strcmp(tokens[0], "dscp"))
+		return 0;
+
+	uint8_t dscp_val;
+
+	if (parser_read_uint8(&dscp_val, tokens[1]))
+		return 0;
+
+	a->dscp.dscp_val = dscp_val;
+
+	a->action_mask |= 1 << RTE_TABLE_ACTION_DSCP;
+	return 2;
+}
+
 static uint32_t
 parse_table_action(char **tokens,
 	uint32_t n_tokens,
@@ -4293,6 +4326,20 @@ parse_table_action(char **tokens,
 		n_tokens -= n;
 	}
 
+	if (n_tokens && (strcmp(tokens[0], "dscp") == 0)) {
+		uint32_t n;
+
+		n = parse_table_action_dscp(tokens, n_tokens, a);
+		if (n == 0) {
+			snprintf(out, out_size, MSG_ARG_INVALID,
+				"action dscp");
+			return 0;
+		}
+
+		tokens += n;
+		n_tokens -= n;
+	}
+
 	if (n_tokens0 - n_tokens == 1) {
 		snprintf(out, out_size, MSG_ARG_INVALID, "action");
 		return 0;
@@ -5056,6 +5103,9 @@ table_rule_show(const char *pipeline_name,
 		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP))
 			fprintf(f, "decap %u ", a->decap.n);
 
+		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_DSCP))
+			fprintf(f, "dscp ");
+
 		/* end */
 		fprintf(f, "\n");
 	}
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index 278775c2d..670174ed4 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -290,6 +290,7 @@ struct table_rule_action {
 	struct rte_table_action_sym_crypto_params sym_crypto;
 	struct rte_table_action_tag_params tag;
 	struct rte_table_action_decap_params decap;
+	struct rte_table_action_dscp_params dscp;
 };
 
 struct table_rule {
diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
index 272fbbeed..c9facb53e 100644
--- a/examples/ip_pipeline/thread.c
+++ b/examples/ip_pipeline/thread.c
@@ -2751,6 +2751,16 @@ action_convert(struct rte_table_action *a,
 			return status;
 	}
 
+	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_DSCP)) {
+		status = rte_table_action_apply(a,
+			data,
+			RTE_TABLE_ACTION_DSCP,
+			&action->dscp);
+
+		if (status)
+			return status;
+	}
+
 	return 0;
 }
 
-- 
2.17.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [dpdk-dev] [PATCH v2 3/3] net/softnic: add support for DSCP action
  2019-02-12 14:03 ` [dpdk-dev] [PATCH v2 1/3] librte_pipeline: " Sheehan,Georgina
  2019-02-12 14:03   ` [dpdk-dev] [PATCH v2 2/3] pipeline: add implementation " Sheehan,Georgina
@ 2019-02-12 14:03   ` Sheehan,Georgina
  2019-02-28 19:21   ` [dpdk-dev] [PATCH v2 1/3] librte_pipeline: " Dumitrescu, Cristian
  2 siblings, 0 replies; 8+ messages in thread
From: Sheehan,Georgina @ 2019-02-12 14:03 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu, Georgina Sheehan

From: Georgina Sheehan <georgina.sheehan@intel.com>

This allows the application to change the DSCP value of incoming packets

v2: Added in call of function parse_table_action_dscp in softnic cli file

Signed-off-by: Georgina Sheehan <georgina.sheehan@intel.com>
---
 drivers/net/softnic/rte_eth_softnic_action.c  | 14 ++++++
 drivers/net/softnic/rte_eth_softnic_cli.c     | 48 +++++++++++++++++++
 .../net/softnic/rte_eth_softnic_internals.h   |  2 +
 drivers/net/softnic/rte_eth_softnic_thread.c  | 10 ++++
 4 files changed, 74 insertions(+)

diff --git a/drivers/net/softnic/rte_eth_softnic_action.c b/drivers/net/softnic/rte_eth_softnic_action.c
index 92c744dc9..98d03d5ef 100644
--- a/drivers/net/softnic/rte_eth_softnic_action.c
+++ b/drivers/net/softnic/rte_eth_softnic_action.c
@@ -397,12 +397,26 @@ softnic_table_action_profile_create(struct pmd_internals *p,
 		}
 	}
 
+	if (params->action_mask & (1LLU << RTE_TABLE_ACTION_DSCP)) {
+		status = rte_table_action_profile_action_register(ap,
+			RTE_TABLE_ACTION_DSCP,
+			&params->dscp);
+
+		if (status) {
+			rte_table_action_profile_free(ap);
+			return NULL;
+		}
+	}
+
+
 	status = rte_table_action_profile_freeze(ap);
 	if (status) {
 		rte_table_action_profile_free(ap);
 		return NULL;
 	}
 
+
+
 	/* Node allocation */
 	profile = calloc(1, sizeof(struct softnic_table_action_profile));
 	if (profile == NULL) {
diff --git a/drivers/net/softnic/rte_eth_softnic_cli.c b/drivers/net/softnic/rte_eth_softnic_cli.c
index 76136c2e2..0e94cfc55 100644
--- a/drivers/net/softnic/rte_eth_softnic_cli.c
+++ b/drivers/net/softnic/rte_eth_softnic_cli.c
@@ -1358,6 +1358,7 @@ cmd_port_in_action_profile(struct pmd_internals *softnic,
  *  [time]
  *  [tag]
  *  [decap]
+ *  [dscp]
  *
  */
 static void
@@ -1787,6 +1788,17 @@ cmd_table_action_profile(struct pmd_internals *softnic,
 		t0 += 5;
 	} /* sym_crypto */
 
+	if (t0 < n_tokens && (strcmp(tokens[t0], "dscp") == 0)) {
+		if (n_tokens < t0 + 1) {
+			snprintf(out, out_size, MSG_ARG_MISMATCH,
+				"table action profile dscp");
+			return;
+		}
+
+		p.action_mask |= 1LLU << RTE_TABLE_ACTION_DSCP;
+		t0 += 1;
+	} /** DSCP **/
+
 	if (t0 < n_tokens) {
 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
 		return;
@@ -3432,6 +3444,7 @@ parse_match(char **tokens,
  *          aead_algo <algo> aead_key <key> aead_iv <iv> aead_aad <aad>
  *          digest_size <size>
  *       data_offset <data_offset>]
+ *    [dscp <n>]
  *
  * where:
  *    <pa> ::= g | y | r | drop
@@ -4431,6 +4444,27 @@ parse_table_action_decap(char **tokens,
 	return 2;
 }
 
+static uint32_t
+parse_table_action_dscp(char **tokens,
+		uint32_t n_tokens,
+		struct softnic_table_rule_action *a)
+{
+	if (n_tokens < 2 ||
+		strcmp(tokens[0], "dscp"))
+		return 0;
+
+	uint8_t dscp_val;
+
+	if (softnic_parser_read_uint8(&dscp_val, tokens[1]))
+		return 0;
+
+	a->dscp.dscp_val = dscp_val;
+
+	a->action_mask |= 1 << RTE_TABLE_ACTION_DSCP;
+
+	return 2;
+}
+
 static uint32_t
 parse_table_action(char **tokens,
 	uint32_t n_tokens,
@@ -4616,6 +4650,20 @@ parse_table_action(char **tokens,
 		n_tokens -= n;
 	}
 
+	if (n_tokens && (strcmp(tokens[0], "dscp") == 0)) {
+		uint32_t n;
+
+		n = parse_table_action_dscp(tokens, n_tokens, a);
+		if (n == 0) {
+			snprintf(out, out_size, MSG_ARG_INVALID,
+				"action dscp");
+			return 0;
+		}
+
+		tokens += n;
+		n_tokens -= n;
+	}
+
 	if (n_tokens0 - n_tokens == 1) {
 		snprintf(out, out_size, MSG_ARG_INVALID, "action");
 		return 0;
diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 415434d0d..67ba3ecf3 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -333,6 +333,7 @@ struct softnic_table_action_profile_params {
 	struct rte_table_action_ttl_config ttl;
 	struct rte_table_action_stats_config stats;
 	struct rte_table_action_sym_crypto_config sym_crypto;
+	struct rte_table_action_dscp_config dscp;
 };
 
 struct softnic_table_action_profile {
@@ -962,6 +963,7 @@ struct softnic_table_rule_action {
 	struct rte_table_action_tag_params tag;
 	struct rte_table_action_decap_params decap;
 	struct rte_table_action_sym_crypto_params sym_crypto;
+	struct rte_table_action_dscp_params dscp;
 };
 
 struct rte_flow {
diff --git a/drivers/net/softnic/rte_eth_softnic_thread.c b/drivers/net/softnic/rte_eth_softnic_thread.c
index 57989a5aa..e73d4a704 100644
--- a/drivers/net/softnic/rte_eth_softnic_thread.c
+++ b/drivers/net/softnic/rte_eth_softnic_thread.c
@@ -2598,6 +2598,16 @@ action_convert(struct rte_table_action *a,
 			return status;
 	}
 
+	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_DSCP)) {
+		status = rte_table_action_apply(a,
+			data,
+			RTE_TABLE_ACTION_DSCP,
+			&action->dscp);
+
+		if (status)
+			return status;
+	}
+
 	return 0;
 }
 
-- 
2.17.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/3] librte_pipeline: add support for DSCP action
  2019-02-12 14:03 ` [dpdk-dev] [PATCH v2 1/3] librte_pipeline: " Sheehan,Georgina
  2019-02-12 14:03   ` [dpdk-dev] [PATCH v2 2/3] pipeline: add implementation " Sheehan,Georgina
  2019-02-12 14:03   ` [dpdk-dev] [PATCH v2 3/3] net/softnic: add support " Sheehan,Georgina
@ 2019-02-28 19:21   ` Dumitrescu, Cristian
  2 siblings, 0 replies; 8+ messages in thread
From: Dumitrescu, Cristian @ 2019-02-28 19:21 UTC (permalink / raw)
  To: Sheehan, Georgina, dev

Hi Georgina,

Thanks for your patch set and sorry for my delayed reply!

> -----Original Message-----
> From: Sheehan, Georgina
> Sent: Sunday, February 11, 2018 1:29 PM
> To: dev@dpdk.org
> Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Sheehan,
> Georgina <georgina.sheehan@intel.com>
> Subject: [PATCH v2 1/3] librte_pipeline: add support for DSCP action

According to DPDK policy, the title of a library patch should remove the "librte_" prefix from the library name, i.e. the title of this patch should be: "pipeline: add support for DSCP action".

> 
> From: Georgina Sheehan <georgina.sheehan@intel.com>
> 
> This allows the application to change the DSCP value of incoming packets
> 
> v2: Added in call of function parse_table_action_dscp in softnic cli file
> 
> Signed-off-by: Georgina Sheehan <georgina.sheehan@intel.com>
> ---
>  lib/librte_pipeline/rte_table_action.c | 133 +++++++++++++++++++++++++
>  lib/librte_pipeline/rte_table_action.h |  20 ++++
>  2 files changed, 153 insertions(+)
> 

<snip>

> diff --git a/lib/librte_pipeline/rte_table_action.h
> b/lib/librte_pipeline/rte_table_action.h
> index c96061291..28db53303 100644
> --- a/lib/librte_pipeline/rte_table_action.h
> +++ b/lib/librte_pipeline/rte_table_action.h
> @@ -102,6 +102,9 @@ enum rte_table_action_type {
> 
>  	/** Packet decapsulations. */
>  	RTE_TABLE_ACTION_DECAP,
> +
> +	/** Differentiated Services Code Point (DSCP) **/
> +	RTE_TABLE_ACTION_DSCP,
>  };
> 
>  /** Common action configuration (per table action profile). */
> @@ -794,6 +797,23 @@ struct rte_table_action_decap_params {
>  	uint16_t n;
>  };
> 
> +/**
> + * RTE_TABLE_ACTION_DSCP
> + */
> +/** DSCP action configuration (per table action profile). */
> +struct rte_table_action_dscp_config {
> +	/** dscp length  */
> +	uint8_t dscp_len;

What exactly is DSCP length?

> +
> +};
> +
> +/** DSCP action parameters (per table rule). */
> +struct rte_table_action_dscp_params {
> +	/** dscp value to be set */
> +	uint8_t dscp_val;
> +
> +};
> +
>  /**
>   * Table action profile.
>   */
> --
> 2.17.1

I have a fundamental issue with this approach for DSCP marking action:
1/ This proposal seems to simply read a single pre-configured DSCP value from the table entry and apply it to all the packets that hit this table entry.
2/ To me, this approach is not really useful, as in practice different packets that belong to the same flow can be tagged with different DSCP values on the way out: for example, the flow can represent all the traffic for a given BNG subscriber, which can include management data, voice, real time video, high priority best effort, low priority best effort, etc packets.

DSCP is typically used by a specific provide to tag the traffic class and the priority of the incoming packets within its network. Packets from the same user can belong to different traffic classes and drop precedences, such as described in e.g. RFC 2598 and related. Therefore, what I suggest is:
1/ Replacing the single pre-defined DSCP value per table entry with an array defined per table (not per table entry).
2/ The reason to define this array per table as opposed to table entry is that the DSCP code points are typically defined per network (all users) rather than per user. Similar approach is already used by other existing actions, such as metering and traffic management.
3/ The array is a 2D array indexed by the traffic class (mbuf->hash.sched.traffic_class) and color/drop precedence (mbuf->hash.sched.color) of the current packet (mbuf). The values are DSCP values for different traffic classes and packet colors.
4/ The number of traffic classes (n_traffic_classes) should be a configuration parameter for this action, therefore the size of the DSCP array is n_traffic_classes x RTE_COLORS.

Makes sense?

Thanks,
Cristian

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [dpdk-dev] [PATCH v2 2/3] pipeline: add implementation for DSCP action
  2019-02-12 14:03   ` [dpdk-dev] [PATCH v2 2/3] pipeline: add implementation " Sheehan,Georgina
@ 2019-02-28 19:24     ` Dumitrescu, Cristian
  0 siblings, 0 replies; 8+ messages in thread
From: Dumitrescu, Cristian @ 2019-02-28 19:24 UTC (permalink / raw)
  To: Sheehan, Georgina, dev



> -----Original Message-----
> From: Sheehan, Georgina
> Sent: Sunday, February 11, 2018 1:29 PM
> To: dev@dpdk.org
> Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Sheehan,
> Georgina <georgina.sheehan@intel.com>
> Subject: [PATCH v2 2/3] pipeline: add implementation for DSCP action

According to DPDK conventions, the title should be: "examples/ip_pipeline: ..." instead of "pipeline: ..."

> 
> From: Georgina Sheehan <georgina.sheehan@intel.com>
> 
> This allows the application to change the DSCP value of incoming packets
> 
> v2: Added in call of function parse_table_action_dscp in softnic cli file
> 
> Signed-off-by: Georgina Sheehan <georgina.sheehan@intel.com>
> ---
>  examples/ip_pipeline/action.c   | 11 +++++++
>  examples/ip_pipeline/action.h   |  1 +
>  examples/ip_pipeline/cli.c      | 52 ++++++++++++++++++++++++++++++++-
>  examples/ip_pipeline/pipeline.h |  1 +
>  examples/ip_pipeline/thread.c   | 10 +++++++
>  5 files changed, 74 insertions(+), 1 deletion(-)
> 
> diff --git a/examples/ip_pipeline/action.c b/examples/ip_pipeline/action.c
> index d2104aad6..625c870a2 100644
> --- a/examples/ip_pipeline/action.c
> +++ b/examples/ip_pipeline/action.c
> @@ -366,6 +366,17 @@ table_action_profile_create(const char *name,
>  		}
>  	}
> 
> +	if (params->action_mask & (1LLU << RTE_TABLE_ACTION_DSCP)) {
> +		status = rte_table_action_profile_action_register(ap,
> +				RTE_TABLE_ACTION_DSCP,
> +				&params->dscp);
> +
> +		if (status) {
> +			rte_table_action_profile_free(ap);
> +			return NULL;
> +		}
> +	}
> +
>  	status = rte_table_action_profile_freeze(ap);
>  	if (status) {
>  		rte_table_action_profile_free(ap);
> diff --git a/examples/ip_pipeline/action.h b/examples/ip_pipeline/action.h
> index cde17e69a..ea8f81c56 100644
> --- a/examples/ip_pipeline/action.h
> +++ b/examples/ip_pipeline/action.h
> @@ -54,6 +54,7 @@ struct table_action_profile_params {
>  	struct rte_table_action_ttl_config ttl;
>  	struct rte_table_action_stats_config stats;
>  	struct rte_table_action_sym_crypto_config sym_crypto;
> +	struct rte_table_action_dscp_config dscp;
>  };
> 
>  struct table_action_profile {
> diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
> index a92467e63..ca3083a48 100644
> --- a/examples/ip_pipeline/cli.c
> +++ b/examples/ip_pipeline/cli.c
> @@ -1045,7 +1045,8 @@ static const char cmd_table_action_profile_help[] =
>  "   [time]\n"
>  "   [sym_crypto dev <CRYPTODEV_NAME> offset <op_offset>]\n"
>  "   [tag]\n"
> -"   [decap]\n";
> +"   [decap]\n"
> +"   [dscp]\n";
> 
>  static void
>  cmd_table_action_profile(char **tokens,
> @@ -1458,6 +1459,17 @@ cmd_table_action_profile(char **tokens,
>  		t0 += 1;
>  	} /* decap */
> 
> +	if ((t0 < n_tokens) && (strcmp(tokens[t0], "dscp") == 0)) {
> +		if (n_tokens < t0 + 1) {
> +			snprintf(out, out_size, MSG_ARG_MISMATCH,
> +				"table action profile dscp");
> +			return;
> +		}
> +
> +		p.action_mask |= 1LLU << RTE_TABLE_ACTION_DSCP;
> +		t0 += 1;
> +	} /** DSCP **/
> +
>  	if (t0 < n_tokens) {
>  		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
>  		return;
> @@ -3116,6 +3128,7 @@ parse_match(char **tokens,
>   *       data_offset <data_offset>]
>   *    [tag <tag>]
>   *    [decap <n>]
> + *    [dscp <n>]
>   *
>   * where:
>   *    <pa> ::= g | y | r | drop
> @@ -4108,6 +4121,26 @@ parse_table_action_decap(char **tokens,
>  	return 2;
>  }
> 
> +static uint32_t
> +parse_table_action_dscp(char **tokens,
> +		uint32_t n_tokens,
> +		struct table_rule_action *a)
> +{
> +	if ((n_tokens < 2) ||
> +		strcmp(tokens[0], "dscp"))
> +		return 0;
> +
> +	uint8_t dscp_val;
> +
> +	if (parser_read_uint8(&dscp_val, tokens[1]))
> +		return 0;
> +
> +	a->dscp.dscp_val = dscp_val;
> +
> +	a->action_mask |= 1 << RTE_TABLE_ACTION_DSCP;
> +	return 2;
> +}
> +
>  static uint32_t
>  parse_table_action(char **tokens,
>  	uint32_t n_tokens,
> @@ -4293,6 +4326,20 @@ parse_table_action(char **tokens,
>  		n_tokens -= n;
>  	}
> 
> +	if (n_tokens && (strcmp(tokens[0], "dscp") == 0)) {
> +		uint32_t n;
> +
> +		n = parse_table_action_dscp(tokens, n_tokens, a);
> +		if (n == 0) {
> +			snprintf(out, out_size, MSG_ARG_INVALID,
> +				"action dscp");
> +			return 0;
> +		}
> +
> +		tokens += n;
> +		n_tokens -= n;
> +	}
> +
>  	if (n_tokens0 - n_tokens == 1) {
>  		snprintf(out, out_size, MSG_ARG_INVALID, "action");
>  		return 0;
> @@ -5056,6 +5103,9 @@ table_rule_show(const char *pipeline_name,
>  		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP))
>  			fprintf(f, "decap %u ", a->decap.n);
> 
> +		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_DSCP))
> +			fprintf(f, "dscp ");
> +
>  		/* end */
>  		fprintf(f, "\n");
>  	}
> diff --git a/examples/ip_pipeline/pipeline.h
> b/examples/ip_pipeline/pipeline.h
> index 278775c2d..670174ed4 100644
> --- a/examples/ip_pipeline/pipeline.h
> +++ b/examples/ip_pipeline/pipeline.h
> @@ -290,6 +290,7 @@ struct table_rule_action {
>  	struct rte_table_action_sym_crypto_params sym_crypto;
>  	struct rte_table_action_tag_params tag;
>  	struct rte_table_action_decap_params decap;
> +	struct rte_table_action_dscp_params dscp;
>  };
> 
>  struct table_rule {
> diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
> index 272fbbeed..c9facb53e 100644
> --- a/examples/ip_pipeline/thread.c
> +++ b/examples/ip_pipeline/thread.c
> @@ -2751,6 +2751,16 @@ action_convert(struct rte_table_action *a,
>  			return status;
>  	}
> 
> +	if (action->action_mask & (1LLU << RTE_TABLE_ACTION_DSCP)) {
> +		status = rte_table_action_apply(a,
> +			data,
> +			RTE_TABLE_ACTION_DSCP,
> +			&action->dscp);
> +
> +		if (status)
> +			return status;
> +	}
> +
>  	return 0;
>  }
> 
> --
> 2.17.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2019-02-28 19:24 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-12  9:31 [dpdk-dev] [PATCH v1 1/3] librte_pipeline: add support for DSCP action Sheehan,Georgina
2019-02-12  9:31 ` [dpdk-dev] [PATCH v1 2/3] pipeline: add implementation " Sheehan,Georgina
2019-02-12  9:31 ` [dpdk-dev] [PATCH v1 3/3] net/softnic: add support " Sheehan,Georgina
2019-02-12 14:03 ` [dpdk-dev] [PATCH v2 1/3] librte_pipeline: " Sheehan,Georgina
2019-02-12 14:03   ` [dpdk-dev] [PATCH v2 2/3] pipeline: add implementation " Sheehan,Georgina
2019-02-28 19:24     ` Dumitrescu, Cristian
2019-02-12 14:03   ` [dpdk-dev] [PATCH v2 3/3] net/softnic: add support " Sheehan,Georgina
2019-02-28 19:21   ` [dpdk-dev] [PATCH v2 1/3] librte_pipeline: " Dumitrescu, Cristian

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).