shortcut-fe: include NAT information and sync reason in sync message

Some connection manager need these information to manipulate connection,
so add them in stats sync message

Change-Id: I59ea72a44d64159aba96b78f779ab7886ee55681
Signed-off-by: Xiaoping Fan <xfan@codeaurora.org>
diff --git a/shortcut-fe/sfe_cm.h b/shortcut-fe/sfe_cm.h
index 031af98..664b1e3 100644
--- a/shortcut-fe/sfe_cm.h
+++ b/shortcut-fe/sfe_cm.h
@@ -68,6 +68,10 @@
 	uint32_t original_accel;
 	uint32_t reply_accel;
 #endif
+	uint32_t src_priority;
+	uint32_t dest_priority;
+	uint32_t src_dscp;
+	uint32_t dest_dscp;
 };
 
 /*
@@ -81,6 +85,12 @@
 	__be16 dest_port;
 };
 
+typedef enum sfe_sync_reason {
+	SFE_SYNC_REASON_STATS,	/* Sync is to synchronize stats */
+	SFE_SYNC_REASON_FLUSH,	/* Sync is to flush a entry */
+	SFE_SYNC_REASON_DESTROY	/* Sync is to destroy a entry(requested by connection manager) */
+} sfe_sync_reason_t;
+
 /*
  * Structure used to sync connection stats/state back within the system.
  *
@@ -93,9 +103,13 @@
 	int is_v6;			/* Is it for ipv6? */
 	int protocol;			/* IP protocol number (IPPROTO_...) */
 	sfe_ip_addr_t src_ip;		/* Non-NAT source address, i.e. the creator of the connection */
+	sfe_ip_addr_t src_ip_xlate;	/* NATed source address */
 	__be16 src_port;		/* Non-NAT source port */
-	sfe_ip_addr_t dest_ip;	/* Non-NAT destination address, i.e. to whom the connection was created */
+	__be16 src_port_xlate;		/* NATed source port */
+	sfe_ip_addr_t dest_ip;		/* Non-NAT destination address, i.e. to whom the connection was created */
+	sfe_ip_addr_t dest_ip_xlate;	/* NATed destination address */
 	__be16 dest_port;		/* Non-NAT destination port */
+	__be16 dest_port_xlate;		/* NATed destination port */
 	uint32_t src_td_max_window;
 	uint32_t src_td_end;
 	uint32_t src_td_max_end;
@@ -110,6 +124,7 @@
 	uint64_t dest_byte_count;
 	uint32_t dest_new_packet_count;
 	uint32_t dest_new_byte_count;
+	uint32_t reason;		/* reason for stats sync message, i.e. destroy, flush, period sync */
 	uint64_t delta_jiffies;		/* Time to be added to the current timeout to keep the connection alive */
 };
 
diff --git a/shortcut-fe/sfe_ipv4.c b/shortcut-fe/sfe_ipv4.c
index 6a12317..7bcdf69 100644
--- a/shortcut-fe/sfe_ipv4.c
+++ b/shortcut-fe/sfe_ipv4.c
@@ -1057,7 +1057,8 @@
  * already held or isn't required.
  */
 static void sfe_ipv4_gen_sync_sfe_ipv4_connection(struct sfe_ipv4 *si, struct sfe_ipv4_connection *c,
-						  struct sfe_connection_sync *sis, uint64_t now_jiffies)
+						  struct sfe_connection_sync *sis, sfe_sync_reason_t reason,
+						  uint64_t now_jiffies)
 {
 	struct sfe_ipv4_connection_match *original_cm;
 	struct sfe_ipv4_connection_match *reply_cm;
@@ -1068,9 +1069,13 @@
 	sis->is_v6 = 0;
 	sis->protocol = c->protocol;
 	sis->src_ip.ip = c->src_ip;
+	sis->src_ip_xlate.ip = c->src_ip_xlate;
 	sis->dest_ip.ip = c->dest_ip;
+	sis->dest_ip_xlate.ip = c->dest_ip_xlate;
 	sis->src_port = c->src_port;
+	sis->src_port_xlate = c->src_port_xlate;
 	sis->dest_port = c->dest_port;
+	sis->dest_port_xlate = c->dest_port_xlate;
 
 	original_cm = c->original_match;
 	reply_cm = c->reply_match;
@@ -1097,6 +1102,8 @@
 	sis->dest_packet_count = reply_cm->rx_packet_count64;
 	sis->dest_byte_count = reply_cm->rx_byte_count64;
 
+	sis->reason = reason;
+
 	/*
 	 * Get the time increment since our last sync.
 	 */
@@ -1113,7 +1120,7 @@
  * from within a BH and so we're fine, but we're also called when connections are
  * torn down.
  */
-static void sfe_ipv4_flush_sfe_ipv4_connection(struct sfe_ipv4 *si, struct sfe_ipv4_connection *c)
+static void sfe_ipv4_flush_sfe_ipv4_connection(struct sfe_ipv4 *si, struct sfe_ipv4_connection *c, sfe_sync_reason_t reason)
 {
 	struct sfe_connection_sync sis;
 	uint64_t now_jiffies;
@@ -1130,7 +1137,7 @@
 		 * Generate a sync message and then sync.
 		 */
 		now_jiffies = get_jiffies_64();
-		sfe_ipv4_gen_sync_sfe_ipv4_connection(si, c, &sis, now_jiffies);
+		sfe_ipv4_gen_sync_sfe_ipv4_connection(si, c, &sis, reason, now_jiffies);
 		sync_rule_callback(&sis);
 	}
 
@@ -1223,7 +1230,7 @@
 		spin_unlock_bh(&si->lock);
 
 		DEBUG_TRACE("flush on find\n");
-		sfe_ipv4_flush_sfe_ipv4_connection(si, c);
+		sfe_ipv4_flush_sfe_ipv4_connection(si, c, SFE_SYNC_REASON_FLUSH);
 		return 0;
 	}
 
@@ -1251,7 +1258,7 @@
 		spin_unlock_bh(&si->lock);
 
 		DEBUG_TRACE("ttl too low\n");
-		sfe_ipv4_flush_sfe_ipv4_connection(si, c);
+		sfe_ipv4_flush_sfe_ipv4_connection(si, c, SFE_SYNC_REASON_FLUSH);
 		return 0;
 	}
 
@@ -1267,7 +1274,7 @@
 		spin_unlock_bh(&si->lock);
 
 		DEBUG_TRACE("larger than mtu\n");
-		sfe_ipv4_flush_sfe_ipv4_connection(si, c);
+		sfe_ipv4_flush_sfe_ipv4_connection(si, c, SFE_SYNC_REASON_FLUSH);
 		return 0;
 	}
 
@@ -1592,7 +1599,7 @@
 		spin_unlock_bh(&si->lock);
 
 		DEBUG_TRACE("flush on find\n");
-		sfe_ipv4_flush_sfe_ipv4_connection(si, c);
+		sfe_ipv4_flush_sfe_ipv4_connection(si, c, SFE_SYNC_REASON_FLUSH);
 		return 0;
 	}
 
@@ -1619,7 +1626,7 @@
 		spin_unlock_bh(&si->lock);
 
 		DEBUG_TRACE("ttl too low\n");
-		sfe_ipv4_flush_sfe_ipv4_connection(si, c);
+		sfe_ipv4_flush_sfe_ipv4_connection(si, c, SFE_SYNC_REASON_FLUSH);
 		return 0;
 	}
 
@@ -1635,7 +1642,7 @@
 		spin_unlock_bh(&si->lock);
 
 		DEBUG_TRACE("larger than mtu\n");
-		sfe_ipv4_flush_sfe_ipv4_connection(si, c);
+		sfe_ipv4_flush_sfe_ipv4_connection(si, c, SFE_SYNC_REASON_FLUSH);
 		return 0;
 	}
 
@@ -1652,7 +1659,7 @@
 
 		DEBUG_TRACE("TCP flags: 0x%x are not fast\n",
 			    flags & (TCP_FLAG_SYN | TCP_FLAG_RST | TCP_FLAG_FIN | TCP_FLAG_ACK));
-		sfe_ipv4_flush_sfe_ipv4_connection(si, c);
+		sfe_ipv4_flush_sfe_ipv4_connection(si, c, SFE_SYNC_REASON_FLUSH);
 		return 0;
 	}
 
@@ -1684,7 +1691,7 @@
 
 			DEBUG_TRACE("seq: %u exceeds right edge: %u\n",
 				    seq, cm->protocol_state.tcp.max_end + 1);
-			sfe_ipv4_flush_sfe_ipv4_connection(si, c);
+			sfe_ipv4_flush_sfe_ipv4_connection(si, c, SFE_SYNC_REASON_FLUSH);
 			return 0;
 		}
 
@@ -1700,7 +1707,7 @@
 			spin_unlock_bh(&si->lock);
 
 			DEBUG_TRACE("TCP data offset: %u, too small\n", data_offs);
-			sfe_ipv4_flush_sfe_ipv4_connection(si, c);
+			sfe_ipv4_flush_sfe_ipv4_connection(si, c, SFE_SYNC_REASON_FLUSH);
 			return 0;
 		}
 
@@ -1717,7 +1724,7 @@
 			spin_unlock_bh(&si->lock);
 
 			DEBUG_TRACE("TCP option SACK size is wrong\n");
-			sfe_ipv4_flush_sfe_ipv4_connection(si, c);
+			sfe_ipv4_flush_sfe_ipv4_connection(si, c, SFE_SYNC_REASON_FLUSH);
 			return 0;
 		}
 
@@ -1734,7 +1741,7 @@
 
 			DEBUG_TRACE("TCP data offset: %u, past end of packet: %u\n",
 				    data_offs, len);
-			sfe_ipv4_flush_sfe_ipv4_connection(si, c);
+			sfe_ipv4_flush_sfe_ipv4_connection(si, c, SFE_SYNC_REASON_FLUSH);
 			return 0;
 		}
 
@@ -1753,7 +1760,7 @@
 
 			DEBUG_TRACE("seq: %u before left edge: %u\n",
 				    end, cm->protocol_state.tcp.end - counter_cm->protocol_state.tcp.max_win - 1);
-			sfe_ipv4_flush_sfe_ipv4_connection(si, c);
+			sfe_ipv4_flush_sfe_ipv4_connection(si, c, SFE_SYNC_REASON_FLUSH);
 			return 0;
 		}
 
@@ -1769,7 +1776,7 @@
 
 			DEBUG_TRACE("ack: %u exceeds right edge: %u\n",
 				    sack, counter_cm->protocol_state.tcp.end + 1);
-			sfe_ipv4_flush_sfe_ipv4_connection(si, c);
+			sfe_ipv4_flush_sfe_ipv4_connection(si, c, SFE_SYNC_REASON_FLUSH);
 			return 0;
 		}
 
@@ -1788,7 +1795,7 @@
 			spin_unlock_bh(&si->lock);
 
 			DEBUG_TRACE("ack: %u before left edge: %u\n", sack, left_edge);
-			sfe_ipv4_flush_sfe_ipv4_connection(si, c);
+			sfe_ipv4_flush_sfe_ipv4_connection(si, c, SFE_SYNC_REASON_FLUSH);
 			return 0;
 		}
 
@@ -2148,7 +2155,7 @@
 	si->packets_not_forwarded++;
 	spin_unlock_bh(&si->lock);
 
-	sfe_ipv4_flush_sfe_ipv4_connection(si, c);
+	sfe_ipv4_flush_sfe_ipv4_connection(si, c, SFE_SYNC_REASON_FLUSH);
 	return 0;
 }
 
@@ -2653,7 +2660,7 @@
 	sfe_ipv4_remove_sfe_ipv4_connection(si, c);
 	spin_unlock_bh(&si->lock);
 
-	sfe_ipv4_flush_sfe_ipv4_connection(si, c);
+	sfe_ipv4_flush_sfe_ipv4_connection(si, c, SFE_SYNC_REASON_DESTROY);
 
 	DEBUG_INFO("connection destroyed - p: %d, s: %pI4:%u, d: %pI4:%u\n",
 		   sid->protocol, &sid->src_ip.ip, ntohs(sid->src_port),
@@ -2730,7 +2737,7 @@
 	spin_unlock_bh(&si->lock);
 
 	if (c) {
-		sfe_ipv4_flush_sfe_ipv4_connection(si, c);
+		sfe_ipv4_flush_sfe_ipv4_connection(si, c, SFE_SYNC_REASON_DESTROY);
 		goto another_round;
 	}
 }
@@ -2817,7 +2824,7 @@
 		 * Sync the connection state.
 		 */
 		c = cm->connection;
-		sfe_ipv4_gen_sync_sfe_ipv4_connection(si, c, &sis, now_jiffies);
+		sfe_ipv4_gen_sync_sfe_ipv4_connection(si, c, &sis, SFE_SYNC_REASON_STATS, now_jiffies);
 
 		/*
 		 * We don't want to be holding the lock when we sync!
diff --git a/shortcut-fe/sfe_ipv6.c b/shortcut-fe/sfe_ipv6.c
index dfa3b87..1d63326 100644
--- a/shortcut-fe/sfe_ipv6.c
+++ b/shortcut-fe/sfe_ipv6.c
@@ -1124,7 +1124,8 @@
  * already held or isn't required.
  */
 static void sfe_ipv6_gen_sync_connection(struct sfe_ipv6 *si, struct sfe_ipv6_connection *c,
-						  struct sfe_connection_sync *sis, uint64_t now_jiffies)
+					struct sfe_connection_sync *sis, sfe_sync_reason_t reason,
+					uint64_t now_jiffies)
 {
 	struct sfe_ipv6_connection_match *original_cm;
 	struct sfe_ipv6_connection_match *reply_cm;
@@ -1134,9 +1135,13 @@
 	 */
 	sis->protocol = c->protocol;
 	sis->src_ip.ip6[0] = c->src_ip[0];
+	sis->src_ip_xlate.ip6[0] = c->src_ip_xlate[0];
 	sis->dest_ip.ip6[0] = c->dest_ip[0];
+	sis->dest_ip_xlate.ip6[0] = c->dest_ip_xlate[0];
 	sis->src_port = c->src_port;
+	sis->src_port_xlate = c->src_port_xlate;
 	sis->dest_port = c->dest_port;
+	sis->dest_port_xlate = c->dest_port_xlate;
 
 	original_cm = c->original_match;
 	reply_cm = c->reply_match;
@@ -1163,6 +1168,8 @@
 	sis->dest_packet_count = reply_cm->rx_packet_count64;
 	sis->dest_byte_count = reply_cm->rx_byte_count64;
 
+	sis->reason = reason;
+
 	/*
 	 * Get the time increment since our last sync.
 	 */
@@ -1179,7 +1186,7 @@
  * from within a BH and so we're fine, but we're also called when connections are
  * torn down.
  */
-static void sfe_ipv6_flush_connection(struct sfe_ipv6 *si, struct sfe_ipv6_connection *c)
+static void sfe_ipv6_flush_connection(struct sfe_ipv6 *si, struct sfe_ipv6_connection *c, sfe_sync_reason_t reason)
 {
 	struct sfe_connection_sync sis;
 	uint64_t now_jiffies;
@@ -1196,7 +1203,7 @@
 		 * Generate a sync message and then sync.
 		 */
 		now_jiffies = get_jiffies_64();
-		sfe_ipv6_gen_sync_connection(si, c, &sis, now_jiffies);
+		sfe_ipv6_gen_sync_connection(si, c, &sis, reason, now_jiffies);
 		sync_rule_callback(&sis);
 	}
 
@@ -1288,7 +1295,7 @@
 		spin_unlock_bh(&si->lock);
 
 		DEBUG_TRACE("flush on find\n");
-		sfe_ipv6_flush_connection(si, c);
+		sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_FLUSH);
 		return 0;
 	}
 
@@ -1315,7 +1322,7 @@
 		spin_unlock_bh(&si->lock);
 
 		DEBUG_TRACE("hop_limit too low\n");
-		sfe_ipv6_flush_connection(si, c);
+		sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_FLUSH);
 		return 0;
 	}
 
@@ -1331,7 +1338,7 @@
 		spin_unlock_bh(&si->lock);
 
 		DEBUG_TRACE("larger than mtu\n");
-		sfe_ipv6_flush_connection(si, c);
+		sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_FLUSH);
 		return 0;
 	}
 
@@ -1636,7 +1643,7 @@
 		spin_unlock_bh(&si->lock);
 
 		DEBUG_TRACE("flush on find\n");
-		sfe_ipv6_flush_connection(si, c);
+		sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_FLUSH);
 		return 0;
 	}
 
@@ -1663,7 +1670,7 @@
 		spin_unlock_bh(&si->lock);
 
 		DEBUG_TRACE("hop_limit too low\n");
-		sfe_ipv6_flush_connection(si, c);
+		sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_FLUSH);
 		return 0;
 	}
 
@@ -1679,7 +1686,7 @@
 		spin_unlock_bh(&si->lock);
 
 		DEBUG_TRACE("larger than mtu\n");
-		sfe_ipv6_flush_connection(si, c);
+		sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_FLUSH);
 		return 0;
 	}
 
@@ -1696,7 +1703,7 @@
 
 		DEBUG_TRACE("TCP flags: 0x%x are not fast\n",
 			    flags & (TCP_FLAG_SYN | TCP_FLAG_RST | TCP_FLAG_FIN | TCP_FLAG_ACK));
-		sfe_ipv6_flush_connection(si, c);
+		sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_FLUSH);
 		return 0;
 	}
 
@@ -1728,7 +1735,7 @@
 
 			DEBUG_TRACE("seq: %u exceeds right edge: %u\n",
 				    seq, cm->protocol_state.tcp.max_end + 1);
-			sfe_ipv6_flush_connection(si, c);
+			sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_FLUSH);
 			return 0;
 		}
 
@@ -1744,7 +1751,7 @@
 			spin_unlock_bh(&si->lock);
 
 			DEBUG_TRACE("TCP data offset: %u, too small\n", data_offs);
-			sfe_ipv6_flush_connection(si, c);
+			sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_FLUSH);
 			return 0;
 		}
 
@@ -1761,7 +1768,7 @@
 			spin_unlock_bh(&si->lock);
 
 			DEBUG_TRACE("TCP option SACK size is wrong\n");
-			sfe_ipv6_flush_connection(si, c);
+			sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_FLUSH);
 			return 0;
 		}
 
@@ -1778,7 +1785,7 @@
 
 			DEBUG_TRACE("TCP data offset: %u, past end of packet: %u\n",
 				    data_offs, len);
-			sfe_ipv6_flush_connection(si, c);
+			sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_FLUSH);
 			return 0;
 		}
 
@@ -1797,7 +1804,7 @@
 
 			DEBUG_TRACE("seq: %u before left edge: %u\n",
 				    end, cm->protocol_state.tcp.end - counter_cm->protocol_state.tcp.max_win - 1);
-			sfe_ipv6_flush_connection(si, c);
+			sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_FLUSH);
 			return 0;
 		}
 
@@ -1813,7 +1820,7 @@
 
 			DEBUG_TRACE("ack: %u exceeds right edge: %u\n",
 				    sack, counter_cm->protocol_state.tcp.end + 1);
-			sfe_ipv6_flush_connection(si, c);
+			sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_FLUSH);
 			return 0;
 		}
 
@@ -1832,7 +1839,7 @@
 			spin_unlock_bh(&si->lock);
 
 			DEBUG_TRACE("ack: %u before left edge: %u\n", sack, left_edge);
-			sfe_ipv6_flush_connection(si, c);
+			sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_FLUSH);
 			return 0;
 		}
 
@@ -2172,7 +2179,7 @@
 	si->packets_not_forwarded++;
 	spin_unlock_bh(&si->lock);
 
-	sfe_ipv6_flush_connection(si, c);
+	sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_FLUSH);
 	return 0;
 }
 
@@ -2673,7 +2680,7 @@
 	sfe_ipv6_remove_connection(si, c);
 	spin_unlock_bh(&si->lock);
 
-	sfe_ipv6_flush_connection(si, c);
+	sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_DESTROY);
 
 	DEBUG_INFO("connection destroyed - p: %d, s: %pI6:%u, d: %pI6:%u\n",
 		   sid->protocol, sid->src_ip.ip6, ntohs(sid->src_port),
@@ -2744,7 +2751,7 @@
 	spin_unlock_bh(&si->lock);
 
 	if (c) {
-		sfe_ipv6_flush_connection(si, c);
+		sfe_ipv6_flush_connection(si, c, SFE_SYNC_REASON_DESTROY);
 		goto another_round;
 	}
 }
@@ -2831,7 +2838,7 @@
 		 * Sync the connection state.
 		 */
 		c = cm->connection;
-		sfe_ipv6_gen_sync_connection(si, c, &sis, now_jiffies);
+		sfe_ipv6_gen_sync_connection(si, c, &sis, SFE_SYNC_REASON_STATS, now_jiffies);
 
 		/*
 		 * We don't want to be holding the lock when we sync!