From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43488) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bf0VU-0000Li-3D for qemu-devel@nongnu.org; Wed, 31 Aug 2016 04:04:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bf0VO-0008Hw-Bk for qemu-devel@nongnu.org; Wed, 31 Aug 2016 04:04:23 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40982) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bf0VI-0008GY-KA for qemu-devel@nongnu.org; Wed, 31 Aug 2016 04:04:18 -0400 References: <1471421428-26379-1-git-send-email-zhangchen.fnst@cn.fujitsu.com> <1471421428-26379-4-git-send-email-zhangchen.fnst@cn.fujitsu.com> From: Jason Wang Message-ID: <82d42d57-ca79-9e63-2dea-456e9f98992f@redhat.com> Date: Wed, 31 Aug 2016 16:04:03 +0800 MIME-Version: 1.0 In-Reply-To: <1471421428-26379-4-git-send-email-zhangchen.fnst@cn.fujitsu.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH V12 03/10] net/colo.c: add colo.c to define and handle packet List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Zhang Chen , qemu devel Cc: Li Zhijian , "eddie . dong" , "Dr . David Alan Gilbert" , zhanghailiang On 2016=E5=B9=B408=E6=9C=8817=E6=97=A5 16:10, Zhang Chen wrote: > The net/colo.c is used by colo-compare and filter-rewriter. > this can share common data structure like net packet, > and other functions. > > Signed-off-by: Zhang Chen > Signed-off-by: Li Zhijian > Signed-off-by: Wen Congyang > --- > net/Makefile.objs | 1 + > net/colo-compare.c | 113 ++++++++++++++++++++++++++++++++++++++++++++= ++++++++- > net/colo.c | 70 +++++++++++++++++++++++++++++++++ > net/colo.h | 38 ++++++++++++++++++ > trace-events | 3 ++ > 5 files changed, 223 insertions(+), 2 deletions(-) > create mode 100644 net/colo.c > create mode 100644 net/colo.h > > diff --git a/net/Makefile.objs b/net/Makefile.objs > index ba92f73..beb504b 100644 > --- a/net/Makefile.objs > +++ b/net/Makefile.objs > @@ -17,3 +17,4 @@ common-obj-y +=3D filter.o > common-obj-y +=3D filter-buffer.o > common-obj-y +=3D filter-mirror.o > common-obj-y +=3D colo-compare.o > +common-obj-y +=3D colo.o > diff --git a/net/colo-compare.c b/net/colo-compare.c > index cdc3e0e..d9e4459 100644 > --- a/net/colo-compare.c > +++ b/net/colo-compare.c > @@ -27,13 +27,38 @@ > #include "sysemu/char.h" > #include "qemu/sockets.h" > #include "qapi-visit.h" > +#include "net/colo.h" > +#include "trace.h" > =20 > #define TYPE_COLO_COMPARE "colo-compare" > #define COLO_COMPARE(obj) \ > OBJECT_CHECK(CompareState, (obj), TYPE_COLO_COMPARE) > =20 > #define COMPARE_READ_LEN_MAX NET_BUFSIZE > +#define MAX_QUEUE_SIZE 1024 > =20 > +/* > + + 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 + > + +--------+ +--------+ +--------+ +--------+ > +*/ > typedef struct CompareState { > Object parent; > =20 > @@ -46,6 +71,9 @@ typedef struct CompareState { > QTAILQ_ENTRY(CompareState) next; > SocketReadState pri_rs; > SocketReadState sec_rs; > + > + /* hashtable to save connection */ > + GHashTable *connection_track_table; > } CompareState; > =20 > typedef struct CompareClass { > @@ -57,6 +85,76 @@ typedef struct CompareChardevProps { > bool is_unix; > } CompareChardevProps; > =20 > +enum { > + PRIMARY_IN =3D 0, > + SECONDARY_IN, > +}; > + > +static int compare_chr_send(CharDriverState *out, > + const uint8_t *buf, > + uint32_t size); > + > +/* > + * Return 0 on success, if return -1 means the pkt > + * is unsupported(arp and ipv6) and will be sent later > + */ > +static int packet_enqueue(CompareState *s, int mode) > +{ > + Packet *pkt =3D NULL; > + > + if (mode =3D=3D PRIMARY_IN) { > + pkt =3D packet_new(s->pri_rs.buf, s->pri_rs.packet_len); > + } else { > + pkt =3D packet_new(s->sec_rs.buf, s->sec_rs.packet_len); > + } > + > + if (parse_packet_early(pkt)) { > + packet_destroy(pkt, NULL); > + pkt =3D NULL; > + return -1; > + } > + /* TODO: get connection key from pkt */ > + > + /* > + * TODO: use connection key get conn from > + * connection_track_table > + */ > + > + /* > + * TODO: insert pkt to it's conn->primary_list > + * or conn->secondary_list > + */ > + > + return 0; > +} > + > +static int compare_chr_send(CharDriverState *out, > + const uint8_t *buf, > + uint32_t size) > +{ > + int ret =3D 0; > + uint32_t len =3D htonl(size); > + > + if (!size) { > + return 0; > + } > + > + ret =3D qemu_chr_fe_write_all(out, (uint8_t *)&len, sizeof(len)); > + if (ret !=3D sizeof(len)) { > + goto err; > + } > + > + ret =3D qemu_chr_fe_write_all(out, (uint8_t *)buf, size); > + if (ret !=3D size) { > + goto err; > + } > + > + return 0; > + > +err: > + return ret < 0 ? ret : -EIO; > +} > + > static char *compare_get_pri_indev(Object *obj, Error **errp) > { > CompareState *s =3D COLO_COMPARE(obj); > @@ -104,12 +202,21 @@ static void compare_set_outdev(Object *obj, const= char *value, Error **errp) > =20 > static void compare_pri_rs_finalize(SocketReadState *pri_rs) > { > - /* if packet_enqueue pri pkt failed we will send unsupported packe= t */ > + CompareState *s =3D container_of(pri_rs, CompareState, pri_rs); > + > + if (packet_enqueue(s, PRIMARY_IN)) { > + trace_colo_compare_main("primary: unsupported packet in"); > + compare_chr_send(s->chr_out, pri_rs->buf, pri_rs->packet_len); > + } > } > =20 > static void compare_sec_rs_finalize(SocketReadState *sec_rs) > { > - /* if packet_enqueue sec pkt failed we will notify trace */ > + CompareState *s =3D container_of(sec_rs, CompareState, sec_rs); > + > + if (packet_enqueue(s, SECONDARY_IN)) { > + trace_colo_compare_main("secondary: unsupported packet in"); > + } > } > =20 > static int compare_chardev_opts(void *opaque, > @@ -218,6 +325,8 @@ static void colo_compare_complete(UserCreatable *uc= , Error **errp) > net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize); > net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize); > =20 > + /* use g_hash_table_new_full() to new a hashtable */ > + > return; > } > =20 > diff --git a/net/colo.c b/net/colo.c > new file mode 100644 > index 0000000..4daedd4 > --- /dev/null > +++ b/net/colo.c > @@ -0,0 +1,70 @@ > +/* > + * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (C= OLO) > + * (a.k.a. Fault Tolerance or Continuous Replication) > + * > + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. > + * Copyright (c) 2016 FUJITSU LIMITED > + * Copyright (c) 2016 Intel Corporation > + * > + * Author: Zhang Chen > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or > + * later. See the COPYING file in the top-level directory. > + */ > + > +#include "qemu/osdep.h" > +#include "qemu/error-report.h" > +#include "net/colo.h" > + > +int parse_packet_early(Packet *pkt) > +{ > + int network_length; > + uint8_t *data =3D pkt->data; > + uint16_t l3_proto; > + ssize_t l2hdr_len =3D eth_get_l2_hdr_length(data); > + > + if (pkt->size < ETH_HLEN) { > + error_report("pkt->size < ETH_HLEN"); Guest triggered, better not use error_report() here. > + return 1; > + } > + pkt->network_header =3D data + ETH_HLEN; Need use l2hdr_len here instead of ETH_HLEP? > + l3_proto =3D eth_get_l3_proto(data, l2hdr_len); > + if (l3_proto !=3D ETH_P_IP) { > + return 1; > + } > + > + network_length =3D pkt->ip->ip_hl * 4; > + if (pkt->size < ETH_HLEN + network_length) { Ditto. > + error_report("pkt->size < network_header + network_length"); And better not use error_report() since it was triggered by guest. > + return 1; > + } > + pkt->transport_header =3D pkt->network_header + network_length; > + > + return 0; > +} > + > +Packet *packet_new(const void *data, int size) > +{ > + Packet *pkt =3D g_slice_new(Packet); > + > + pkt->data =3D g_memdup(data, size); > + pkt->size =3D size; > + > + return pkt; > +} > + > +void packet_destroy(void *opaque, void *user_data) > +{ > + Packet *pkt =3D opaque; > + > + g_free(pkt->data); > + g_slice_free(Packet, pkt); > +} > + > +/* > + * Clear hashtable, stop this hash growing really huge > + */ > +void connection_hashtable_reset(GHashTable *connection_track_table) > +{ > + g_hash_table_remove_all(connection_track_table); > +} > diff --git a/net/colo.h b/net/colo.h > new file mode 100644 > index 0000000..8559f28 > --- /dev/null > +++ b/net/colo.h > @@ -0,0 +1,38 @@ > +/* > + * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (C= OLO) > + * (a.k.a. Fault Tolerance or Continuous Replication) > + * > + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. > + * Copyright (c) 2016 FUJITSU LIMITED > + * Copyright (c) 2016 Intel Corporation > + * > + * Author: Zhang Chen > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or > + * later. See the COPYING file in the top-level directory. > + */ > + > +#ifndef QEMU_COLO_BASE_H > +#define QEMU_COLO_BASE_H > + > +#include "slirp/slirp.h" > +#include "qemu/jhash.h" > + > +#define HASHTABLE_MAX_SIZE 16384 > + > +typedef struct Packet { > + void *data; > + union { > + uint8_t *network_header; > + struct ip *ip; > + }; > + uint8_t *transport_header; > + int size; > +} Packet; > + > +int parse_packet_early(Packet *pkt); > +void connection_hashtable_reset(GHashTable *connection_track_table); > +Packet *packet_new(const void *data, int size); > +void packet_destroy(void *opaque, void *user_data); > + > +#endif /* QEMU_COLO_BASE_H */ > diff --git a/trace-events b/trace-events > index ca7211b..703de1a 100644 > --- a/trace-events > +++ b/trace-events > @@ -1916,3 +1916,6 @@ aspeed_vic_update_fiq(int flags) "Raising FIQ: %d= " > aspeed_vic_update_irq(int flags) "Raising IRQ: %d" > aspeed_vic_read(uint64_t offset, unsigned size, uint32_t value) "From= 0x%" PRIx64 " of size %u: 0x%" PRIx32 > aspeed_vic_write(uint64_t offset, unsigned size, uint32_t data) "To 0= x%" PRIx64 " of size %u: 0x%" PRIx32 > + > +# net/colo-compare.c > +colo_compare_main(const char *chr) ": %s"