From patchwork Tue Dec 22 10:42:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhang Chen X-Patchwork-Id: 560012 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id A3EAC140BC3 for ; Tue, 22 Dec 2015 23:43:33 +1100 (AEDT) Received: from localhost ([::1]:50058 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aBMHr-0004na-HI for incoming@patchwork.ozlabs.org; Tue, 22 Dec 2015 07:43:31 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41618) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aBMDq-0005RG-Bv for qemu-devel@nongnu.org; Tue, 22 Dec 2015 07:39:25 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aBMDk-00008r-Di for qemu-devel@nongnu.org; Tue, 22 Dec 2015 07:39:22 -0500 Received: from [59.151.112.132] (port=17493 helo=heian.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aBMDk-00005q-0f for qemu-devel@nongnu.org; Tue, 22 Dec 2015 07:39:16 -0500 X-IronPort-AV: E=Sophos;i="5.20,346,1444665600"; d="scan'208";a="1856286" Received: from bogon (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 22 Dec 2015 18:43:11 +0800 Received: from G08CNEXCHPEKD02.g08.fujitsu.local (unknown [10.167.33.83]) by cn.fujitsu.com (Postfix) with ESMTP id 7E7F441887D9; Tue, 22 Dec 2015 18:42:52 +0800 (CST) Received: from G08FNSTD140215.g08.fujitsu.local (10.167.226.56) by G08CNEXCHPEKD02.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.181.6; Tue, 22 Dec 2015 18:42:52 +0800 From: Zhang Chen To: qemu devel , Jason Wang , Stefan Hajnoczi Date: Tue, 22 Dec 2015 18:42:56 +0800 Message-ID: <1450780978-19123-9-git-send-email-zhangchen.fnst@cn.fujitsu.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1450780978-19123-1-git-send-email-zhangchen.fnst@cn.fujitsu.com> References: <1450780978-19123-1-git-send-email-zhangchen.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.226.56] X-yoursite-MailScanner-ID: 7E7F441887D9.AF111 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: zhangchen.fnst@cn.fujitsu.com X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 59.151.112.132 Cc: Li Zhijian , Gui jianfeng , "eddie.dong" , "Dr. David Alan Gilbert" , Huang peng , Gong lei , jan.kiszka@siemens.com, Zhang Chen , Yang Hongyang , zhanghailiang Subject: [Qemu-devel] [RFC PATCH v2 08/10] net/colo-proxy: Handle packet and connection X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: zhangchen In here we will handle ip packet and connection Signed-off-by: zhangchen Signed-off-by: zhanghailiang --- net/colo-proxy.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/net/colo-proxy.c b/net/colo-proxy.c index 5e5c72e..06bab80 100644 --- a/net/colo-proxy.c +++ b/net/colo-proxy.c @@ -167,11 +167,141 @@ static int connection_key_equal(const void *opaque1, const void *opaque2) return memcmp(opaque1, opaque2, sizeof(ConnectionKey)) == 0; } +static void connection_destroy(void *opaque) +{ + Connection *conn = opaque; + + g_queue_foreach(&conn->primary_list, packet_destroy, NULL); + g_queue_free(&conn->primary_list); + g_queue_foreach(&conn->secondary_list, packet_destroy, NULL); + g_queue_free(&conn->secondary_list); + g_slice_free(Connection, conn); +} + +static Connection *connection_new(ConnectionKey *key) +{ + Connection *conn = g_slice_new(Connection); + + conn->ip_proto = key->ip_proto; + conn->processing = false; + g_queue_init(&conn->primary_list); + g_queue_init(&conn->secondary_list); + + return conn; +} + +/* + * Clear hashtable, stop this hash growing really huge + */ +static void clear_connection_hashtable(COLOProxyState *s) +{ + s->hashtable_size = 0; + g_hash_table_remove_all(colo_conn_hash); + trace_colo_proxy("clear_connection_hashtable"); +} + bool colo_proxy_query_checkpoint(void) { return colo_do_checkpoint; } +/* Return 0 on success, or return -1 if the pkt is corrupted */ +static int parse_packet_early(Packet *pkt, ConnectionKey *key) +{ + int network_length; + uint8_t *data = pkt->data; + uint16_t l3_proto; + uint32_t tmp_ports; + ssize_t l2hdr_len = eth_get_l2_hdr_length(data); + + pkt->network_layer = data + ETH_HLEN; + l3_proto = eth_get_l3_proto(data, l2hdr_len); + if (l3_proto != ETH_P_IP) { + if (l3_proto == ETH_P_ARP) { + return -1; + } + return 0; + } + + network_length = pkt->ip->ip_hl * 4; + pkt->transport_layer = pkt->network_layer + network_length; + key->ip_proto = pkt->ip->ip_p; + key->src = pkt->ip->ip_src; + key->dst = pkt->ip->ip_dst; + + switch (key->ip_proto) { + case IPPROTO_TCP: + case IPPROTO_UDP: + case IPPROTO_DCCP: + case IPPROTO_ESP: + case IPPROTO_SCTP: + case IPPROTO_UDPLITE: + tmp_ports = *(uint32_t *)(pkt->transport_layer); + key->src_port = tmp_ports & 0xffff; + key->dst_port = tmp_ports >> 16; + break; + case IPPROTO_AH: + tmp_ports = *(uint32_t *)(pkt->transport_layer + 4); + key->src_port = tmp_ports & 0xffff; + key->dst_port = tmp_ports >> 16; + break; + default: + break; + } + + return 0; +} + +static Packet *packet_new(COLOProxyState *s, void *data, + int size, ConnectionKey *key, NetClientState *sender) +{ + Packet *pkt = g_slice_new(Packet); + + pkt->data = data; + pkt->size = size; + pkt->s = s; + pkt->sender = sender; + + if (parse_packet_early(pkt, key)) { + packet_destroy(pkt, NULL); + pkt = NULL; + } + + return pkt; +} + +static void packet_destroy(void *opaque, void *user_data) +{ + Packet *pkt = opaque; + g_free(pkt->data); + g_slice_free(Packet, pkt); +} + +/* if not found, creata a new connection and add to hash table */ +static Connection *colo_proxy_get_conn(COLOProxyState *s, + ConnectionKey *key) +{ + /* FIXME: protect colo_conn_hash */ + Connection *conn = g_hash_table_lookup(colo_conn_hash, key); + + if (conn == NULL) { + ConnectionKey *new_key = g_malloc(sizeof(*key)); + + conn = connection_new(key); + memcpy(new_key, key, sizeof(*key)); + + s->hashtable_size++; + if (s->hashtable_size > hashtable_max_size) { + trace_colo_proxy("colo proxy connection hashtable full, clear it"); + clear_connection_hashtable(s); + } else { + g_hash_table_insert(colo_conn_hash, new_key, conn); + } + } + + return conn; +} + static ssize_t colo_proxy_enqueue_primary_packet(NetFilterState *nf, NetClientState *sender, unsigned flags,