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,