All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Wang <jasowang@redhat.com>
To: peter.maydell@linaro.org
Cc: qemu-devel@nongnu.org, Zhang Chen <zhangchen.fnst@cn.fujitsu.com>,
	Li Zhijian <lizhijian@cn.fujitsu.com>,
	Wen Congyang <wency@cn.fujitsu.com>,
	Jason Wang <jasowang@redhat.com>
Subject: [Qemu-devel] [PULL 05/27] net/colo.c: add colo.c to define and handle packet
Date: Mon, 26 Sep 2016 16:59:13 +0800	[thread overview]
Message-ID: <1474880375-22946-6-git-send-email-jasowang@redhat.com> (raw)
In-Reply-To: <1474880375-22946-1-git-send-email-jasowang@redhat.com>

From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>

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 <zhangchen.fnst@cn.fujitsu.com>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 net/Makefile.objs  |   1 +
 net/colo-compare.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 net/colo.c         |  86 ++++++++++++++++++++++++++++++++++++++++
 net/colo.h         |  37 +++++++++++++++++
 trace-events       |   6 +++
 5 files changed, 240 insertions(+), 4 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 += filter.o
 common-obj-y += filter-buffer.o
 common-obj-y += filter-mirror.o
 common-obj-y += colo-compare.o
+common-obj-y += colo.o
diff --git a/net/colo-compare.c b/net/colo-compare.c
index dc5f70c..cea9b27 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -14,6 +14,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu/error-report.h"
+#include "trace.h"
 #include "qemu-common.h"
 #include "qapi/qmp/qerror.h"
 #include "qapi/error.h"
@@ -26,13 +27,34 @@
 #include "sysemu/char.h"
 #include "qemu/sockets.h"
 #include "qapi-visit.h"
+#include "net/colo.h"
 
 #define TYPE_COLO_COMPARE "colo-compare"
 #define COLO_COMPARE(obj) \
     OBJECT_CHECK(CompareState, (obj), TYPE_COLO_COMPARE)
 
-#define COMPARE_READ_LEN_MAX NET_BUFSIZE
-
+/*
+  + 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;
 
@@ -44,6 +66,9 @@ typedef struct CompareState {
     CharDriverState *chr_out;
     SocketReadState pri_rs;
     SocketReadState sec_rs;
+
+    /* hashtable to save connection */
+    GHashTable *connection_track_table;
 } CompareState;
 
 typedef struct CompareClass {
@@ -54,6 +79,76 @@ typedef struct CompareChardevProps {
     bool is_socket;
 } CompareChardevProps;
 
+enum {
+    PRIMARY_IN = 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 = NULL;
+
+    if (mode == PRIMARY_IN) {
+        pkt = packet_new(s->pri_rs.buf, s->pri_rs.packet_len);
+    } else {
+        pkt = packet_new(s->sec_rs.buf, s->sec_rs.packet_len);
+    }
+
+    if (parse_packet_early(pkt)) {
+        packet_destroy(pkt, NULL);
+        pkt = 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 = 0;
+    uint32_t len = htonl(size);
+
+    if (!size) {
+        return 0;
+    }
+
+    ret = qemu_chr_fe_write_all(out, (uint8_t *)&len, sizeof(len));
+    if (ret != sizeof(len)) {
+        goto err;
+    }
+
+    ret = qemu_chr_fe_write_all(out, (uint8_t *)buf, size);
+    if (ret != size) {
+        goto err;
+    }
+
+    return 0;
+
+err:
+    return ret < 0 ? ret : -EIO;
+}
+
 static char *compare_get_pri_indev(Object *obj, Error **errp)
 {
     CompareState *s = COLO_COMPARE(obj);
@@ -101,12 +196,21 @@ static void compare_set_outdev(Object *obj, const char *value, Error **errp)
 
 static void compare_pri_rs_finalize(SocketReadState *pri_rs)
 {
-    /* if packet_enqueue pri pkt failed we will send unsupported packet */
+    CompareState *s = 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);
+    }
 }
 
 static void compare_sec_rs_finalize(SocketReadState *sec_rs)
 {
-    /* if packet_enqueue sec pkt failed we will notify trace */
+    CompareState *s = container_of(sec_rs, CompareState, sec_rs);
+
+    if (packet_enqueue(s, SECONDARY_IN)) {
+        trace_colo_compare_main("secondary: unsupported packet in");
+    }
 }
 
 static int compare_chardev_opts(void *opaque,
@@ -204,6 +308,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);
 
+    /* use g_hash_table_new_full() to new a hashtable */
+
     return;
 }
 
diff --git a/net/colo.c b/net/colo.c
new file mode 100644
index 0000000..8582175
--- /dev/null
+++ b/net/colo.c
@@ -0,0 +1,86 @@
+/*
+ * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (COLO)
+ * (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 <zhangchen.fnst@cn.fujitsu.com>
+ *
+ * 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 "trace.h"
+#include "net/colo.h"
+
+int parse_packet_early(Packet *pkt)
+{
+    int network_length;
+    static const uint8_t vlan[] = {0x81, 0x00};
+    uint8_t *data = pkt->data;
+    uint16_t l3_proto;
+    ssize_t l2hdr_len = eth_get_l2_hdr_length(data);
+
+    if (pkt->size < ETH_HLEN) {
+        trace_colo_proxy_main("pkt->size < ETH_HLEN");
+        return 1;
+    }
+
+    /*
+     * TODO: support vlan.
+     */
+    if (!memcmp(&data[12], vlan, sizeof(vlan))) {
+        trace_colo_proxy_main("COLO-proxy don't support vlan");
+        return 1;
+    }
+
+    pkt->network_header = data + l2hdr_len;
+
+    const struct iovec l2vec = {
+        .iov_base = (void *) data,
+        .iov_len = l2hdr_len
+    };
+    l3_proto = eth_get_l3_proto(&l2vec, 1, l2hdr_len);
+
+    if (l3_proto != ETH_P_IP) {
+        return 1;
+    }
+
+    network_length = pkt->ip->ip_hl * 4;
+    if (pkt->size < l2hdr_len + network_length) {
+        trace_colo_proxy_main("pkt->size < network_header + network_length");
+        return 1;
+    }
+    pkt->transport_header = pkt->network_header + network_length;
+
+    return 0;
+}
+
+Packet *packet_new(const void *data, int size)
+{
+    Packet *pkt = g_slice_new(Packet);
+
+    pkt->data = g_memdup(data, size);
+    pkt->size = size;
+
+    return pkt;
+}
+
+void packet_destroy(void *opaque, void *user_data)
+{
+    Packet *pkt = 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..e211eda
--- /dev/null
+++ b/net/colo.h
@@ -0,0 +1,37 @@
+/*
+ * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (COLO)
+ * (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 <zhangchen.fnst@cn.fujitsu.com>
+ *
+ * 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_PROXY_H
+#define QEMU_COLO_PROXY_H
+
+#include "slirp/slirp.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_PROXY_H */
diff --git a/trace-events b/trace-events
index 8d59631..9b4186f 100644
--- a/trace-events
+++ b/trace-events
@@ -139,6 +139,12 @@ memory_region_subpage_write(int cpu_index, void *mr, uint64_t offset, uint64_t v
 memory_region_tb_read(int cpu_index, uint64_t addr, uint64_t value, unsigned size) "cpu %d addr %#"PRIx64" value %#"PRIx64" size %u"
 memory_region_tb_write(int cpu_index, uint64_t addr, uint64_t value, unsigned size) "cpu %d addr %#"PRIx64" value %#"PRIx64" size %u"
 
+# net/colo.c
+colo_proxy_main(const char *chr) ": %s"
+
+# net/colo-compare.c
+colo_compare_main(const char *chr) ": %s"
+
 ### Guest events, keep at bottom
 
 # @vaddr: Access' virtual address.
-- 
2.7.4

  parent reply	other threads:[~2016-09-26  9:00 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-26  8:59 [Qemu-devel] [PULL 00/27] Net patches Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 01/27] virtio-net: allow increasing rx queue size Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 02/27] net: hmp_host_net_remove: Del the -net option of the removed host_net Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 03/27] qemu-char: Add qemu_chr_add_handlers_full() for GMaincontext Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 04/27] colo-compare: introduce colo compare initialization Jason Wang
2016-09-26  8:59 ` Jason Wang [this message]
2016-09-26  8:59 ` [Qemu-devel] [PULL 06/27] Jhash: add linux kernel jhashtable in qemu Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 07/27] colo-compare: track connection and enqueue packet Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 08/27] colo-compare: introduce packet comparison thread Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 09/27] colo-compare: add TCP, UDP, ICMP packet comparison Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 10/27] filter-rewriter: introduce filter-rewriter initialization Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 11/27] filter-rewriter: track connection and parse packet Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 12/27] filter-rewriter: rewrite tcp packet to keep secondary connection Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 13/27] MAINTAINERS: add maintainer for COLO-proxy Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 14/27] docs: Add documentation " Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 15/27] e1000: fix buliding complaint Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 16/27] tap: Allow specifying a bridge Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 17/27] net: limit allocation in nc_sendv_compat Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 18/27] e1000e: Flush all receive queues on receive enable Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 19/27] e1000e: Flush receive queues on link up Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 20/27] e1000e: Fix CTRL_EXT.EIAME behavior Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 21/27] e1000e: Fix PBACLR implementation Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 22/27] e1000e: Fix OTHER interrupts processing for MSI-X Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 23/27] e1000e: Fix spurious RX TCP ACK interrupts Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 24/27] e1000e: Fix EIAC register implementation Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 25/27] net: mcf: limit buffer descriptor count Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 26/27] mcf_fec: fix error in qemu_send_packet argument Jason Wang
2016-09-26  8:59 ` [Qemu-devel] [PULL 27/27] imx_fec: " Jason Wang
2016-09-26 21:04 ` [Qemu-devel] [PULL 00/27] Net patches Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1474880375-22946-6-git-send-email-jasowang@redhat.com \
    --to=jasowang@redhat.com \
    --cc=lizhijian@cn.fujitsu.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=wency@cn.fujitsu.com \
    --cc=zhangchen.fnst@cn.fujitsu.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.