All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Sheehan,Georgina" <georgina.sheehan@intel.com>
To: dev@dpdk.org
Cc: cristian.dumitrescu@intel.com,
	Georgina Sheehan <georgina.sheehan@intel.com>
Subject: [PATCH v1 1/3] librte_pipeline: add support for DSCP action
Date: Sun, 11 Feb 2018 08:57:20 +0000	[thread overview]
Message-ID: <20180211085722.59717-1-georgina.sheehan@intel.com> (raw)

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

             reply	other threads:[~2019-02-12  9:31 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-11  8:57 Sheehan,Georgina [this message]
2018-02-11  8:57 ` [PATCH v1 2/3] pipeline: add implementation for DSCP action Sheehan,Georgina
2018-02-11  8:57 ` [PATCH v1 3/3] net/softnic: add support " Sheehan,Georgina
2018-02-11 13:29 ` [PATCH v2 1/3] librte_pipeline: " Sheehan,Georgina
2018-02-11 13:29   ` [PATCH v2 2/3] pipeline: add implementation " Sheehan,Georgina
2019-02-28 19:24     ` Dumitrescu, Cristian
2018-02-11 13:29   ` [PATCH v2 3/3] net/softnic: add support " Sheehan,Georgina
2019-02-28 19:21   ` [PATCH v2 1/3] librte_pipeline: " Dumitrescu, Cristian

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180211085722.59717-1-georgina.sheehan@intel.com \
    --to=georgina.sheehan@intel.com \
    --cc=cristian.dumitrescu@intel.com \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.