All of lore.kernel.org
 help / color / mirror / Atom feed
* [PULL 0/6] COLO-Proxy patches for 2021-06-25
@ 2021-06-25  3:11 Zhang Chen
  2021-06-25  3:11 ` [PULL 1/6] qapi/net: Add IPFlowSpec and QMP command for filter passthrough Zhang Chen
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Zhang Chen @ 2021-06-25  3:11 UTC (permalink / raw)
  To: Jason Wang
  Cc: Lukas Straub, Daniel P. Berrangé,
	Li Zhijian, qemu-dev, Markus Armbruster, Zhang Chen,
	Gerd Hoffmann, Eric Blake, Dr. David Alan Gilbert

Hi Jason, Please help to queue COLO-proxy patches to net branch.

Thanks
Chen

The following changes since commit b22726abdfa54592d6ad88f65b0297c0e8b363e2:

  Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-6.1-pull-request' into staging (2021-06-22 16:07:53 +0100)

are available in the Git repository at:

  https://github.com/zhangckid/qemu.git master-colo-21jun25-pull-request

for you to fetch changes up to 5375645efde8892b05a8b7c7a088b63a7d1fd5aa:

  net/net.c: Add handler for passthrough filter command (2021-06-23 17:22:40 +0800)

----------------------------------------------------------------

This series add passthrough support frame to object with network
processing function. The first object is colo-compare.

----------------------------------------------------------------

Zhang Chen (6):
  qapi/net: Add IPFlowSpec and QMP command for filter passthrough
  util/qemu-sockets.c: Add inet_parse_base to handle
    InetSocketAddressBase
  hmp-commands: Add new HMP command for filter passthrough
  net/colo-compare: Move data structure and define to .h file.
  net/colo-compare: Add passthrough list to CompareState
  net/net.c: Add handler for passthrough filter command

 hmp-commands.hx        |  26 ++++++
 include/monitor/hmp.h  |   2 +
 include/qemu/sockets.h |   1 +
 monitor/hmp-cmds.c     |  76 +++++++++++++++
 net/colo-compare.c     | 160 ++++++++++----------------------
 net/colo-compare.h     |  98 ++++++++++++++++++++
 net/net.c              | 205 +++++++++++++++++++++++++++++++++++++++++
 qapi/net.json          |  78 ++++++++++++++++
 util/qemu-sockets.c    |  14 +++
 9 files changed, 551 insertions(+), 109 deletions(-)

-- 
2.25.1



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PULL 1/6] qapi/net: Add IPFlowSpec and QMP command for filter passthrough
  2021-06-25  3:11 [PULL 0/6] COLO-Proxy patches for 2021-06-25 Zhang Chen
@ 2021-06-25  3:11 ` Zhang Chen
  2021-06-25  3:11 ` [PULL 2/6] util/qemu-sockets.c: Add inet_parse_base to handle InetSocketAddressBase Zhang Chen
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Zhang Chen @ 2021-06-25  3:11 UTC (permalink / raw)
  To: Jason Wang
  Cc: Lukas Straub, Daniel P. Berrangé,
	Li Zhijian, qemu-dev, Markus Armbruster, Zhang Chen,
	Gerd Hoffmann, Eric Blake, Dr. David Alan Gilbert

Since the real user scenario does not need to monitor all traffic.
Add passthrough-filter-add and passthrough-filter-del to maintain
a network passthrough list in object with network packet processing
function. Add IPFlowSpec struct for all QMP commands.
Most the fields of IPFlowSpec are optional,except object-name.

Signed-off-by: Zhang Chen <chen.zhang@intel.com>
---
 net/net.c     | 10 +++++++
 qapi/net.json | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 88 insertions(+)

diff --git a/net/net.c b/net/net.c
index 76bbb7c31b..00f2be7a58 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1195,6 +1195,16 @@ void qmp_netdev_del(const char *id, Error **errp)
     }
 }
 
+void qmp_passthrough_filter_add(IPFlowSpec *spec, Error **errp)
+{
+    /* TODO implement setup passthrough rule */
+}
+
+void qmp_passthrough_filter_del(IPFlowSpec *spec, Error **errp)
+{
+    /* TODO implement delete passthrough rule */
+}
+
 static void netfilter_print_info(Monitor *mon, NetFilterState *nf)
 {
     char *str;
diff --git a/qapi/net.json b/qapi/net.json
index 7fab2e7cd8..bfe38faab5 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -7,6 +7,7 @@
 ##
 
 { 'include': 'common.json' }
+{ 'include': 'sockets.json' }
 
 ##
 # @set_link:
@@ -696,3 +697,80 @@
 ##
 { 'event': 'FAILOVER_NEGOTIATED',
   'data': {'device-id': 'str'} }
+
+##
+# @IPFlowSpec:
+#
+# IP flow specification.
+#
+# @protocol: Transport layer protocol like TCP/UDP, etc. The protocol is the
+#            string instead of enum, because it can be passed to getprotobyname(3)
+#            and avoid duplication with /etc/protocols.
+#
+# @object-name: The @object-name means a qemu object with network packet
+#               processing function, for example colo-compare, filtr-redirector
+#               filtr-mirror, etc. VM can running with multi network packet
+#               processing function objects. They can control different network
+#               data paths from netdev or chardev. So it needs the object-name
+#               to set the effective module.
+#
+# @source: Source address and port.
+#
+# @destination: Destination address and port.
+#
+# Since: 6.1
+##
+{ 'struct': 'IPFlowSpec',
+  'data': { '*protocol': 'str', 'object-name': 'str',
+    '*source': 'InetSocketAddressBase',
+    '*destination': 'InetSocketAddressBase' } }
+
+##
+# @passthrough-filter-add:
+#
+# Add passthrough entry IPFlowSpec to a qemu object with network packet
+# processing function, for example filtr-mirror, COLO-compare, etc.
+# The object-name is necessary. The protocol and source/destination IP and
+# source/destination ports are optional. if only inputs part of the
+# information, it will match all traffic.
+#
+# Returns: Nothing on success
+#
+# Since: 6.1
+#
+# Example:
+#
+# -> { "execute": "passthrough-filter-add",
+#      "arguments": { "protocol": "tcp", "object-name": "object0",
+#      "source": {"host": "192.168.1.1", "port": "1234"},
+#      "destination": {"host": "192.168.1.2", "port": "4321"} } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'passthrough-filter-add', 'boxed': true,
+     'data': 'IPFlowSpec' }
+
+##
+# @passthrough-filter-del:
+#
+# Delete passthrough entry IPFlowSpec to a qemu object with network packet
+# processing function, for example filtr-mirror, COLO-compare, etc.
+# The object-name is necessary. The protocol and source/destination IP and
+# source/destination ports are optional. if only inputs part of the
+# information, only the exact same rule will be deleted.
+#
+# Returns: Nothing on success
+#
+# Since: 6.1
+#
+# Example:
+#
+# -> { "execute": "passthrough-filter-del",
+#      "arguments": { "protocol": "tcp", "object-name": "object0",
+#      "source": {"host": "192.168.1.1", "port": "1234"},
+#      "destination": {"host": "192.168.1.2", "port": "4321"} } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'passthrough-filter-del', 'boxed': true,
+     'data': 'IPFlowSpec' }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PULL 2/6] util/qemu-sockets.c: Add inet_parse_base to handle InetSocketAddressBase
  2021-06-25  3:11 [PULL 0/6] COLO-Proxy patches for 2021-06-25 Zhang Chen
  2021-06-25  3:11 ` [PULL 1/6] qapi/net: Add IPFlowSpec and QMP command for filter passthrough Zhang Chen
@ 2021-06-25  3:11 ` Zhang Chen
  2021-06-25  3:11 ` [PULL 3/6] hmp-commands: Add new HMP command for filter passthrough Zhang Chen
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Zhang Chen @ 2021-06-25  3:11 UTC (permalink / raw)
  To: Jason Wang
  Cc: Lukas Straub, Daniel P. Berrangé,
	Li Zhijian, qemu-dev, Markus Armbruster, Zhang Chen,
	Gerd Hoffmann, Eric Blake, Dr. David Alan Gilbert

No need to carry the flag all the time in many scenarios.

Signed-off-by: Zhang Chen <chen.zhang@intel.com>
---
 include/qemu/sockets.h |  1 +
 util/qemu-sockets.c    | 14 ++++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index 0c34bf2398..3a0f8fa8f2 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -32,6 +32,7 @@ int socket_set_fast_reuse(int fd);
 int inet_ai_family_from_address(InetSocketAddress *addr,
                                 Error **errp);
 int inet_parse(InetSocketAddress *addr, const char *str, Error **errp);
+int inet_parse_base(InetSocketAddressBase *addr, const char *str, Error **errp);
 int inet_connect(const char *str, Error **errp);
 int inet_connect_saddr(InetSocketAddress *saddr, Error **errp);
 
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 080a240b74..cd7fa0b884 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -713,6 +713,20 @@ int inet_parse(InetSocketAddress *addr, const char *str, Error **errp)
     return 0;
 }
 
+int inet_parse_base(InetSocketAddressBase *base, const char *str, Error **errp)
+{
+    InetSocketAddress *addr;
+    int ret = 0;
+
+    addr = g_new0(InetSocketAddress, 1);
+    ret = inet_parse(addr, str, errp);
+
+    base->host = addr->host;
+    base->port = addr->port;
+
+    g_free(addr);
+    return ret;
+}
 
 /**
  * Create a blocking socket and connect it to an address.
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PULL 3/6] hmp-commands: Add new HMP command for filter passthrough
  2021-06-25  3:11 [PULL 0/6] COLO-Proxy patches for 2021-06-25 Zhang Chen
  2021-06-25  3:11 ` [PULL 1/6] qapi/net: Add IPFlowSpec and QMP command for filter passthrough Zhang Chen
  2021-06-25  3:11 ` [PULL 2/6] util/qemu-sockets.c: Add inet_parse_base to handle InetSocketAddressBase Zhang Chen
@ 2021-06-25  3:11 ` Zhang Chen
  2021-06-30 10:39   ` Dr. David Alan Gilbert
  2021-06-25  3:11 ` [PULL 4/6] net/colo-compare: Move data structure and define to .h file Zhang Chen
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 9+ messages in thread
From: Zhang Chen @ 2021-06-25  3:11 UTC (permalink / raw)
  To: Jason Wang
  Cc: Lukas Straub, Daniel P. Berrangé,
	Li Zhijian, qemu-dev, Markus Armbruster, Zhang Chen,
	Gerd Hoffmann, Eric Blake, Dr. David Alan Gilbert

Add hmp_passthrough_filter_add and hmp_passthrough_filter_del make user
can maintain object network passthrough list in human monitor

Signed-off-by: Zhang Chen <chen.zhang@intel.com>
---
 hmp-commands.hx       | 26 +++++++++++++++
 include/monitor/hmp.h |  2 ++
 monitor/hmp-cmds.c    | 76 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 104 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 8e45bce2cd..426a7d6cda 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1292,6 +1292,32 @@ SRST
   Remove host network device.
 ERST
 
+    {
+        .name       = "passthrough_filter_add",
+        .args_type  = "protocol:s?,object-name:s,src:s?,dst:s?",
+        .params     = "[protocol] object-name [src] [dst]",
+        .help       = "Add network passthrough rule to object passthrough list",
+        .cmd        = hmp_passthrough_filter_add,
+    },
+
+SRST
+``passthrough_filter_add``
+  Add network stream to object passthrough list.
+ERST
+
+    {
+        .name       = "passthrough_filter_del",
+        .args_type  = "protocol:s?,object-name:s,src:s?,dst:s?",
+        .params     = "[protocol] object-name [src] [dst]",
+        .help       = "Delete network passthrough rule from object passthrough list",
+        .cmd        = hmp_passthrough_filter_del,
+    },
+
+SRST
+``passthrough_filter_del``
+  Delete network stream from object passthrough list.
+ERST
+
     {
         .name       = "object_add",
         .args_type  = "object:S",
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index 3baa1058e2..ba6987e552 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -77,6 +77,8 @@ void hmp_device_del(Monitor *mon, const QDict *qdict);
 void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict);
 void hmp_netdev_add(Monitor *mon, const QDict *qdict);
 void hmp_netdev_del(Monitor *mon, const QDict *qdict);
+void hmp_passthrough_filter_add(Monitor *mon, const QDict *qdict);
+void hmp_passthrough_filter_del(Monitor *mon, const QDict *qdict);
 void hmp_getfd(Monitor *mon, const QDict *qdict);
 void hmp_closefd(Monitor *mon, const QDict *qdict);
 void hmp_sendkey(Monitor *mon, const QDict *qdict);
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 0942027208..26ff316c93 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -1638,6 +1638,82 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
+void hmp_passthrough_filter_add(Monitor *mon, const QDict *qdict)
+{
+    IPFlowSpec *spec = g_new0(IPFlowSpec, 1);
+    char *src, *dst;
+    Error *err = NULL;
+
+    spec->protocol = g_strdup(qdict_get_try_str(qdict, "protocol"));
+    spec->object_name = g_strdup(qdict_get_try_str(qdict, "object-name"));
+    src = g_strdup(qdict_get_try_str(qdict, "src"));
+    dst = g_strdup(qdict_get_try_str(qdict, "dst"));
+
+    if (src) {
+        spec->source = g_new0(InetSocketAddressBase, 1);
+
+        if (inet_parse_base(spec->source, src, NULL)) {
+            monitor_printf(mon, "Incorrect passthrough src address\n");
+            goto out;
+        }
+    }
+
+    if (dst) {
+        spec->destination = g_new0(InetSocketAddressBase, 1);
+
+        if (inet_parse_base(spec->destination, dst, NULL)) {
+            monitor_printf(mon, "Incorrect passthrough dst address\n");
+            goto out;
+        }
+    }
+
+    qmp_passthrough_filter_add(spec, &err);
+
+out:
+    g_free(src);
+    g_free(dst);
+
+    hmp_handle_error(mon, err);
+}
+
+void hmp_passthrough_filter_del(Monitor *mon, const QDict *qdict)
+{
+    IPFlowSpec *spec = g_new0(IPFlowSpec, 1);
+    char *src, *dst;
+    Error *err = NULL;
+
+    spec->protocol = g_strdup(qdict_get_try_str(qdict, "protocol"));
+    spec->object_name = g_strdup(qdict_get_try_str(qdict, "object-name"));
+    src = g_strdup(qdict_get_try_str(qdict, "src"));
+    dst = g_strdup(qdict_get_try_str(qdict, "dst"));
+
+    if (src) {
+        spec->source = g_new0(InetSocketAddressBase, 1);
+
+        if (inet_parse_base(spec->source, src, NULL)) {
+            monitor_printf(mon, "Incorrect passthrough src address\n");
+            goto out;
+        }
+    }
+
+    if (dst) {
+        spec->destination = g_new0(InetSocketAddressBase, 1);
+
+        if (inet_parse_base(spec->destination, dst, NULL)) {
+            monitor_printf(mon, "Incorrect passthrough dst address\n");
+            goto out;
+        }
+    }
+
+    qmp_passthrough_filter_del(spec, &err);
+
+out:
+    g_free(src);
+    g_free(dst);
+
+    hmp_handle_error(mon, err);
+}
+
 void hmp_object_add(Monitor *mon, const QDict *qdict)
 {
     const char *options = qdict_get_str(qdict, "object");
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PULL 4/6] net/colo-compare: Move data structure and define to .h file.
  2021-06-25  3:11 [PULL 0/6] COLO-Proxy patches for 2021-06-25 Zhang Chen
                   ` (2 preceding siblings ...)
  2021-06-25  3:11 ` [PULL 3/6] hmp-commands: Add new HMP command for filter passthrough Zhang Chen
@ 2021-06-25  3:11 ` Zhang Chen
  2021-06-25  3:11 ` [PULL 5/6] net/colo-compare: Add passthrough list to CompareState Zhang Chen
  2021-06-25  3:11 ` [PULL 6/6] net/net.c: Add handler for passthrough filter command Zhang Chen
  5 siblings, 0 replies; 9+ messages in thread
From: Zhang Chen @ 2021-06-25  3:11 UTC (permalink / raw)
  To: Jason Wang
  Cc: Lukas Straub, Daniel P. Berrangé,
	Li Zhijian, qemu-dev, Markus Armbruster, Zhang Chen,
	Gerd Hoffmann, Eric Blake, Dr. David Alan Gilbert

Rename structure with COLO index and move it to .h file,
It make other modules can reuse COLO code.

Signed-off-by: Zhang Chen <chen.zhang@intel.com>
---
 net/colo-compare.c | 132 ++++++++-------------------------------------
 net/colo-compare.h |  86 +++++++++++++++++++++++++++++
 2 files changed, 109 insertions(+), 109 deletions(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index b100e7b51f..dcd24bb113 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -17,29 +17,18 @@
 #include "qemu/error-report.h"
 #include "trace.h"
 #include "qapi/error.h"
-#include "net/net.h"
 #include "net/eth.h"
 #include "qom/object_interfaces.h"
 #include "qemu/iov.h"
 #include "qom/object.h"
 #include "net/queue.h"
-#include "chardev/char-fe.h"
 #include "qemu/sockets.h"
-#include "colo.h"
-#include "sysemu/iothread.h"
 #include "net/colo-compare.h"
-#include "migration/colo.h"
-#include "migration/migration.h"
 #include "util.h"
 
 #include "block/aio-wait.h"
 #include "qemu/coroutine.h"
 
-#define TYPE_COLO_COMPARE "colo-compare"
-typedef struct CompareState CompareState;
-DECLARE_INSTANCE_CHECKER(CompareState, COLO_COMPARE,
-                         TYPE_COLO_COMPARE)
-
 static QTAILQ_HEAD(, CompareState) net_compares =
        QTAILQ_HEAD_INITIALIZER(net_compares);
 
@@ -47,13 +36,13 @@ static NotifierList colo_compare_notifiers =
     NOTIFIER_LIST_INITIALIZER(colo_compare_notifiers);
 
 #define COMPARE_READ_LEN_MAX NET_BUFSIZE
-#define MAX_QUEUE_SIZE 1024
+#define MAX_COLO_QUEUE_SIZE 1024
 
 #define COLO_COMPARE_FREE_PRIMARY     0x01
 #define COLO_COMPARE_FREE_SECONDARY   0x02
 
-#define REGULAR_PACKET_CHECK_MS 1000
-#define DEFAULT_TIME_OUT_MS 3000
+#define COLO_REGULAR_PACKET_CHECK_MS 1000
+#define COLO_DEFAULT_TIME_OUT_MS 3000
 
 /* #define DEBUG_COLO_PACKETS */
 
@@ -64,87 +53,6 @@ static QemuCond event_complete_cond;
 static int event_unhandled_count;
 static uint32_t max_queue_size;
 
-/*
- *  + 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 SendCo {
-    Coroutine *co;
-    struct CompareState *s;
-    CharBackend *chr;
-    GQueue send_list;
-    bool notify_remote_frame;
-    bool done;
-    int ret;
-} SendCo;
-
-typedef struct SendEntry {
-    uint32_t size;
-    uint32_t vnet_hdr_len;
-    uint8_t *buf;
-} SendEntry;
-
-struct CompareState {
-    Object parent;
-
-    char *pri_indev;
-    char *sec_indev;
-    char *outdev;
-    char *notify_dev;
-    CharBackend chr_pri_in;
-    CharBackend chr_sec_in;
-    CharBackend chr_out;
-    CharBackend chr_notify_dev;
-    SocketReadState pri_rs;
-    SocketReadState sec_rs;
-    SocketReadState notify_rs;
-    SendCo out_sendco;
-    SendCo notify_sendco;
-    bool vnet_hdr;
-    uint64_t compare_timeout;
-    uint32_t expired_scan_cycle;
-
-    /*
-     * Record the connection that through the NIC
-     * Element type: Connection
-     */
-    GQueue conn_list;
-    /* Record the connection without repetition */
-    GHashTable *connection_track_table;
-
-    IOThread *iothread;
-    GMainContext *worker_context;
-    QEMUTimer *packet_check_timer;
-
-    QEMUBH *event_bh;
-    enum colo_event event;
-
-    QTAILQ_ENTRY(CompareState) next;
-};
-
-typedef struct CompareClass {
-    ObjectClass parent_class;
-} CompareClass;
-
 enum {
     PRIMARY_IN = 0,
     SECONDARY_IN,
@@ -155,6 +63,12 @@ static const char *colo_mode[] = {
     [SECONDARY_IN] = "secondary",
 };
 
+typedef struct COLOSendEntry {
+    uint32_t size;
+    uint32_t vnet_hdr_len;
+    uint8_t *buf;
+} COLOSendEntry;
+
 static int compare_chr_send(CompareState *s,
                             uint8_t *buf,
                             uint32_t size,
@@ -724,19 +638,19 @@ static void colo_compare_connection(void *opaque, void *user_data)
 
 static void coroutine_fn _compare_chr_send(void *opaque)
 {
-    SendCo *sendco = opaque;
+    COLOSendCo *sendco = opaque;
     CompareState *s = sendco->s;
     int ret = 0;
 
     while (!g_queue_is_empty(&sendco->send_list)) {
-        SendEntry *entry = g_queue_pop_tail(&sendco->send_list);
+        COLOSendEntry *entry = g_queue_pop_tail(&sendco->send_list);
         uint32_t len = htonl(entry->size);
 
         ret = qemu_chr_fe_write_all(sendco->chr, (uint8_t *)&len, sizeof(len));
 
         if (ret != sizeof(len)) {
             g_free(entry->buf);
-            g_slice_free(SendEntry, entry);
+            g_slice_free(COLOSendEntry, entry);
             goto err;
         }
 
@@ -753,7 +667,7 @@ static void coroutine_fn _compare_chr_send(void *opaque)
 
             if (ret != sizeof(len)) {
                 g_free(entry->buf);
-                g_slice_free(SendEntry, entry);
+                g_slice_free(COLOSendEntry, entry);
                 goto err;
             }
         }
@@ -764,12 +678,12 @@ static void coroutine_fn _compare_chr_send(void *opaque)
 
         if (ret != entry->size) {
             g_free(entry->buf);
-            g_slice_free(SendEntry, entry);
+            g_slice_free(COLOSendEntry, entry);
             goto err;
         }
 
         g_free(entry->buf);
-        g_slice_free(SendEntry, entry);
+        g_slice_free(COLOSendEntry, entry);
     }
 
     sendco->ret = 0;
@@ -777,9 +691,9 @@ static void coroutine_fn _compare_chr_send(void *opaque)
 
 err:
     while (!g_queue_is_empty(&sendco->send_list)) {
-        SendEntry *entry = g_queue_pop_tail(&sendco->send_list);
+        COLOSendEntry *entry = g_queue_pop_tail(&sendco->send_list);
         g_free(entry->buf);
-        g_slice_free(SendEntry, entry);
+        g_slice_free(COLOSendEntry, entry);
     }
     sendco->ret = ret < 0 ? ret : -EIO;
 out:
@@ -795,8 +709,8 @@ static int compare_chr_send(CompareState *s,
                             bool notify_remote_frame,
                             bool zero_copy)
 {
-    SendCo *sendco;
-    SendEntry *entry;
+    COLOSendCo *sendco;
+    COLOSendEntry *entry;
 
     if (notify_remote_frame) {
         sendco = &s->notify_sendco;
@@ -808,7 +722,7 @@ static int compare_chr_send(CompareState *s,
         return 0;
     }
 
-    entry = g_slice_new(SendEntry);
+    entry = g_slice_new(COLOSendEntry);
     entry->size = size;
     entry->vnet_hdr_len = vnet_hdr_len;
     if (zero_copy) {
@@ -1261,17 +1175,17 @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
 
     if (!s->compare_timeout) {
         /* Set default value to 3000 MS */
-        s->compare_timeout = DEFAULT_TIME_OUT_MS;
+        s->compare_timeout = COLO_DEFAULT_TIME_OUT_MS;
     }
 
     if (!s->expired_scan_cycle) {
         /* Set default value to 3000 MS */
-        s->expired_scan_cycle = REGULAR_PACKET_CHECK_MS;
+        s->expired_scan_cycle = COLO_REGULAR_PACKET_CHECK_MS;
     }
 
     if (!max_queue_size) {
         /* Set default queue size to 1024 */
-        max_queue_size = MAX_QUEUE_SIZE;
+        max_queue_size = MAX_COLO_QUEUE_SIZE;
     }
 
     if (find_and_check_chardev(&chr, s->pri_indev, errp) ||
diff --git a/net/colo-compare.h b/net/colo-compare.h
index b055270da2..031b627a2f 100644
--- a/net/colo-compare.h
+++ b/net/colo-compare.h
@@ -17,6 +17,92 @@
 #ifndef QEMU_COLO_COMPARE_H
 #define QEMU_COLO_COMPARE_H
 
+#include "net/net.h"
+#include "chardev/char-fe.h"
+#include "migration/colo.h"
+#include "migration/migration.h"
+#include "sysemu/iothread.h"
+#include "colo.h"
+
+#define TYPE_COLO_COMPARE "colo-compare"
+typedef struct CompareState CompareState;
+DECLARE_INSTANCE_CHECKER(CompareState, COLO_COMPARE,
+                         TYPE_COLO_COMPARE)
+
+typedef struct COLOSendCo {
+    Coroutine *co;
+    struct CompareState *s;
+    CharBackend *chr;
+    GQueue send_list;
+    bool notify_remote_frame;
+    bool done;
+    int ret;
+} COLOSendCo;
+
+/*
+ *  + 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  +
+ *                    +--------+  +--------+    +--------+ +--------+
+ */
+struct CompareState {
+    Object parent;
+
+    char *pri_indev;
+    char *sec_indev;
+    char *outdev;
+    char *notify_dev;
+    CharBackend chr_pri_in;
+    CharBackend chr_sec_in;
+    CharBackend chr_out;
+    CharBackend chr_notify_dev;
+    SocketReadState pri_rs;
+    SocketReadState sec_rs;
+    SocketReadState notify_rs;
+    COLOSendCo out_sendco;
+    COLOSendCo notify_sendco;
+    bool vnet_hdr;
+    uint64_t compare_timeout;
+    uint32_t expired_scan_cycle;
+
+    /*
+     * Record the connection that through the NIC
+     * Element type: Connection
+     */
+    GQueue conn_list;
+    /* Record the connection without repetition */
+    GHashTable *connection_track_table;
+
+    IOThread *iothread;
+    GMainContext *worker_context;
+    QEMUTimer *packet_check_timer;
+
+    QEMUBH *event_bh;
+    enum colo_event event;
+
+    QTAILQ_ENTRY(CompareState) next;
+};
+
+typedef struct CompareClass {
+    ObjectClass parent_class;
+} CompareClass;
+
 void colo_notify_compares_event(void *opaque, int event, Error **errp);
 void colo_compare_register_notifier(Notifier *notify);
 void colo_compare_unregister_notifier(Notifier *notify);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PULL 5/6] net/colo-compare: Add passthrough list to CompareState
  2021-06-25  3:11 [PULL 0/6] COLO-Proxy patches for 2021-06-25 Zhang Chen
                   ` (3 preceding siblings ...)
  2021-06-25  3:11 ` [PULL 4/6] net/colo-compare: Move data structure and define to .h file Zhang Chen
@ 2021-06-25  3:11 ` Zhang Chen
  2021-06-25  3:11 ` [PULL 6/6] net/net.c: Add handler for passthrough filter command Zhang Chen
  5 siblings, 0 replies; 9+ messages in thread
From: Zhang Chen @ 2021-06-25  3:11 UTC (permalink / raw)
  To: Jason Wang
  Cc: Lukas Straub, Daniel P. Berrangé,
	Li Zhijian, qemu-dev, Markus Armbruster, Zhang Chen,
	Gerd Hoffmann, Eric Blake, Dr. David Alan Gilbert

Add passthrough list for each CompareState.

Signed-off-by: Zhang Chen <chen.zhang@intel.com>
---
 net/colo-compare.c | 28 ++++++++++++++++++++++++++++
 net/colo-compare.h | 12 ++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index dcd24bb113..64e72c82f1 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -161,6 +161,7 @@ static int packet_enqueue(CompareState *s, int mode, Connection **con)
     ConnectionKey key;
     Packet *pkt = NULL;
     Connection *conn;
+    COLOPassthroughEntry *pass, *next;
     int ret;
 
     if (mode == PRIMARY_IN) {
@@ -180,6 +181,31 @@ static int packet_enqueue(CompareState *s, int mode, Connection **con)
     }
     fill_connection_key(pkt, &key);
 
+    /* Check COLO passthrough specifications */
+    qemu_mutex_lock(&s->passthroughlist_mutex);
+    if (!QLIST_EMPTY(&s->passthroughlist)) {
+        QLIST_FOREACH_SAFE(pass, &s->passthroughlist, node, next) {
+            if (key.ip_proto == pass->l4_protocol.p_proto) {
+                if (pass->src_port == 0 || pass->src_port == key.dst_port) {
+                    if (pass->src_ip.s_addr == 0 ||
+                        pass->src_ip.s_addr == key.src.s_addr) {
+                        if (pass->dst_port == 0 ||
+                            pass->dst_port == key.src_port) {
+                            if (pass->dst_ip.s_addr == 0 ||
+                                pass->dst_ip.s_addr == key.dst.s_addr) {
+                                packet_destroy(pkt, NULL);
+                                pkt = NULL;
+                                qemu_mutex_unlock(&s->passthroughlist_mutex);
+                                return -1;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    qemu_mutex_unlock(&s->passthroughlist_mutex);
+
     conn = connection_get(s->connection_track_table,
                           &key,
                           &s->conn_list);
@@ -1232,6 +1258,7 @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
     }
 
     g_queue_init(&s->conn_list);
+    QLIST_INIT(&s->passthroughlist);
 
     s->connection_track_table = g_hash_table_new_full(connection_key_hash,
                                                       connection_key_equal,
@@ -1246,6 +1273,7 @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
         qemu_cond_init(&event_complete_cond);
         colo_compare_active = true;
     }
+    qemu_mutex_init(&s->passthroughlist_mutex);
     QTAILQ_INSERT_TAIL(&net_compares, s, next);
     qemu_mutex_unlock(&colo_compare_mutex);
 
diff --git a/net/colo-compare.h b/net/colo-compare.h
index 031b627a2f..995f28b833 100644
--- a/net/colo-compare.h
+++ b/net/colo-compare.h
@@ -23,6 +23,7 @@
 #include "migration/migration.h"
 #include "sysemu/iothread.h"
 #include "colo.h"
+#include <netdb.h>
 
 #define TYPE_COLO_COMPARE "colo-compare"
 typedef struct CompareState CompareState;
@@ -39,6 +40,15 @@ typedef struct COLOSendCo {
     int ret;
 } COLOSendCo;
 
+typedef struct COLOPassthroughEntry {
+    struct protoent l4_protocol;
+    int src_port;
+    int dst_port;
+    struct in_addr src_ip;
+    struct in_addr dst_ip;
+    QLIST_ENTRY(COLOPassthroughEntry) node;
+} COLOPassthroughEntry;
+
 /*
  *  + CompareState ++
  *  |               |
@@ -95,6 +105,8 @@ struct CompareState {
 
     QEMUBH *event_bh;
     enum colo_event event;
+    QLIST_HEAD(, COLOPassthroughEntry) passthroughlist;
+    QemuMutex passthroughlist_mutex;
 
     QTAILQ_ENTRY(CompareState) next;
 };
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PULL 6/6] net/net.c: Add handler for passthrough filter command
  2021-06-25  3:11 [PULL 0/6] COLO-Proxy patches for 2021-06-25 Zhang Chen
                   ` (4 preceding siblings ...)
  2021-06-25  3:11 ` [PULL 5/6] net/colo-compare: Add passthrough list to CompareState Zhang Chen
@ 2021-06-25  3:11 ` Zhang Chen
  5 siblings, 0 replies; 9+ messages in thread
From: Zhang Chen @ 2021-06-25  3:11 UTC (permalink / raw)
  To: Jason Wang
  Cc: Lukas Straub, Daniel P. Berrangé,
	Li Zhijian, qemu-dev, Markus Armbruster, Zhang Chen,
	Gerd Hoffmann, Eric Blake, Dr. David Alan Gilbert

Use the connection protocol,src port,dst port,src ip,dst ip as the key
to passthrough certain network traffic in object with network packet
processing function.

Signed-off-by: Zhang Chen <chen.zhang@intel.com>
---
 net/net.c | 199 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 197 insertions(+), 2 deletions(-)

diff --git a/net/net.c b/net/net.c
index 00f2be7a58..9ede98d166 100644
--- a/net/net.c
+++ b/net/net.c
@@ -55,6 +55,8 @@
 #include "net/colo-compare.h"
 #include "net/filter.h"
 #include "qapi/string-output-visitor.h"
+#include "net/colo-compare.h"
+#include "qom/object_interfaces.h"
 
 /* Net bridge is currently not supported for W32. */
 #if !defined(_WIN32)
@@ -1195,14 +1197,207 @@ void qmp_netdev_del(const char *id, Error **errp)
     }
 }
 
+static int check_addr(InetSocketAddressBase *addr)
+{
+    if (!addr || (addr->host && !qemu_isdigit(addr->host[0]))) {
+        return -1;
+    }
+
+    if (atoi(addr->port) > 65536 || atoi(addr->port) < 0) {
+        return -1;
+    }
+
+    return 0;
+}
+
+/* The initial version only supports colo-compare */
+static CompareState *passthrough_filter_check(IPFlowSpec *spec, Error **errp)
+{
+    Object *container;
+    Object *obj;
+    CompareState *s;
+
+    if (!spec->object_name) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "object-name",
+                   "Need input object name");
+        return NULL;
+    }
+
+    container = object_get_objects_root();
+    obj = object_resolve_path_component(container, spec->object_name);
+    if (!obj) {
+        error_setg(errp, "object '%s' not found", spec->object_name);
+        return NULL;
+    }
+
+    s = COLO_COMPARE(obj);
+
+    if (!getprotobyname(spec->protocol)) {
+        error_setg(errp, "Passthrough filter get wrong protocol");
+        return NULL;
+    }
+
+    if (spec->source) {
+        if (check_addr(spec->source)) {
+            error_setg(errp, "Passthrough filter get wrong source");
+            return NULL;
+        }
+    }
+
+    if (spec->destination) {
+        if (check_addr(spec->destination)) {
+            error_setg(errp, "Passthrough filter get wrong destination");
+            return NULL;
+        }
+    }
+
+    return s;
+}
+
+/* The initial version only supports colo-compare */
+static COLOPassthroughEntry *passthrough_filter_find(CompareState *s,
+                                                     COLOPassthroughEntry *ent)
+{
+    COLOPassthroughEntry *next = NULL, *origin = NULL;
+
+    if (!QLIST_EMPTY(&s->passthroughlist)) {
+        QLIST_FOREACH_SAFE(origin, &s->passthroughlist, node, next) {
+            if ((ent->l4_protocol.p_proto == origin->l4_protocol.p_proto) &&
+                (ent->src_port == origin->src_port) &&
+                (ent->dst_port == origin->dst_port) &&
+                (ent->src_ip.s_addr == origin->src_ip.s_addr) &&
+                (ent->dst_ip.s_addr == origin->dst_ip.s_addr)) {
+                return origin;
+            }
+        }
+    }
+
+    return NULL;
+}
+
+/* The initial version only supports colo-compare */
+static void passthrough_filter_add(CompareState *s,
+                                   IPFlowSpec *spec,
+                                   Error **errp)
+{
+    COLOPassthroughEntry *pass = NULL;
+
+    pass = g_new0(COLOPassthroughEntry, 1);
+
+    if (spec->protocol) {
+        memcpy(&pass->l4_protocol, getprotobyname(spec->protocol),
+               sizeof(struct protoent));
+    }
+
+    if (spec->source) {
+        if (!inet_aton(spec->source->host, &pass->src_ip)) {
+            pass->src_ip.s_addr = 0;
+        }
+
+        pass->src_port = atoi(spec->source->port);
+    }
+
+    if (spec->destination) {
+        if (!inet_aton(spec->destination->host, &pass->dst_ip)) {
+            pass->dst_ip.s_addr = 0;
+        }
+
+        pass->dst_port = atoi(spec->destination->port);
+    }
+
+    qemu_mutex_lock(&s->passthroughlist_mutex);
+    if (passthrough_filter_find(s, pass)) {
+        error_setg(errp, "The pass through connection already exists");
+        g_free(pass);
+        qemu_mutex_unlock(&s->passthroughlist_mutex);
+        return;
+    }
+
+    QLIST_INSERT_HEAD(&s->passthroughlist, pass, node);
+    qemu_mutex_unlock(&s->passthroughlist_mutex);
+}
+
+/* The initial version only supports colo-compare */
+static void passthrough_filter_del(CompareState *s,
+                                   IPFlowSpec *spec,
+                                   Error **errp)
+{
+    COLOPassthroughEntry *pass = NULL, *result = NULL;
+
+    pass = g_new0(COLOPassthroughEntry, 1);
+
+    if (spec->protocol) {
+        memcpy(&pass->l4_protocol, getprotobyname(spec->protocol),
+               sizeof(struct protoent));
+    }
+
+    if (spec->source) {
+        if (!inet_aton(spec->source->host, &pass->src_ip)) {
+            pass->src_ip.s_addr = 0;
+        }
+
+        pass->src_port = atoi(spec->source->port);
+    }
+
+    if (spec->destination) {
+        if (!inet_aton(spec->destination->host, &pass->dst_ip)) {
+            pass->dst_ip.s_addr = 0;
+        }
+
+        pass->dst_port = atoi(spec->destination->port);
+    }
+
+    qemu_mutex_lock(&s->passthroughlist_mutex);
+
+    result = passthrough_filter_find(s, pass);
+    if (result) {
+        QLIST_REMOVE(result, node);
+        g_free(result);
+    } else {
+        error_setg(errp, "Can't find the IP flow Spec");
+    }
+
+    g_free(pass);
+    g_free(spec);
+    qemu_mutex_unlock(&s->passthroughlist_mutex);
+}
+
+/* The initial version only supports colo-compare */
 void qmp_passthrough_filter_add(IPFlowSpec *spec, Error **errp)
 {
-    /* TODO implement setup passthrough rule */
+    CompareState *s;
+    Error *err = NULL;
+
+    s = passthrough_filter_check(spec, &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    passthrough_filter_add(s, spec, &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
 }
 
+/* The initial version only supports colo-compare */
 void qmp_passthrough_filter_del(IPFlowSpec *spec, Error **errp)
 {
-    /* TODO implement delete passthrough rule */
+    CompareState *s;
+    Error *err = NULL;
+
+    s = passthrough_filter_check(spec, &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    passthrough_filter_del(s, spec, &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
 }
 
 static void netfilter_print_info(Monitor *mon, NetFilterState *nf)
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PULL 3/6] hmp-commands: Add new HMP command for filter passthrough
  2021-06-25  3:11 ` [PULL 3/6] hmp-commands: Add new HMP command for filter passthrough Zhang Chen
@ 2021-06-30 10:39   ` Dr. David Alan Gilbert
  2021-07-01  8:32     ` chen.zhang
  0 siblings, 1 reply; 9+ messages in thread
From: Dr. David Alan Gilbert @ 2021-06-30 10:39 UTC (permalink / raw)
  To: Zhang Chen
  Cc: Lukas Straub, Daniel P. Berrangé,
	Li Zhijian, Jason Wang, qemu-dev, Markus Armbruster,
	Gerd Hoffmann, Eric Blake

* Zhang Chen (chen.zhang@intel.com) wrote:
> Add hmp_passthrough_filter_add and hmp_passthrough_filter_del make user
> can maintain object network passthrough list in human monitor
> 
> Signed-off-by: Zhang Chen <chen.zhang@intel.com>
> ---
>  hmp-commands.hx       | 26 +++++++++++++++
>  include/monitor/hmp.h |  2 ++
>  monitor/hmp-cmds.c    | 76 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 104 insertions(+)
> 
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 8e45bce2cd..426a7d6cda 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1292,6 +1292,32 @@ SRST
>    Remove host network device.
>  ERST
>  
> +    {
> +        .name       = "passthrough_filter_add",
> +        .args_type  = "protocol:s?,object-name:s,src:s?,dst:s?",
> +        .params     = "[protocol] object-name [src] [dst]",
> +        .help       = "Add network passthrough rule to object passthrough list",
> +        .cmd        = hmp_passthrough_filter_add,
> +    },
> +
> +SRST
> +``passthrough_filter_add``
> +  Add network stream to object passthrough list.
> +ERST
> +
> +    {
> +        .name       = "passthrough_filter_del",
> +        .args_type  = "protocol:s?,object-name:s,src:s?,dst:s?",
> +        .params     = "[protocol] object-name [src] [dst]",
> +        .help       = "Delete network passthrough rule from object passthrough list",
> +        .cmd        = hmp_passthrough_filter_del,
> +    },
> +
> +SRST
> +``passthrough_filter_del``
> +  Delete network stream from object passthrough list.
> +ERST
> +
>      {
>          .name       = "object_add",
>          .args_type  = "object:S",
> diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
> index 3baa1058e2..ba6987e552 100644
> --- a/include/monitor/hmp.h
> +++ b/include/monitor/hmp.h
> @@ -77,6 +77,8 @@ void hmp_device_del(Monitor *mon, const QDict *qdict);
>  void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict);
>  void hmp_netdev_add(Monitor *mon, const QDict *qdict);
>  void hmp_netdev_del(Monitor *mon, const QDict *qdict);
> +void hmp_passthrough_filter_add(Monitor *mon, const QDict *qdict);
> +void hmp_passthrough_filter_del(Monitor *mon, const QDict *qdict);
>  void hmp_getfd(Monitor *mon, const QDict *qdict);
>  void hmp_closefd(Monitor *mon, const QDict *qdict);
>  void hmp_sendkey(Monitor *mon, const QDict *qdict);
> diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
> index 0942027208..26ff316c93 100644
> --- a/monitor/hmp-cmds.c
> +++ b/monitor/hmp-cmds.c
> @@ -1638,6 +1638,82 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> +void hmp_passthrough_filter_add(Monitor *mon, const QDict *qdict)
> +{
> +    IPFlowSpec *spec = g_new0(IPFlowSpec, 1);
> +    char *src, *dst;
> +    Error *err = NULL;
> +
> +    spec->protocol = g_strdup(qdict_get_try_str(qdict, "protocol"));
> +    spec->object_name = g_strdup(qdict_get_try_str(qdict, "object-name"));
> +    src = g_strdup(qdict_get_try_str(qdict, "src"));
> +    dst = g_strdup(qdict_get_try_str(qdict, "dst"));
> +
> +    if (src) {
> +        spec->source = g_new0(InetSocketAddressBase, 1);
> +
> +        if (inet_parse_base(spec->source, src, NULL)) {
> +            monitor_printf(mon, "Incorrect passthrough src address\n");
> +            goto out;

Are you leaking spec->source ?

> +        }
> +    }
> +
> +    if (dst) {
> +        spec->destination = g_new0(InetSocketAddressBase, 1);
> +
> +        if (inet_parse_base(spec->destination, dst, NULL)) {
> +            monitor_printf(mon, "Incorrect passthrough dst address\n");
> +            goto out;
> +        }
> +    }
> +
> +    qmp_passthrough_filter_add(spec, &err);
> +
> +out:
> +    g_free(src);
> +    g_free(dst);
> +
> +    hmp_handle_error(mon, err);
> +}
> +
> +void hmp_passthrough_filter_del(Monitor *mon, const QDict *qdict)
> +{
> +    IPFlowSpec *spec = g_new0(IPFlowSpec, 1);
> +    char *src, *dst;
> +    Error *err = NULL;
> +
> +    spec->protocol = g_strdup(qdict_get_try_str(qdict, "protocol"));
> +    spec->object_name = g_strdup(qdict_get_try_str(qdict, "object-name"));
> +    src = g_strdup(qdict_get_try_str(qdict, "src"));
> +    dst = g_strdup(qdict_get_try_str(qdict, "dst"));
> +
> +    if (src) {
> +        spec->source = g_new0(InetSocketAddressBase, 1);
> +
> +        if (inet_parse_base(spec->source, src, NULL)) {
> +            monitor_printf(mon, "Incorrect passthrough src address\n");
> +            goto out;
> +        }
> +    }
> +
> +    if (dst) {
> +        spec->destination = g_new0(InetSocketAddressBase, 1);
> +
> +        if (inet_parse_base(spec->destination, dst, NULL)) {
> +            monitor_printf(mon, "Incorrect passthrough dst address\n");
> +            goto out;
> +        }
> +    }

You could merge that into something like:

   IPFlowSpec *hmp_parse_IPFlowSpec(Monitor *mon, const QDict *qdict)

Dave

> +    qmp_passthrough_filter_del(spec, &err);
> +
> +out:
> +    g_free(src);
> +    g_free(dst);
> +
> +    hmp_handle_error(mon, err);
> +}
> +
>  void hmp_object_add(Monitor *mon, const QDict *qdict)
>  {
>      const char *options = qdict_get_str(qdict, "object");
> -- 
> 2.25.1
> 
-- 
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PULL 3/6] hmp-commands: Add new HMP command for filter passthrough
  2021-06-30 10:39   ` Dr. David Alan Gilbert
@ 2021-07-01  8:32     ` chen.zhang
  0 siblings, 0 replies; 9+ messages in thread
From: chen.zhang @ 2021-07-01  8:32 UTC (permalink / raw)
  To: Dr. David Alan Gilbert
  Cc: Lukas Straub, Daniel P. Berrangé,
	Li Zhijian, Jason Wang, qemu-dev, Markus Armbruster,
	Gerd Hoffmann, Eric Blake


On 6/30/21 6:39 PM, Dr. David Alan Gilbert wrote:
> * Zhang Chen (chen.zhang@intel.com) wrote:
>> Add hmp_passthrough_filter_add and hmp_passthrough_filter_del make user
>> can maintain object network passthrough list in human monitor
>>
>> Signed-off-by: Zhang Chen <chen.zhang@intel.com>
>> ---
>>   hmp-commands.hx       | 26 +++++++++++++++
>>   include/monitor/hmp.h |  2 ++
>>   monitor/hmp-cmds.c    | 76 +++++++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 104 insertions(+)
>>
>> diff --git a/hmp-commands.hx b/hmp-commands.hx
>> index 8e45bce2cd..426a7d6cda 100644
>> --- a/hmp-commands.hx
>> +++ b/hmp-commands.hx
>> @@ -1292,6 +1292,32 @@ SRST
>>     Remove host network device.
>>   ERST
>>   
>> +    {
>> +        .name       = "passthrough_filter_add",
>> +        .args_type  = "protocol:s?,object-name:s,src:s?,dst:s?",
>> +        .params     = "[protocol] object-name [src] [dst]",
>> +        .help       = "Add network passthrough rule to object passthrough list",
>> +        .cmd        = hmp_passthrough_filter_add,
>> +    },
>> +
>> +SRST
>> +``passthrough_filter_add``
>> +  Add network stream to object passthrough list.
>> +ERST
>> +
>> +    {
>> +        .name       = "passthrough_filter_del",
>> +        .args_type  = "protocol:s?,object-name:s,src:s?,dst:s?",
>> +        .params     = "[protocol] object-name [src] [dst]",
>> +        .help       = "Delete network passthrough rule from object passthrough list",
>> +        .cmd        = hmp_passthrough_filter_del,
>> +    },
>> +
>> +SRST
>> +``passthrough_filter_del``
>> +  Delete network stream from object passthrough list.
>> +ERST
>> +
>>       {
>>           .name       = "object_add",
>>           .args_type  = "object:S",
>> diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
>> index 3baa1058e2..ba6987e552 100644
>> --- a/include/monitor/hmp.h
>> +++ b/include/monitor/hmp.h
>> @@ -77,6 +77,8 @@ void hmp_device_del(Monitor *mon, const QDict *qdict);
>>   void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict);
>>   void hmp_netdev_add(Monitor *mon, const QDict *qdict);
>>   void hmp_netdev_del(Monitor *mon, const QDict *qdict);
>> +void hmp_passthrough_filter_add(Monitor *mon, const QDict *qdict);
>> +void hmp_passthrough_filter_del(Monitor *mon, const QDict *qdict);
>>   void hmp_getfd(Monitor *mon, const QDict *qdict);
>>   void hmp_closefd(Monitor *mon, const QDict *qdict);
>>   void hmp_sendkey(Monitor *mon, const QDict *qdict);
>> diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
>> index 0942027208..26ff316c93 100644
>> --- a/monitor/hmp-cmds.c
>> +++ b/monitor/hmp-cmds.c
>> @@ -1638,6 +1638,82 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict)
>>       hmp_handle_error(mon, err);
>>   }
>>   
>> +void hmp_passthrough_filter_add(Monitor *mon, const QDict *qdict)
>> +{
>> +    IPFlowSpec *spec = g_new0(IPFlowSpec, 1);
>> +    char *src, *dst;
>> +    Error *err = NULL;
>> +
>> +    spec->protocol = g_strdup(qdict_get_try_str(qdict, "protocol"));
>> +    spec->object_name = g_strdup(qdict_get_try_str(qdict, "object-name"));
>> +    src = g_strdup(qdict_get_try_str(qdict, "src"));
>> +    dst = g_strdup(qdict_get_try_str(qdict, "dst"));
>> +
>> +    if (src) {
>> +        spec->source = g_new0(InetSocketAddressBase, 1);
>> +
>> +        if (inet_parse_base(spec->source, src, NULL)) {
>> +            monitor_printf(mon, "Incorrect passthrough src address\n");
>> +            goto out;
> Are you leaking spec->source ?


Good catch.


>
>> +        }
>> +    }
>> +
>> +    if (dst) {
>> +        spec->destination = g_new0(InetSocketAddressBase, 1);
>> +
>> +        if (inet_parse_base(spec->destination, dst, NULL)) {
>> +            monitor_printf(mon, "Incorrect passthrough dst address\n");
>> +            goto out;
>> +        }
>> +    }
>> +
>> +    qmp_passthrough_filter_add(spec, &err);
>> +
>> +out:
>> +    g_free(src);
>> +    g_free(dst);
>> +
>> +    hmp_handle_error(mon, err);
>> +}
>> +
>> +void hmp_passthrough_filter_del(Monitor *mon, const QDict *qdict)
>> +{
>> +    IPFlowSpec *spec = g_new0(IPFlowSpec, 1);
>> +    char *src, *dst;
>> +    Error *err = NULL;
>> +
>> +    spec->protocol = g_strdup(qdict_get_try_str(qdict, "protocol"));
>> +    spec->object_name = g_strdup(qdict_get_try_str(qdict, "object-name"));
>> +    src = g_strdup(qdict_get_try_str(qdict, "src"));
>> +    dst = g_strdup(qdict_get_try_str(qdict, "dst"));
>> +
>> +    if (src) {
>> +        spec->source = g_new0(InetSocketAddressBase, 1);
>> +
>> +        if (inet_parse_base(spec->source, src, NULL)) {
>> +            monitor_printf(mon, "Incorrect passthrough src address\n");
>> +            goto out;
>> +        }
>> +    }
>> +
>> +    if (dst) {
>> +        spec->destination = g_new0(InetSocketAddressBase, 1);
>> +
>> +        if (inet_parse_base(spec->destination, dst, NULL)) {
>> +            monitor_printf(mon, "Incorrect passthrough dst address\n");
>> +            goto out;
>> +        }
>> +    }
> You could merge that into something like:
>
>     IPFlowSpec *hmp_parse_IPFlowSpec(Monitor *mon, const QDict *qdict)


OK, I will update to V2.

Thanks

Chen


>
> Dave
>
>> +    qmp_passthrough_filter_del(spec, &err);
>> +
>> +out:
>> +    g_free(src);
>> +    g_free(dst);
>> +
>> +    hmp_handle_error(mon, err);
>> +}
>> +
>>   void hmp_object_add(Monitor *mon, const QDict *qdict)
>>   {
>>       const char *options = qdict_get_str(qdict, "object");
>> -- 
>> 2.25.1
>>


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-07-01  8:39 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-25  3:11 [PULL 0/6] COLO-Proxy patches for 2021-06-25 Zhang Chen
2021-06-25  3:11 ` [PULL 1/6] qapi/net: Add IPFlowSpec and QMP command for filter passthrough Zhang Chen
2021-06-25  3:11 ` [PULL 2/6] util/qemu-sockets.c: Add inet_parse_base to handle InetSocketAddressBase Zhang Chen
2021-06-25  3:11 ` [PULL 3/6] hmp-commands: Add new HMP command for filter passthrough Zhang Chen
2021-06-30 10:39   ` Dr. David Alan Gilbert
2021-07-01  8:32     ` chen.zhang
2021-06-25  3:11 ` [PULL 4/6] net/colo-compare: Move data structure and define to .h file Zhang Chen
2021-06-25  3:11 ` [PULL 5/6] net/colo-compare: Add passthrough list to CompareState Zhang Chen
2021-06-25  3:11 ` [PULL 6/6] net/net.c: Add handler for passthrough filter command Zhang Chen

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.