From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34743) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aYOlA-0002Xc-6n for qemu-devel@nongnu.org; Tue, 23 Feb 2016 21:01:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aYOl6-00043K-VK for qemu-devel@nongnu.org; Tue, 23 Feb 2016 21:01:00 -0500 Received: from [59.151.112.132] (port=31966 helo=heian.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aYOl3-00041X-Lg for qemu-devel@nongnu.org; Tue, 23 Feb 2016 21:00:56 -0500 References: <1450780978-19123-1-git-send-email-zhangchen.fnst@cn.fujitsu.com> <1450780978-19123-9-git-send-email-zhangchen.fnst@cn.fujitsu.com> <20160219200427.GL2412@work-vm> <56CAAD91.7040602@cn.fujitsu.com> <20160223175824.GA2305@work-vm> From: Zhang Chen Message-ID: <56CD0EE4.3040106@cn.fujitsu.com> Date: Wed, 24 Feb 2016 10:01:08 +0800 MIME-Version: 1.0 In-Reply-To: <20160223175824.GA2305@work-vm> Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [RFC PATCH v2 08/10] net/colo-proxy: Handle packet and connection List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Dr. David Alan Gilbert" Cc: zhanghailiang , Li Zhijian , Gui jianfeng , Jason Wang , "eddie.dong" , qemu devel , Huang peng , Gong lei , Stefan Hajnoczi , jan.kiszka@siemens.com, Yang Hongyang On 02/24/2016 01:58 AM, Dr. David Alan Gilbert wrote: > * Zhang Chen (zhangchen.fnst@cn.fujitsu.com) wrote: >> >> On 02/20/2016 04:04 AM, Dr. David Alan Gilbert wrote: >>> * Zhang Chen (zhangchen.fnst@cn.fujitsu.com) wrote: >>>> 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); >>> Be careful about these lists and which threads access them; >>> I found I could occasionally trigger a seg fault as two >>> threads tried to manipulate them at once; I just put a 'list_lock' >>> in the connection, which seems to fix it, but I might have to be >>> more careful with deadlocks. >> Thanks for your work to colo. >> and where can I see your code for colo-proxy? >> maybe I need it to make my code better. > Here is my latest version; it seems to just about work; but very > much still working on it: > > https://github.com/orbitfp7/qemu/tree/orbit-wp4-colo-jan16 > with the wp4-colo-rdma-2016-02-23 tag. > > Dave Thanks for your work to colo~~ zhangchen >>>> + 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; >>> These fields are not byteswapped; it makes it very confusing >>> when printing them for debug; I added htons around every >>> reading of the ports from the packets. >>> >>> Dave >> I will fix it in colo-compare module. >> >> Thanks >> zhangchen >> >>>> + 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, >>>> -- >>>> 1.9.1 >>>> >>>> >>>> >>>> >>> -- >>> Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK >>> >>> >>> . >>> >> -- >> Thanks >> zhangchen >> >> >> > -- > Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK > > > . > -- Thanks zhangchen