In this patch we use kernel jhash table to track
connection, and then enqueue net packet like this:
+ CompareState ++
| |
+---------------+ +---------------+ +---------------+
|conn list +--->conn +--------->conn |
+---------------+ +---------------+ +---------------+
| | | | | |
+---------------+ +---v----+ +---v----+ +---v----+ +---v----+
|primary | |secondary |primary | |secondary
|packet | |packet + |packet | |packet +
+--------+ +--------+ +--------+ +--------+
| | | |
+---v----+ +---v----+ +---v----+ +---v----+
|primary | |secondary |primary | |secondary
|packet | |packet + |packet | |packet +
+--------+ +--------+ +--------+ +--------+
| | | |
+---v----+ +---v----+ +---v----+ +---v----+
|primary | |secondary |primary | |secondary
|packet | |packet + |packet | |packet +
+--------+ +--------+ +--------+ +--------+
We use conn_list to record connection info.
When we want to enqueue a packet, firstly get the
connection from connection_track_table. then push
the packet to g_queue(pri/sec) in it's own conn.
Signed-off-by: Zhang Chen <address@hidden>
Signed-off-by: Li Zhijian <address@hidden>
Signed-off-by: Wen Congyang <address@hidden>
---
net/colo-compare.c | 51 ++++++++++++++++++++-----
net/colo.c | 108
+++++++++++++++++++++++++++++++++++++++++++++++++++++
net/colo.h | 27 ++++++++++++++
3 files changed, 176 insertions(+), 10 deletions(-)
diff --git a/net/colo-compare.c b/net/colo-compare.c
index d642ad4..42fc354 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -70,6 +70,11 @@ typedef struct CompareState {
SocketReadState pri_rs;
SocketReadState sec_rs;
+ /* connection list: the connections belonged to this NIC could
be found
+ * in this list.
+ * element type: Connection
+ */
+ GQueue conn_list;
/* hashtable to save connection */
GHashTable *connection_track_table;
} CompareState;
@@ -97,7 +102,9 @@ static int compare_chr_send(CharDriverState *out,
*/
static int packet_enqueue(CompareState *s, int mode)
{
+ ConnectionKey key = {{ 0 } };
Packet *pkt = NULL;
+ Connection *conn;
if (mode == PRIMARY_IN) {
pkt = packet_new(s->pri_rs.buf, s->pri_rs.packet_len);
@@ -110,17 +117,34 @@ static int packet_enqueue(CompareState *s, int
mode)
pkt = NULL;
return -1;
}
- /* TODO: get connection key from pkt */
+ fill_connection_key(pkt, &key);
- /*
- * TODO: use connection key get conn from
- * connection_track_table
- */
+ conn = connection_get(s->connection_track_table,
+ &key,
+ &s->conn_list);
- /*
- * TODO: insert pkt to it's conn->primary_list
- * or conn->secondary_list
- */
+ if (!conn->processing) {
+ g_queue_push_tail(&s->conn_list, conn);
+ conn->processing = true;
+ }
+
+ if (mode == PRIMARY_IN) {
+ if (g_queue_get_length(&conn->primary_list) <=
+ MAX_QUEUE_SIZE) {
+ g_queue_push_tail(&conn->primary_list, pkt);
+ } else {
+ error_report("colo compare primary queue size too big,"
+ "drop packet");
+ }
+ } else {
+ if (g_queue_get_length(&conn->secondary_list) <
+ MAX_QUEUE_SIZE) {