From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51293) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aXkBA-0000vF-EC for qemu-devel@nongnu.org; Mon, 22 Feb 2016 01:41:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aXkB7-0008J1-7p for qemu-devel@nongnu.org; Mon, 22 Feb 2016 01:41:08 -0500 Received: from [59.151.112.132] (port=42925 helo=heian.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aXkB6-0008I5-2F for qemu-devel@nongnu.org; Mon, 22 Feb 2016 01:41:05 -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> From: Zhang Chen Message-ID: <56CAAD91.7040602@cn.fujitsu.com> Date: Mon, 22 Feb 2016 14:41:21 +0800 MIME-Version: 1.0 In-Reply-To: <20160219200427.GL2412@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/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. > >> + 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