shortcut-fe: support to remark packet DSCP and skb priority

Change-Id: Icfd14f2c472405269dd8bfe909f4d7e0604ad57c
Signed-off-by: Xiaoping Fan <xfan@codeaurora.org>
diff --git a/shortcut-fe/sfe_ipv6.c b/shortcut-fe/sfe_ipv6.c
index 1d63326..4c570ab 100644
--- a/shortcut-fe/sfe_ipv6.c
+++ b/shortcut-fe/sfe_ipv6.c
@@ -55,6 +55,9 @@
 	__be16 h_proto;
 } SFE_IPV6_UNALIGNED_STRUCT;
 
+#define SFE_IPV6_DSCP_MASK 0xf03f
+#define SFE_IPV6_DSCP_SHIFT 2
+
 /*
  * An IPv6 header, but with an optional "packed" attribute to
  * help with performance on some platforms (see the definition of
@@ -183,16 +186,20 @@
 /*
  * Bit flags for IPv6 connection matching entry.
  */
-#define SFE_IPV6_CONNECTION_MATCH_FLAG_XLATE_SRC 0x1
+#define SFE_IPV6_CONNECTION_MATCH_FLAG_XLATE_SRC (1<<0)
 					/* Perform source translation */
-#define SFE_IPV6_CONNECTION_MATCH_FLAG_XLATE_DEST 0x2
+#define SFE_IPV6_CONNECTION_MATCH_FLAG_XLATE_DEST (1<<1)
 					/* Perform destination translation */
-#define SFE_IPV6_CONNECTION_MATCH_FLAG_NO_SEQ_CHECK 0x4
+#define SFE_IPV6_CONNECTION_MATCH_FLAG_NO_SEQ_CHECK (1<<2)
 					/* Ignore TCP sequence numbers */
-#define SFE_IPV6_CONNECTION_MATCH_FLAG_WRITE_FAST_ETH_HDR 0x8
+#define SFE_IPV6_CONNECTION_MATCH_FLAG_WRITE_FAST_ETH_HDR (1<<3)
 					/* Fast Ethernet header write */
-#define SFE_IPV6_CONNECTION_MATCH_FLAG_WRITE_L2_HDR 0x10
+#define SFE_IPV6_CONNECTION_MATCH_FLAG_WRITE_L2_HDR (1<<4)
 					/* Fast Ethernet header write */
+#define SFE_IPV6_CONNECTION_MATCH_FLAG_PRIORITY_REMARK (1<<5)
+					/* remark priority of SKB */
+#define SFE_IPV6_CONNECTION_MATCH_FLAG_DSCP_REMARK (1<<6)
+					/* remark DSCP of packet */
 
 /*
  * IPv6 connection matching structure.
@@ -258,6 +265,12 @@
 					/* Transport layer checksum adjustment after destination translation */
 
 	/*
+	 * QoS information
+	 */
+	uint32_t priority;
+	uint32_t dscp;
+
+	/*
 	 * Packet transmit information.
 	 */
 	struct net_device *xmit_dev;	/* Network device on which to transmit */
@@ -554,6 +567,17 @@
 }
 
 /*
+ * sfe_ipv6_change_dsfield()
+ *	change dscp field in IPv6 packet
+ */
+static inline void sfe_ipv6_change_dsfield(struct sfe_ipv6_ip_hdr *iph, uint8_t dscp)
+{
+	__be16 *p = (__be16 *)iph;
+
+	*p = ((*p & htons(SFE_IPV6_DSCP_MASK)) | htons((u16)dscp << 4));
+}
+
+/*
  * sfe_ipv6_get_connection_match_hash()
  *	Generate the hash used in connection match lookups.
  */
@@ -1347,6 +1371,13 @@
 	 */
 
 	/*
+	 * Update DSCP
+	 */
+	if (unlikely(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_DSCP_REMARK)) {
+		sfe_ipv6_change_dsfield(iph, cm->dscp);
+	}
+
+	/*
 	 * Decrement our hop_limit.
 	 */
 	iph->hop_limit -= 1;
@@ -1440,6 +1471,13 @@
 	}
 
 	/*
+	 * Update priority of skb.
+	 */
+	if (unlikely(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_PRIORITY_REMARK)) {
+		skb->priority = cm->priority;
+	}
+
+	/*
 	 * Mark outgoing packet.
 	 */
 	skb->mark = cm->connection->mark;
@@ -1871,6 +1909,13 @@
 	 */
 
 	/*
+	 * Update DSCP
+	 */
+	if (unlikely(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_DSCP_REMARK)) {
+		sfe_ipv6_change_dsfield(iph, cm->dscp);
+	}
+
+	/*
 	 * Decrement our hop_limit.
 	 */
 	iph->hop_limit -= 1;
@@ -1962,6 +2007,13 @@
 	}
 
 	/*
+	 * Update priority of skb.
+	 */
+	if (unlikely(cm->flags & SFE_IPV6_CONNECTION_MATCH_FLAG_PRIORITY_REMARK)) {
+		skb->priority = cm->priority;
+	}
+
+	/*
 	 * Mark outgoing packet
 	 */
 	skb->mark = cm->connection->mark;
@@ -2493,6 +2545,14 @@
 	original_cm->connection = c;
 	original_cm->counter_match = reply_cm;
 	original_cm->flags = 0;
+	if (sic->flags & SFE_CREATE_FLAG_REMARK_PRIORITY) {
+		original_cm->priority = sic->src_priority;
+		original_cm->flags |= SFE_IPV6_CONNECTION_MATCH_FLAG_PRIORITY_REMARK;
+	}
+	if (sic->flags & SFE_CREATE_FLAG_REMARK_DSCP) {
+		original_cm->dscp = sic->src_dscp << SFE_IPV6_DSCP_SHIFT;
+		original_cm->flags |= SFE_IPV6_CONNECTION_MATCH_FLAG_DSCP_REMARK;
+	}
 #ifdef CONFIG_NF_FLOW_COOKIE
 	original_cm->flow_cookie = 0;
 #endif
@@ -2544,6 +2604,14 @@
 	reply_cm->connection = c;
 	reply_cm->counter_match = original_cm;
 	reply_cm->flags = 0;
+	if (sic->flags & SFE_CREATE_FLAG_REMARK_PRIORITY) {
+		reply_cm->priority = sic->dest_priority;
+		reply_cm->flags |= SFE_IPV6_CONNECTION_MATCH_FLAG_PRIORITY_REMARK;
+	}
+	if (sic->flags & SFE_CREATE_FLAG_REMARK_DSCP) {
+		reply_cm->dscp = sic->dest_dscp << SFE_IPV6_DSCP_SHIFT;
+		reply_cm->flags |= SFE_IPV6_CONNECTION_MATCH_FLAG_DSCP_REMARK;
+	}
 #ifdef CONFIG_NF_FLOW_COOKIE
 	reply_cm->flow_cookie = 0;
 #endif
@@ -2926,7 +2994,7 @@
 	uint64_t dest_rx_packets;
 	uint64_t dest_rx_bytes;
 	uint64_t last_sync_jiffies;
-	uint32_t mark;
+	uint32_t mark, src_priority, dest_priority, src_dscp, dest_dscp;
 #ifdef CONFIG_NF_FLOW_COOKIE
 	int src_flow_cookie, dst_flow_cookie;
 #endif
@@ -2958,6 +3026,8 @@
 	src_ip_xlate = c->src_ip_xlate[0];
 	src_port = c->src_port;
 	src_port_xlate = c->src_port_xlate;
+	src_priority = original_cm->priority;
+	src_dscp = original_cm->dscp >> SFE_IPV6_DSCP_SHIFT;
 
 	sfe_ipv6_connection_match_update_summary_stats(original_cm);
 	sfe_ipv6_connection_match_update_summary_stats(reply_cm);
@@ -2969,6 +3039,8 @@
 	dest_ip_xlate = c->dest_ip_xlate[0];
 	dest_port = c->dest_port;
 	dest_port_xlate = c->dest_port_xlate;
+	dest_priority = reply_cm->priority;
+	dest_dscp = reply_cm->dscp >> SFE_IPV6_DSCP_SHIFT;
 	dest_rx_packets = reply_cm->rx_packet_count64;
 	dest_rx_bytes = reply_cm->rx_byte_count64;
 	last_sync_jiffies = get_jiffies_64() - c->last_sync_jiffies;
@@ -2984,10 +3056,12 @@
 				"src_dev=\"%s\" "
 				"src_ip=\"%pI6\" src_ip_xlate=\"%pI6\" "
 				"src_port=\"%u\" src_port_xlate=\"%u\" "
+				"src_priority=\"%u\" src_dscp=\"%u\" "
 				"src_rx_pkts=\"%llu\" src_rx_bytes=\"%llu\" "
 				"dest_dev=\"%s\" "
 				"dest_ip=\"%pI6\" dest_ip_xlate=\"%pI6\" "
 				"dest_port=\"%u\" dest_port_xlate=\"%u\" "
+				"dest_priority=\"%u\" dest_dscp=\"%u\" "
 				"dest_rx_pkts=\"%llu\" dest_rx_bytes=\"%llu\" "
 #ifdef CONFIG_NF_FLOW_COOKIE
 				"src_flow_cookie=\"%d\" dst_flow_cookie=\"%d\" "
@@ -2998,10 +3072,12 @@
 				src_dev->name,
 				&src_ip, &src_ip_xlate,
 				ntohs(src_port), ntohs(src_port_xlate),
+				src_priority, src_dscp,
 				src_rx_packets, src_rx_bytes,
 				dest_dev->name,
 				&dest_ip, &dest_ip_xlate,
 				ntohs(dest_port), ntohs(dest_port_xlate),
+				dest_priority, dest_dscp,
 				dest_rx_packets, dest_rx_bytes,
 #ifdef CONFIG_NF_FLOW_COOKIE
 				src_flow_cookie, dst_flow_cookie,