* Zhang Chen (zhangchen.f...@cn.fujitsu.com) wrote: > > > On 02/20/2016 04:04 AM, Dr. David Alan Gilbert wrote: > >* Zhang Chen (zhangchen.f...@cn.fujitsu.com) wrote: > >>From: zhangchen <zhangchen.f...@cn.fujitsu.com> > >> > >>In here we will handle ip packet and connection > >> > >>Signed-off-by: zhangchen <zhangchen.f...@cn.fujitsu.com> > >>Signed-off-by: zhanghailiang <zhang.zhanghaili...@huawei.com> > >>--- > >> 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 > > > > >>+ 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 / dgilb...@redhat.com / Manchester, UK > > > > > >. > > > > -- > Thanks > zhangchen > > > -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK