* [Qemu-devel] [PATCH v2 1/9] net: add a new object netfilter
2015-07-31 4:13 [Qemu-devel] [PATCH v2 0/9] For QEMU 2.5: Add a netfilter object and netbuffer filter Yang Hongyang
@ 2015-07-31 4:13 ` Yang Hongyang
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 2/9] init/cleanup of netfilter object Yang Hongyang
` (8 subsequent siblings)
9 siblings, 0 replies; 23+ messages in thread
From: Yang Hongyang @ 2015-07-31 4:13 UTC (permalink / raw)
To: qemu-devel
Cc: thuth, zhang.zhanghailiang, lizhijian, jasowang, mrhines,
stefanha, Paolo Bonzini, Yang Hongyang
Add the framework for a new netfilter object and a new
-netfilter CLI option as a basis for the following patches.
Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Eric Blake <eblake@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
include/net/filter.h | 15 +++++++++++++++
include/sysemu/sysemu.h | 1 +
net/Makefile.objs | 1 +
net/filter.c | 27 +++++++++++++++++++++++++++
qemu-options.hx | 1 +
vl.c | 13 +++++++++++++
6 files changed, 58 insertions(+)
create mode 100644 include/net/filter.h
create mode 100644 net/filter.c
diff --git a/include/net/filter.h b/include/net/filter.h
new file mode 100644
index 0000000..4242ded
--- /dev/null
+++ b/include/net/filter.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2015 FUJITSU LIMITED
+ *
+ * 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_NET_FILTER_H
+#define QEMU_NET_FILTER_H
+
+#include "qemu-common.h"
+
+int net_init_filters(void);
+
+#endif /* QEMU_NET_FILTER_H */
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 44570d1..15d6d00 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -212,6 +212,7 @@ extern QemuOptsList qemu_chardev_opts;
extern QemuOptsList qemu_device_opts;
extern QemuOptsList qemu_netdev_opts;
extern QemuOptsList qemu_net_opts;
+extern QemuOptsList qemu_netfilter_opts;
extern QemuOptsList qemu_global_opts;
extern QemuOptsList qemu_mon_opts;
diff --git a/net/Makefile.objs b/net/Makefile.objs
index ec19cb3..914aec0 100644
--- a/net/Makefile.objs
+++ b/net/Makefile.objs
@@ -13,3 +13,4 @@ common-obj-$(CONFIG_HAIKU) += tap-haiku.o
common-obj-$(CONFIG_SLIRP) += slirp.o
common-obj-$(CONFIG_VDE) += vde.o
common-obj-$(CONFIG_NETMAP) += netmap.o
+common-obj-y += filter.o
diff --git a/net/filter.c b/net/filter.c
new file mode 100644
index 0000000..4e40f08
--- /dev/null
+++ b/net/filter.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2015 FUJITSU LIMITED
+ *
+ * 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-common.h"
+#include "net/filter.h"
+
+int net_init_filters(void)
+{
+ return 0;
+}
+
+QemuOptsList qemu_netfilter_opts = {
+ .name = "netfilter",
+ .implied_opt_name = "type",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_netfilter_opts.head),
+ .desc = {
+ /*
+ * no elements => accept any params
+ * validation will happen later
+ */
+ { /* end of list */ }
+ },
+};
diff --git a/qemu-options.hx b/qemu-options.hx
index 77f5853..0d52d02 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1575,6 +1575,7 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
"socket][,vlan=n][,option][,option][,...]\n"
" old way to initialize a host network interface\n"
" (use the -netdev option if possible instead)\n", QEMU_ARCH_ALL)
+DEF("netfilter", HAS_ARG, QEMU_OPTION_netfilter, "", QEMU_ARCH_ALL)
STEXI
@item -net nic[,vlan=@var{n}][,macaddr=@var{mac}][,model=@var{type}] [,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}]
@findex -net
diff --git a/vl.c b/vl.c
index 0adbbd6..3b70371 100644
--- a/vl.c
+++ b/vl.c
@@ -75,6 +75,7 @@ int main(int argc, char **argv)
#include "monitor/qdev.h"
#include "sysemu/bt.h"
#include "net/net.h"
+#include "net/filter.h"
#include "net/slirp.h"
#include "monitor/monitor.h"
#include "ui/console.h"
@@ -2998,6 +2999,7 @@ int main(int argc, char **argv, char **envp)
qemu_add_opts(&qemu_device_opts);
qemu_add_opts(&qemu_netdev_opts);
qemu_add_opts(&qemu_net_opts);
+ qemu_add_opts(&qemu_netfilter_opts);
qemu_add_opts(&qemu_rtc_opts);
qemu_add_opts(&qemu_global_opts);
qemu_add_opts(&qemu_mon_opts);
@@ -3284,6 +3286,13 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
break;
+ case QEMU_OPTION_netfilter:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("netfilter"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
#ifdef CONFIG_LIBISCSI
case QEMU_OPTION_iscsi:
opts = qemu_opts_parse_noisily(qemu_find_opts("iscsi"),
@@ -4413,6 +4422,10 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
+ if (net_init_filters() < 0) {
+ exit(1);
+ }
+
#ifdef CONFIG_TPM
if (tpm_init() < 0) {
exit(1);
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v2 2/9] init/cleanup of netfilter object
2015-07-31 4:13 [Qemu-devel] [PATCH v2 0/9] For QEMU 2.5: Add a netfilter object and netbuffer filter Yang Hongyang
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 1/9] net: add a new object netfilter Yang Hongyang
@ 2015-07-31 4:13 ` Yang Hongyang
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 3/9] netfilter: add netfilter_{add|del} commands Yang Hongyang
` (7 subsequent siblings)
9 siblings, 0 replies; 23+ messages in thread
From: Yang Hongyang @ 2015-07-31 4:13 UTC (permalink / raw)
To: qemu-devel
Cc: thuth, zhang.zhanghailiang, lizhijian, jasowang, mrhines,
stefanha, Yang Hongyang
This is mostly the same with init/cleanup of netdev object.
Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
---
include/net/filter.h | 30 ++++++++++
include/qemu/typedefs.h | 1 +
net/filter.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++
qapi-schema.json | 37 ++++++++++++
4 files changed, 215 insertions(+)
diff --git a/include/net/filter.h b/include/net/filter.h
index 4242ded..9eaaae3 100644
--- a/include/net/filter.h
+++ b/include/net/filter.h
@@ -9,7 +9,37 @@
#define QEMU_NET_FILTER_H
#include "qemu-common.h"
+#include "qemu/typedefs.h"
+
+/* the netfilter chain */
+enum {
+ NET_FILTER_IN,
+ NET_FILTER_OUT,
+ NET_FILTER_ALL,
+};
+
+typedef void (FilterCleanup) (NetFilterState *);
+
+typedef struct NetFilterInfo {
+ NetFilterOptionsKind type;
+ size_t size;
+ FilterCleanup *cleanup;
+} NetFilterInfo;
+
+struct NetFilterState {
+ NetFilterInfo *info;
+ char *model;
+ char *name;
+ NetClientState *netdev;
+ int chain;
+ QTAILQ_ENTRY(NetFilterState) next;
+};
int net_init_filters(void);
+NetFilterState *qemu_new_net_filter(NetFilterInfo *info,
+ NetClientState *netdev,
+ const char *model,
+ const char *name,
+ int chain);
#endif /* QEMU_NET_FILTER_H */
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 6fdcbcd..2f75109 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -45,6 +45,7 @@ typedef struct Monitor Monitor;
typedef struct MouseTransformInfo MouseTransformInfo;
typedef struct MSIMessage MSIMessage;
typedef struct NetClientState NetClientState;
+typedef struct NetFilterState NetFilterState;
typedef struct NICInfo NICInfo;
typedef struct PcGuestInfo PcGuestInfo;
typedef struct PCIBridge PCIBridge;
diff --git a/net/filter.c b/net/filter.c
index 4e40f08..d19b390 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -6,10 +6,157 @@
*/
#include "qemu-common.h"
+#include "qapi-visit.h"
+#include "qapi/qmp/qerror.h"
+#include "qemu/error-report.h"
+#include "qapi-visit.h"
+#include "qapi/opts-visitor.h"
+#include "qapi/dealloc-visitor.h"
+#include "qemu/config-file.h"
+
#include "net/filter.h"
+#include "net/net.h"
+
+static QTAILQ_HEAD(, NetFilterState) net_filters;
+
+NetFilterState *qemu_new_net_filter(NetFilterInfo *info,
+ NetClientState *netdev,
+ const char *model,
+ const char *name,
+ int chain)
+{
+ NetFilterState *nf;
+
+ assert(info->size >= sizeof(NetFilterState));
+
+ nf = g_malloc0(info->size);
+ nf->info = info;
+ nf->model = g_strdup(model);
+ nf->name = g_strdup(name);
+ nf->netdev = netdev;
+ nf->chain = chain;
+ QTAILQ_INSERT_TAIL(&net_filters, nf, next);
+ /* TODO: attach netfilter to netdev */
+
+ return nf;
+}
+
+static inline void qemu_cleanup_net_filter(NetFilterState *nf)
+{
+ /* TODO: remove netfilter from netdev */
+
+ QTAILQ_REMOVE(&net_filters, nf, next);
+
+ if (nf->info->cleanup) {
+ nf->info->cleanup(nf);
+ }
+
+ g_free(nf->name);
+ g_free(nf->model);
+ g_free(nf);
+}
+
+typedef int (NetFilterInit)(const NetFilterOptions *opts,
+ const char *name, int chain,
+ NetClientState *netdev, Error **errp);
+
+static
+NetFilterInit * const net_filter_init_fun[NET_FILTER_OPTIONS_KIND_MAX] = {
+};
+
+static int net_filter_init1(const NetFilter *netfilter, Error **errp)
+{
+ NetClientState *netdev = NULL;
+ NetClientState *ncs[MAX_QUEUE_NUM];
+ const char *name = netfilter->id;
+ const char *netdev_id = netfilter->netdev;
+ const char *chain_str = NULL;
+ const NetFilterOptions *opts = netfilter->opts;
+ int chain, queues;
+
+ if (!net_filter_init_fun[opts->kind]) {
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type",
+ "a net filter type");
+ return -1;
+ }
+
+ if (netfilter->has_chain) {
+ chain_str = netfilter->chain;
+ if (!strcmp(chain_str, "in")) {
+ chain = NET_FILTER_IN;
+ } else if (!strcmp(chain_str, "out")) {
+ chain = NET_FILTER_OUT;
+ } else if (!strcmp(chain_str, "all")) {
+ chain = NET_FILTER_ALL;
+ } else {
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "chain",
+ "netfilter chain (in/out/all)");
+ return -1;
+ }
+ } else {
+ /* default */
+ chain = NET_FILTER_ALL;
+ }
+
+ queues = qemu_find_net_clients_except(netdev_id, ncs,
+ NET_CLIENT_OPTIONS_KIND_NIC,
+ MAX_QUEUE_NUM);
+ if (queues > 1) {
+ error_setg(errp, "multiqueues is not supported by now");
+ return -1;
+ } else if (queues < 1) {
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "netdev",
+ "a network backend id");
+ return -1;
+ }
+
+ netdev = ncs[0];
+
+ if (net_filter_init_fun[opts->kind](opts, name, chain, netdev, errp) < 0) {
+ if (errp && !*errp) {
+ error_setg(errp, QERR_DEVICE_INIT_FAILED,
+ NetFilterOptionsKind_lookup[opts->kind]);
+ }
+ return -1;
+ }
+
+ return 0;
+}
+
+static int net_init_filter(void *dummy, QemuOpts *opts, Error **errp)
+{
+ NetFilter *object = NULL;
+ Error *err = NULL;
+ int ret = -1;
+ OptsVisitor *ov = opts_visitor_new(opts);
+
+ visit_type_NetFilter(opts_get_visitor(ov), &object, NULL, &err);
+ opts_visitor_cleanup(ov);
+
+ if (!err) {
+ ret = net_filter_init1(object, &err);
+ }
+
+ if (object) {
+ QapiDeallocVisitor *dv = qapi_dealloc_visitor_new();
+
+ visit_type_NetFilter(qapi_dealloc_get_visitor(dv), &object, NULL, NULL);
+ qapi_dealloc_visitor_cleanup(dv);
+ }
+
+ error_propagate(errp, err);
+ return ret;
+}
int net_init_filters(void)
{
+ QTAILQ_INIT(&net_filters);
+
+ if (qemu_opts_foreach(qemu_find_opts("netfilter"),
+ net_init_filter, NULL, NULL)) {
+ return -1;
+ }
+
return 0;
}
diff --git a/qapi-schema.json b/qapi-schema.json
index 4342a08..d7fb578 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2537,6 +2537,43 @@
'opts': 'NetClientOptions' } }
##
+# @NetFilterOptions
+#
+# A discriminated record of network filters.
+#
+# Since 2.5
+#
+##
+{ 'union': 'NetFilterOptions',
+ 'data': { } }
+
+##
+# @NetFilter
+#
+# Captures the packets of a network backend.
+#
+# @id: identifier for monitor commands
+#
+# @netdev: the network backend it attached to
+#
+# @chain: #optional accept "in","out","all", if not specified, default is "all"
+# "in" means this filter will receive packets sent to the @netdev
+# "out" means this filter will receive packets sent from the @netdev
+# "all" means this filter will receive packets both sent to/from
+# the @netdev
+#
+# @opts: filter type specific properties
+#
+# Since 2.5
+##
+{ 'struct': 'NetFilter',
+ 'data': {
+ 'id': 'str',
+ 'netdev': 'str',
+ '*chain': 'str',
+ 'opts': 'NetFilterOptions' } }
+
+##
# @InetSocketAddress
#
# Captures a socket address or address range in the Internet namespace.
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v2 3/9] netfilter: add netfilter_{add|del} commands
2015-07-31 4:13 [Qemu-devel] [PATCH v2 0/9] For QEMU 2.5: Add a netfilter object and netbuffer filter Yang Hongyang
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 1/9] net: add a new object netfilter Yang Hongyang
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 2/9] init/cleanup of netfilter object Yang Hongyang
@ 2015-07-31 4:13 ` Yang Hongyang
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 4/9] net: add/remove filters from network backend Yang Hongyang
` (6 subsequent siblings)
9 siblings, 0 replies; 23+ messages in thread
From: Yang Hongyang @ 2015-07-31 4:13 UTC (permalink / raw)
To: qemu-devel
Cc: thuth, zhang.zhanghailiang, lizhijian, jasowang,
Markus Armbruster, mrhines, Luiz Capitulino, stefanha,
Yang Hongyang
add netfilter_{add|del} commands
This is mostly the same with netdev_{add|del} commands.
Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
CC: Luiz Capitulino <lcapitulino@redhat.com>
CC: Markus Armbruster <armbru@redhat.com>
CC: Eric Blake <eblake@redhat.com>
---
hmp-commands.hx | 30 +++++++++++++++++++++
hmp.c | 29 ++++++++++++++++++++
hmp.h | 4 +++
include/net/filter.h | 2 ++
monitor.c | 33 +++++++++++++++++++++++
net/filter.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++-
qapi-schema.json | 47 ++++++++++++++++++++++++++++++++
qmp-commands.hx | 57 +++++++++++++++++++++++++++++++++++++++
8 files changed, 277 insertions(+), 1 deletion(-)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index d3b7932..902e2d1 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1253,6 +1253,36 @@ Remove host network device.
ETEXI
{
+ .name = "netfilter_add",
+ .args_type = "netfilter:O",
+ .params = "[type],id=str,netdev=str[,chain=in|out|all,prop=value][,...]",
+ .help = "add netfilter",
+ .mhandler.cmd = hmp_netfilter_add,
+ .command_completion = netfilter_add_completion,
+ },
+
+STEXI
+@item netfilter_add
+@findex netfilter_add
+Add netfilter.
+ETEXI
+
+ {
+ .name = "netfilter_del",
+ .args_type = "id:s",
+ .params = "id",
+ .help = "remove netfilter",
+ .mhandler.cmd = hmp_netfilter_del,
+ .command_completion = netfilter_del_completion,
+ },
+
+STEXI
+@item netfilter_del
+@findex netfilter_del
+Remove netfilter.
+ETEXI
+
+ {
.name = "object_add",
.args_type = "object:O",
.params = "[qom-type=]type,id=str[,prop=value][,...]",
diff --git a/hmp.c b/hmp.c
index dcc66f1..09e3cda 100644
--- a/hmp.c
+++ b/hmp.c
@@ -15,6 +15,7 @@
#include "hmp.h"
#include "net/net.h"
+#include "net/filter.h"
#include "net/eth.h"
#include "sysemu/char.h"
#include "sysemu/block-backend.h"
@@ -1599,6 +1600,34 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict)
hmp_handle_error(mon, &err);
}
+void hmp_netfilter_add(Monitor *mon, const QDict *qdict)
+{
+ Error *err = NULL;
+ QemuOpts *opts;
+
+ opts = qemu_opts_from_qdict(qemu_find_opts("netfilter"), qdict, &err);
+ if (err) {
+ goto out;
+ }
+
+ netfilter_add(opts, &err);
+ if (err) {
+ qemu_opts_del(opts);
+ }
+
+out:
+ hmp_handle_error(mon, &err);
+}
+
+void hmp_netfilter_del(Monitor *mon, const QDict *qdict)
+{
+ const char *id = qdict_get_str(qdict, "id");
+ Error *err = NULL;
+
+ qmp_netfilter_del(id, &err);
+ hmp_handle_error(mon, &err);
+}
+
void hmp_object_add(Monitor *mon, const QDict *qdict)
{
Error *err = NULL;
diff --git a/hmp.h b/hmp.h
index 0cf4f2a..a21dbbb 100644
--- a/hmp.h
+++ b/hmp.h
@@ -85,6 +85,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_netfilter_add(Monitor *mon, const QDict *qdict);
+void hmp_netfilter_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);
@@ -112,6 +114,8 @@ void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str);
void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str);
void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str);
+void netfilter_add_completion(ReadLineState *rs, int nb_args, const char *str);
+void netfilter_del_completion(ReadLineState *rs, int nb_args, const char *str);
void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str);
void watchdog_action_completion(ReadLineState *rs, int nb_args,
const char *str);
diff --git a/include/net/filter.h b/include/net/filter.h
index 9eaaae3..1b6f896 100644
--- a/include/net/filter.h
+++ b/include/net/filter.h
@@ -41,5 +41,7 @@ NetFilterState *qemu_new_net_filter(NetFilterInfo *info,
const char *model,
const char *name,
int chain);
+void netfilter_add(QemuOpts *opts, Error **errp);
+void qmp_netfilter_add(QDict *qdict, QObject **ret, Error **errp);
#endif /* QEMU_NET_FILTER_H */
diff --git a/monitor.c b/monitor.c
index aeea2b5..d6b8f24 100644
--- a/monitor.c
+++ b/monitor.c
@@ -31,6 +31,7 @@
#include "hw/loader.h"
#include "exec/gdbstub.h"
#include "net/net.h"
+#include "net/filter.h"
#include "net/slirp.h"
#include "sysemu/char.h"
#include "ui/qemu-spice.h"
@@ -4193,6 +4194,21 @@ void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str)
}
}
+void netfilter_add_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+ size_t len;
+ int i;
+
+ if (nb_args != 2) {
+ return;
+ }
+ len = strlen(str);
+ readline_set_completion_index(rs, len);
+ for (i = 0; NetFilterOptionsKind_lookup[i]; i++) {
+ add_completion_option(rs, str, NetFilterOptionsKind_lookup[i]);
+ }
+}
+
void device_add_completion(ReadLineState *rs, int nb_args, const char *str)
{
GSList *list, *elt;
@@ -4429,6 +4445,23 @@ void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str)
}
}
+void netfilter_del_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+ int len;
+ QemuOpts *opts;
+
+ if (nb_args != 2) {
+ return;
+ }
+
+ len = strlen(str);
+ readline_set_completion_index(rs, len);
+ opts = qemu_opts_find(qemu_find_opts_err("netfilter", NULL), str);
+ if (opts) {
+ readline_add_completion(rs, str);
+ }
+}
+
void watchdog_action_completion(ReadLineState *rs, int nb_args, const char *str)
{
int i;
diff --git a/net/filter.c b/net/filter.c
index d19b390..18d1c8f 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -13,6 +13,7 @@
#include "qapi/opts-visitor.h"
#include "qapi/dealloc-visitor.h"
#include "qemu/config-file.h"
+#include "qmp-commands.h"
#include "net/filter.h"
#include "net/net.h"
@@ -41,7 +42,7 @@ NetFilterState *qemu_new_net_filter(NetFilterInfo *info,
return nf;
}
-static inline void qemu_cleanup_net_filter(NetFilterState *nf)
+static void qemu_cleanup_net_filter(NetFilterState *nf)
{
/* TODO: remove netfilter from netdev */
@@ -56,6 +57,79 @@ static inline void qemu_cleanup_net_filter(NetFilterState *nf)
g_free(nf);
}
+static void qemu_del_net_filter(NetFilterState *nf)
+{
+ /* handle multi queue? */
+ qemu_cleanup_net_filter(nf);
+}
+
+static NetFilterState *qemu_find_netfilter(const char *id)
+{
+ NetFilterState *nf;
+
+ QTAILQ_FOREACH(nf, &net_filters, next) {
+ if (!strcmp(nf->name, id)) {
+ return nf;
+ }
+ }
+
+ return NULL;
+}
+
+static int net_init_filter(void *dummy, QemuOpts *opts, Error **errp);
+void netfilter_add(QemuOpts *opts, Error **errp)
+{
+ net_init_filter(NULL, opts, errp);
+}
+
+void qmp_netfilter_add(QDict *qdict, QObject **ret, Error **errp)
+{
+ Error *local_err = NULL;
+ QemuOptsList *opts_list;
+ QemuOpts *opts;
+
+ opts_list = qemu_find_opts_err("netfilter", &local_err);
+ if (local_err) {
+ goto out;
+ }
+
+ opts = qemu_opts_from_qdict(opts_list, qdict, &local_err);
+ if (local_err) {
+ goto out;
+ }
+
+ netfilter_add(opts, &local_err);
+ if (local_err) {
+ qemu_opts_del(opts);
+ goto out;
+ }
+
+out:
+ error_propagate(errp, local_err);
+}
+
+void qmp_netfilter_del(const char *id, Error **errp)
+{
+ NetFilterState *nf;
+ QemuOpts *opts;
+
+ nf = qemu_find_netfilter(id);
+ if (!nf) {
+ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+ "Device '%s' not found", id);
+ return;
+ }
+
+ opts = qemu_opts_find(qemu_find_opts_err("netfilter", NULL), id);
+ if (!opts) {
+ error_setg(errp, "Device '%s' is not a netfilter", id);
+ return;
+ }
+
+ qemu_del_net_filter(nf);
+ qemu_opts_del(opts);
+}
+
typedef int (NetFilterInit)(const NetFilterOptions *opts,
const char *name, int chain,
NetClientState *netdev, Error **errp);
diff --git a/qapi-schema.json b/qapi-schema.json
index d7fb578..9d97c21 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2537,6 +2537,53 @@
'opts': 'NetClientOptions' } }
##
+# @netfilter_add:
+#
+# Add a netfilter.
+#
+# @type: the type of netfilter.
+#
+# @id: the name of the new netfilter.
+#
+# @netdev: the name of the netdev which this filter will be attached to.
+#
+# @chain: #optional accept "in","out","all", if not specified, default is "all"
+# "in" means this filter will receive packets sent to the @netdev
+# "out" means this filter will receive packets sent from the @netdev
+# "all" means this filter will receive packets both sent to/from
+# the @netdev
+#
+# @props: #optional a list of properties to be passed to the netfilter in
+# the format of 'name=value'
+#
+# Since: 2.5
+#
+# Returns: Nothing on success
+# If @type is not a valid netfilter, DeviceNotFound
+##
+{ 'command': 'netfilter_add',
+ 'data': {
+ 'type': 'str',
+ 'id': 'str',
+ 'netdev': 'str',
+ '*chain': 'str',
+ '*props': '**'}, 'gen': false }
+
+##
+# @netfilter_del:
+#
+# Remove a netfilter.
+#
+# @id: the name of the netfilter to remove
+#
+# Returns: Nothing on success
+# If @id is not a valid netfilter, DeviceNotFound
+#
+# Since: 2.5
+##
+{ 'command': 'netfilter_del', 'data': {'id': 'str'} }
+
+##
# @NetFilterOptions
#
# A discriminated record of network filters.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ba630b1..4f0dc98 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -926,6 +926,63 @@ Example:
EQMP
{
+ .name = "netfilter_add",
+ .args_type = "netfilter:O",
+ .mhandler.cmd_new = qmp_netfilter_add,
+ },
+
+SQMP
+netfilter_add
+----------
+
+Add netfilter.
+
+Arguments:
+
+- "type": the filter type (json-string)
+- "id": the netfilter's ID, must be unique (json-string)
+- "netdev": the netdev's ID which this filter will be attached to(json-string)
+- filter options
+
+Example:
+
+-> { "execute": "netfilter_add",
+ "arguments": { "type": "type", "id": "nf0",
+ "netdev": "bn",
+ "chain": "in" } }
+<- { "return": {} }
+
+Note: The supported filter options are the same ones supported by the
+ '-netfilter' command-line argument, which are listed in the '-help'
+ output or QEMU's manual
+
+EQMP
+
+ {
+ .name = "netfilter_del",
+ .args_type = "id:s",
+ .mhandler.cmd_new = qmp_marshal_input_netfilter_del,
+ },
+
+SQMP
+netfilter_del
+----------
+
+Remove netfilter.
+
+Arguments:
+
+- "id": the netfilter's ID, must be unique (json-string)
+
+Example:
+
+-> { "execute": "netfilter_del", "arguments": { "id": "nf0" } }
+<- { "return": {} }
+
+
+EQMP
+
+ {
.name = "object-add",
.args_type = "qom-type:s,id:s,props:q?",
.mhandler.cmd_new = qmp_object_add,
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v2 4/9] net: add/remove filters from network backend
2015-07-31 4:13 [Qemu-devel] [PATCH v2 0/9] For QEMU 2.5: Add a netfilter object and netbuffer filter Yang Hongyang
` (2 preceding siblings ...)
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 3/9] netfilter: add netfilter_{add|del} commands Yang Hongyang
@ 2015-07-31 4:13 ` Yang Hongyang
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 5/9] netfilter: hook packets before net queue send Yang Hongyang
` (5 subsequent siblings)
9 siblings, 0 replies; 23+ messages in thread
From: Yang Hongyang @ 2015-07-31 4:13 UTC (permalink / raw)
To: qemu-devel
Cc: thuth, zhang.zhanghailiang, lizhijian, jasowang, mrhines,
stefanha, Yang Hongyang
add/remove filters from network backend
Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
---
include/net/net.h | 8 ++++++++
net/filter.c | 4 ++--
net/net.c | 38 ++++++++++++++++++++++++++++++++++++++
3 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/include/net/net.h b/include/net/net.h
index 6a6cbef..5c5c109 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -40,6 +40,11 @@ typedef struct NICConf {
/* Net clients */
+typedef struct Filter Filter;
+struct Filter {
+ NetFilterState *nf;
+ QTAILQ_ENTRY(Filter) next;
+};
typedef void (NetPoll)(NetClientState *, bool enable);
typedef int (NetCanReceive)(NetClientState *);
@@ -92,6 +97,7 @@ struct NetClientState {
NetClientDestructor *destructor;
unsigned int queue_index;
unsigned rxfilter_notify_enabled:1;
+ QTAILQ_HEAD(, Filter) filters;
};
typedef struct NICState {
@@ -109,6 +115,8 @@ NetClientState *qemu_new_net_client(NetClientInfo *info,
NetClientState *peer,
const char *model,
const char *name);
+int qemu_netdev_add_filter(NetClientState *nc, NetFilterState *nf);
+void qemu_netdev_remove_filter(NetClientState *nc, NetFilterState *nf);
NICState *qemu_new_nic(NetClientInfo *info,
NICConf *conf,
const char *model,
diff --git a/net/filter.c b/net/filter.c
index 18d1c8f..b3a2285 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -37,14 +37,14 @@ NetFilterState *qemu_new_net_filter(NetFilterInfo *info,
nf->netdev = netdev;
nf->chain = chain;
QTAILQ_INSERT_TAIL(&net_filters, nf, next);
- /* TODO: attach netfilter to netdev */
+ qemu_netdev_add_filter(netdev, nf);
return nf;
}
static void qemu_cleanup_net_filter(NetFilterState *nf)
{
- /* TODO: remove netfilter from netdev */
+ qemu_netdev_remove_filter(nf->netdev, nf);
QTAILQ_REMOVE(&net_filters, nf, next);
diff --git a/net/net.c b/net/net.c
index 28a5597..22748e0 100644
--- a/net/net.c
+++ b/net/net.c
@@ -287,6 +287,7 @@ static void qemu_net_client_setup(NetClientState *nc,
nc->incoming_queue = qemu_new_net_queue(nc);
nc->destructor = destructor;
+ QTAILQ_INIT(&nc->filters);
}
NetClientState *qemu_new_net_client(NetClientInfo *info,
@@ -305,6 +306,38 @@ NetClientState *qemu_new_net_client(NetClientInfo *info,
return nc;
}
+int qemu_netdev_add_filter(NetClientState *nc, NetFilterState *nf)
+{
+ Filter *filter = g_malloc0(sizeof(*filter));
+
+ filter->nf = nf;
+ QTAILQ_INSERT_TAIL(&nc->filters, filter, next);
+ return 0;
+}
+
+static void remove_filter(NetClientState *nc, Filter *filter)
+{
+ if (!filter) {
+ return;
+ }
+
+ QTAILQ_REMOVE(&nc->filters, filter, next);
+ g_free(filter);
+}
+
+void qemu_netdev_remove_filter(NetClientState *nc, NetFilterState *nf)
+{
+ Filter *filter = NULL;
+
+ QTAILQ_FOREACH(filter, &nc->filters, next) {
+ if (filter->nf == nf) {
+ break;
+ }
+ }
+
+ remove_filter(nc, filter);
+}
+
NICState *qemu_new_nic(NetClientInfo *info,
NICConf *conf,
const char *model,
@@ -367,6 +400,8 @@ static void qemu_cleanup_net_client(NetClientState *nc)
static void qemu_free_net_client(NetClientState *nc)
{
+ Filter *filter, *next;
+
if (nc->incoming_queue) {
qemu_del_net_queue(nc->incoming_queue);
}
@@ -375,6 +410,9 @@ static void qemu_free_net_client(NetClientState *nc)
}
g_free(nc->name);
g_free(nc->model);
+ QTAILQ_FOREACH_SAFE(filter, &nc->filters, next, next) {
+ remove_filter(nc, filter);
+ }
if (nc->destructor) {
nc->destructor(nc);
}
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v2 5/9] netfilter: hook packets before net queue send
2015-07-31 4:13 [Qemu-devel] [PATCH v2 0/9] For QEMU 2.5: Add a netfilter object and netbuffer filter Yang Hongyang
` (3 preceding siblings ...)
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 4/9] net: add/remove filters from network backend Yang Hongyang
@ 2015-07-31 4:13 ` Yang Hongyang
2015-07-31 6:06 ` Jason Wang
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 6/9] net/queue: export qemu_net_queue_append_iov Yang Hongyang
` (4 subsequent siblings)
9 siblings, 1 reply; 23+ messages in thread
From: Yang Hongyang @ 2015-07-31 4:13 UTC (permalink / raw)
To: qemu-devel
Cc: thuth, zhang.zhanghailiang, lizhijian, jasowang, mrhines,
stefanha, Yang Hongyang
Capture packets that will be sent.
Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
---
include/net/filter.h | 8 +++++++
net/filter.c | 1 +
net/net.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 75 insertions(+), 1 deletion(-)
diff --git a/include/net/filter.h b/include/net/filter.h
index 1b6f896..93579c1 100644
--- a/include/net/filter.h
+++ b/include/net/filter.h
@@ -19,11 +19,19 @@ enum {
};
typedef void (FilterCleanup) (NetFilterState *);
+/*
+ * Return:
+ * 0: finished handling the packet, we should continue
+ * size: filter stolen this packet, we stop pass this packet further
+ */
+typedef ssize_t (FilterReceiveIOV)(NetFilterState *, NetClientState *sender,
+ unsigned flags, const struct iovec *, int);
typedef struct NetFilterInfo {
NetFilterOptionsKind type;
size_t size;
FilterCleanup *cleanup;
+ FilterReceiveIOV *receive_iov;
} NetFilterInfo;
struct NetFilterState {
diff --git a/net/filter.c b/net/filter.c
index b3a2285..1ae9344 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -29,6 +29,7 @@ NetFilterState *qemu_new_net_filter(NetFilterInfo *info,
NetFilterState *nf;
assert(info->size >= sizeof(NetFilterState));
+ assert(info->receive_iov);
nf = g_malloc0(info->size);
nf->info = info;
diff --git a/net/net.c b/net/net.c
index 22748e0..b55d934 100644
--- a/net/net.c
+++ b/net/net.c
@@ -24,6 +24,7 @@
#include "config-host.h"
#include "net/net.h"
+#include "net/filter.h"
#include "clients.h"
#include "hub.h"
#include "net/slirp.h"
@@ -592,6 +593,42 @@ int qemu_can_send_packet(NetClientState *sender)
return 1;
}
+static ssize_t filter_receive_iov(NetClientState *nc, int chain,
+ NetClientState *sender,
+ unsigned flags,
+ const struct iovec *iov,
+ int iovcnt) {
+ ssize_t ret = 0;
+ Filter *filter = NULL;
+ NetFilterState *nf = NULL;
+ ssize_t size = iov_size(iov, iovcnt);
+
+ QTAILQ_FOREACH(filter, &nc->filters, next) {
+ nf = filter->nf;
+ if (nf->chain == chain || nf->chain == NET_FILTER_ALL) {
+ ret = nf->info->receive_iov(nf, sender, flags, iov, iovcnt);
+ if (ret == size) {
+ return ret;
+ }
+ }
+ }
+
+ return ret;
+}
+
+static ssize_t filter_receive(NetClientState *nc, int chain,
+ NetClientState *sender,
+ unsigned flags,
+ const uint8_t *data,
+ size_t size) {
+ struct iovec iov = {
+ .iov_base = (void *)data,
+ .iov_len = size
+ };
+
+ return filter_receive_iov(nc, chain, sender, flags, &iov, 1);
+}
+
ssize_t qemu_deliver_packet(NetClientState *sender,
unsigned flags,
const uint8_t *data,
@@ -663,6 +700,7 @@ static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender,
NetPacketSent *sent_cb)
{
NetQueue *queue;
+ int ret;
#ifdef DEBUG_NET
printf("qemu_send_packet_async:\n");
@@ -673,6 +711,18 @@ static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender,
return size;
}
+ /* Let filters handle the packet first */
+ ret = filter_receive(sender, NET_FILTER_OUT, sender, flags, buf, size);
+ if (ret == size) {
+ return size;
+ }
+
+ ret = filter_receive(sender->peer, NET_FILTER_IN,
+ sender, flags, buf, size);
+ if (ret == size) {
+ return size;
+ }
+
queue = sender->peer->incoming_queue;
return qemu_net_queue_send(queue, sender, flags, buf, size, sent_cb);
@@ -743,9 +793,24 @@ ssize_t qemu_sendv_packet_async(NetClientState *sender,
NetPacketSent *sent_cb)
{
NetQueue *queue;
+ int size = iov_size(iov, iovcnt);
+ int ret;
if (sender->link_down || !sender->peer) {
- return iov_size(iov, iovcnt);
+ return size;
+ }
+
+ /* Let filters handle the packet first */
+ ret = filter_receive_iov(sender, NET_FILTER_OUT,
+ sender, QEMU_NET_PACKET_FLAG_NONE, iov, iovcnt);
+ if (ret == size) {
+ return size;
+ }
+
+ ret = filter_receive_iov(sender->peer, NET_FILTER_IN,
+ sender, QEMU_NET_PACKET_FLAG_NONE, iov, iovcnt);
+ if (ret == size) {
+ return size;
}
queue = sender->peer->incoming_queue;
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v2 5/9] netfilter: hook packets before net queue send
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 5/9] netfilter: hook packets before net queue send Yang Hongyang
@ 2015-07-31 6:06 ` Jason Wang
2015-07-31 8:24 ` Yang Hongyang
0 siblings, 1 reply; 23+ messages in thread
From: Jason Wang @ 2015-07-31 6:06 UTC (permalink / raw)
To: Yang Hongyang, qemu-devel
Cc: thuth, zhang.zhanghailiang, lizhijian, mrhines, stefanha
On 07/31/2015 12:13 PM, Yang Hongyang wrote:
> Capture packets that will be sent.
>
> Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
> ---
> include/net/filter.h | 8 +++++++
> net/filter.c | 1 +
> net/net.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++-
> 3 files changed, 75 insertions(+), 1 deletion(-)
>
> diff --git a/include/net/filter.h b/include/net/filter.h
> index 1b6f896..93579c1 100644
> --- a/include/net/filter.h
> +++ b/include/net/filter.h
> @@ -19,11 +19,19 @@ enum {
> };
>
> typedef void (FilterCleanup) (NetFilterState *);
> +/*
> + * Return:
> + * 0: finished handling the packet, we should continue
> + * size: filter stolen this packet, we stop pass this packet further
> + */
> +typedef ssize_t (FilterReceiveIOV)(NetFilterState *, NetClientState *sender,
> + unsigned flags, const struct iovec *, int);
>
> typedef struct NetFilterInfo {
> NetFilterOptionsKind type;
> size_t size;
> FilterCleanup *cleanup;
> + FilterReceiveIOV *receive_iov;
Please move this to patch 2.
> } NetFilterInfo;
>
> struct NetFilterState {
> diff --git a/net/filter.c b/net/filter.c
> index b3a2285..1ae9344 100644
> --- a/net/filter.c
> +++ b/net/filter.c
> @@ -29,6 +29,7 @@ NetFilterState *qemu_new_net_filter(NetFilterInfo *info,
> NetFilterState *nf;
>
> assert(info->size >= sizeof(NetFilterState));
> + assert(info->receive_iov);
>
> nf = g_malloc0(info->size);
> nf->info = info;
> diff --git a/net/net.c b/net/net.c
> index 22748e0..b55d934 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -24,6 +24,7 @@
> #include "config-host.h"
>
> #include "net/net.h"
> +#include "net/filter.h"
> #include "clients.h"
> #include "hub.h"
> #include "net/slirp.h"
> @@ -592,6 +593,42 @@ int qemu_can_send_packet(NetClientState *sender)
> return 1;
> }
>
> +static ssize_t filter_receive_iov(NetClientState *nc, int chain,
> + NetClientState *sender,
> + unsigned flags,
> + const struct iovec *iov,
> + int iovcnt) {
> + ssize_t ret = 0;
> + Filter *filter = NULL;
> + NetFilterState *nf = NULL;
> + ssize_t size = iov_size(iov, iovcnt);
> +
> + QTAILQ_FOREACH(filter, &nc->filters, next) {
> + nf = filter->nf;
> + if (nf->chain == chain || nf->chain == NET_FILTER_ALL) {
> + ret = nf->info->receive_iov(nf, sender, flags, iov, iovcnt);
> + if (ret == size) {
> + return ret;
> + }
> + }
> + }
So if a packet is being stolen or blocked by one filter, it could only
be flushed to destination? I think we need an API to flush it into next
filter.
> +
> + return ret;
> +}
> +
> +static ssize_t filter_receive(NetClientState *nc, int chain,
> + NetClientState *sender,
> + unsigned flags,
> + const uint8_t *data,
> + size_t size) {
> + struct iovec iov = {
> + .iov_base = (void *)data,
> + .iov_len = size
> + };
> +
> + return filter_receive_iov(nc, chain, sender, flags, &iov, 1);
> +}
> +
> ssize_t qemu_deliver_packet(NetClientState *sender,
> unsigned flags,
> const uint8_t *data,
> @@ -663,6 +700,7 @@ static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender,
> NetPacketSent *sent_cb)
> {
> NetQueue *queue;
> + int ret;
>
> #ifdef DEBUG_NET
> printf("qemu_send_packet_async:\n");
> @@ -673,6 +711,18 @@ static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender,
> return size;
> }
>
> + /* Let filters handle the packet first */
> + ret = filter_receive(sender, NET_FILTER_OUT, sender, flags, buf, size);
> + if (ret == size) {
> + return size;
> + }
> +
> + ret = filter_receive(sender->peer, NET_FILTER_IN,
> + sender, flags, buf, size);
> + if (ret == size) {
> + return size;
> + }
> +
> queue = sender->peer->incoming_queue;
>
> return qemu_net_queue_send(queue, sender, flags, buf, size, sent_cb);
> @@ -743,9 +793,24 @@ ssize_t qemu_sendv_packet_async(NetClientState *sender,
> NetPacketSent *sent_cb)
> {
> NetQueue *queue;
> + int size = iov_size(iov, iovcnt);
> + int ret;
>
> if (sender->link_down || !sender->peer) {
> - return iov_size(iov, iovcnt);
> + return size;
> + }
> +
> + /* Let filters handle the packet first */
> + ret = filter_receive_iov(sender, NET_FILTER_OUT,
> + sender, QEMU_NET_PACKET_FLAG_NONE, iov, iovcnt);
> + if (ret == size) {
> + return size;
> + }
> +
> + ret = filter_receive_iov(sender->peer, NET_FILTER_IN,
> + sender, QEMU_NET_PACKET_FLAG_NONE, iov, iovcnt);
> + if (ret == size) {
> + return size;
> }
>
> queue = sender->peer->incoming_queue;
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v2 5/9] netfilter: hook packets before net queue send
2015-07-31 6:06 ` Jason Wang
@ 2015-07-31 8:24 ` Yang Hongyang
2015-07-31 9:09 ` Jason Wang
0 siblings, 1 reply; 23+ messages in thread
From: Yang Hongyang @ 2015-07-31 8:24 UTC (permalink / raw)
To: Jason Wang, qemu-devel
Cc: thuth, zhang.zhanghailiang, lizhijian, mrhines, stefanha
On 07/31/2015 02:06 PM, Jason Wang wrote:
>
>
> On 07/31/2015 12:13 PM, Yang Hongyang wrote:
>> Capture packets that will be sent.
>>
>> Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
>> ---
>> include/net/filter.h | 8 +++++++
>> net/filter.c | 1 +
>> net/net.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++-
>> 3 files changed, 75 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/net/filter.h b/include/net/filter.h
>> index 1b6f896..93579c1 100644
>> --- a/include/net/filter.h
>> +++ b/include/net/filter.h
>> @@ -19,11 +19,19 @@ enum {
>> };
>>
>> typedef void (FilterCleanup) (NetFilterState *);
>> +/*
>> + * Return:
>> + * 0: finished handling the packet, we should continue
>> + * size: filter stolen this packet, we stop pass this packet further
>> + */
>> +typedef ssize_t (FilterReceiveIOV)(NetFilterState *, NetClientState *sender,
>> + unsigned flags, const struct iovec *, int);
>>
>> typedef struct NetFilterInfo {
>> NetFilterOptionsKind type;
>> size_t size;
>> FilterCleanup *cleanup;
>> + FilterReceiveIOV *receive_iov;
>
> Please move this to patch 2.
Ok, thanks!
>
>> } NetFilterInfo;
>>
>> struct NetFilterState {
>> diff --git a/net/filter.c b/net/filter.c
>> index b3a2285..1ae9344 100644
>> --- a/net/filter.c
>> +++ b/net/filter.c
>> @@ -29,6 +29,7 @@ NetFilterState *qemu_new_net_filter(NetFilterInfo *info,
>> NetFilterState *nf;
>>
>> assert(info->size >= sizeof(NetFilterState));
>> + assert(info->receive_iov);
>>
>> nf = g_malloc0(info->size);
>> nf->info = info;
>> diff --git a/net/net.c b/net/net.c
>> index 22748e0..b55d934 100644
>> --- a/net/net.c
>> +++ b/net/net.c
>> @@ -24,6 +24,7 @@
>> #include "config-host.h"
>>
>> #include "net/net.h"
>> +#include "net/filter.h"
>> #include "clients.h"
>> #include "hub.h"
>> #include "net/slirp.h"
>> @@ -592,6 +593,42 @@ int qemu_can_send_packet(NetClientState *sender)
>> return 1;
>> }
>>
>> +static ssize_t filter_receive_iov(NetClientState *nc, int chain,
>> + NetClientState *sender,
>> + unsigned flags,
>> + const struct iovec *iov,
>> + int iovcnt) {
>> + ssize_t ret = 0;
>> + Filter *filter = NULL;
>> + NetFilterState *nf = NULL;
>> + ssize_t size = iov_size(iov, iovcnt);
>> +
>> + QTAILQ_FOREACH(filter, &nc->filters, next) {
>> + nf = filter->nf;
>> + if (nf->chain == chain || nf->chain == NET_FILTER_ALL) {
>> + ret = nf->info->receive_iov(nf, sender, flags, iov, iovcnt);
>> + if (ret == size) {
>> + return ret;
>> + }
>> + }
>> + }
>
> So if a packet is being stolen or blocked by one filter, it could only
> be flushed to destination? I think we need an API to flush it into next
> filter.
Yes, we could, just call next filter's receive_iov, do I need to introduce
the API now in this series? or introduce later when we actually need it?
>
>> +
>> + return ret;
>> +}
>> +
>> +static ssize_t filter_receive(NetClientState *nc, int chain,
>> + NetClientState *sender,
>> + unsigned flags,
>> + const uint8_t *data,
>> + size_t size) {
>> + struct iovec iov = {
>> + .iov_base = (void *)data,
>> + .iov_len = size
>> + };
>> +
>> + return filter_receive_iov(nc, chain, sender, flags, &iov, 1);
>> +}
>> +
>> ssize_t qemu_deliver_packet(NetClientState *sender,
>> unsigned flags,
>> const uint8_t *data,
>> @@ -663,6 +700,7 @@ static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender,
>> NetPacketSent *sent_cb)
>> {
>> NetQueue *queue;
>> + int ret;
>>
>> #ifdef DEBUG_NET
>> printf("qemu_send_packet_async:\n");
>> @@ -673,6 +711,18 @@ static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender,
>> return size;
>> }
>>
>> + /* Let filters handle the packet first */
>> + ret = filter_receive(sender, NET_FILTER_OUT, sender, flags, buf, size);
>> + if (ret == size) {
>> + return size;
>> + }
>> +
>> + ret = filter_receive(sender->peer, NET_FILTER_IN,
>> + sender, flags, buf, size);
>> + if (ret == size) {
>> + return size;
>> + }
>> +
>> queue = sender->peer->incoming_queue;
>>
>> return qemu_net_queue_send(queue, sender, flags, buf, size, sent_cb);
>> @@ -743,9 +793,24 @@ ssize_t qemu_sendv_packet_async(NetClientState *sender,
>> NetPacketSent *sent_cb)
>> {
>> NetQueue *queue;
>> + int size = iov_size(iov, iovcnt);
>> + int ret;
>>
>> if (sender->link_down || !sender->peer) {
>> - return iov_size(iov, iovcnt);
>> + return size;
>> + }
>> +
>> + /* Let filters handle the packet first */
>> + ret = filter_receive_iov(sender, NET_FILTER_OUT,
>> + sender, QEMU_NET_PACKET_FLAG_NONE, iov, iovcnt);
>> + if (ret == size) {
>> + return size;
>> + }
>> +
>> + ret = filter_receive_iov(sender->peer, NET_FILTER_IN,
>> + sender, QEMU_NET_PACKET_FLAG_NONE, iov, iovcnt);
>> + if (ret == size) {
>> + return size;
>> }
>>
>> queue = sender->peer->incoming_queue;
>
> .
>
--
Thanks,
Yang.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v2 5/9] netfilter: hook packets before net queue send
2015-07-31 8:24 ` Yang Hongyang
@ 2015-07-31 9:09 ` Jason Wang
2015-07-31 9:58 ` Yang Hongyang
0 siblings, 1 reply; 23+ messages in thread
From: Jason Wang @ 2015-07-31 9:09 UTC (permalink / raw)
To: Yang Hongyang, qemu-devel
Cc: thuth, zhang.zhanghailiang, lizhijian, mrhines, stefanha
On 07/31/2015 04:24 PM, Yang Hongyang wrote:
>
>
> On 07/31/2015 02:06 PM, Jason Wang wrote:
>>
>>
>> On 07/31/2015 12:13 PM, Yang Hongyang wrote:
>>> Capture packets that will be sent.
>>>
>>> Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
>>> ---
>>> include/net/filter.h | 8 +++++++
>>> net/filter.c | 1 +
>>> net/net.c | 67
>>> +++++++++++++++++++++++++++++++++++++++++++++++++++-
>>> 3 files changed, 75 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/include/net/filter.h b/include/net/filter.h
>>> index 1b6f896..93579c1 100644
>>> --- a/include/net/filter.h
>>> +++ b/include/net/filter.h
>>> @@ -19,11 +19,19 @@ enum {
>>> };
>>>
>>> typedef void (FilterCleanup) (NetFilterState *);
>>> +/*
>>> + * Return:
>>> + * 0: finished handling the packet, we should continue
>>> + * size: filter stolen this packet, we stop pass this packet further
>>> + */
>>> +typedef ssize_t (FilterReceiveIOV)(NetFilterState *, NetClientState
>>> *sender,
>>> + unsigned flags, const struct
>>> iovec *, int);
>>>
>>> typedef struct NetFilterInfo {
>>> NetFilterOptionsKind type;
>>> size_t size;
>>> FilterCleanup *cleanup;
>>> + FilterReceiveIOV *receive_iov;
>>
>> Please move this to patch 2.
>
> Ok, thanks!
>
>>
>>> } NetFilterInfo;
>>>
>>> struct NetFilterState {
>>> diff --git a/net/filter.c b/net/filter.c
>>> index b3a2285..1ae9344 100644
>>> --- a/net/filter.c
>>> +++ b/net/filter.c
>>> @@ -29,6 +29,7 @@ NetFilterState *qemu_new_net_filter(NetFilterInfo
>>> *info,
>>> NetFilterState *nf;
>>>
>>> assert(info->size >= sizeof(NetFilterState));
>>> + assert(info->receive_iov);
>>>
>>> nf = g_malloc0(info->size);
>>> nf->info = info;
>>> diff --git a/net/net.c b/net/net.c
>>> index 22748e0..b55d934 100644
>>> --- a/net/net.c
>>> +++ b/net/net.c
>>> @@ -24,6 +24,7 @@
>>> #include "config-host.h"
>>>
>>> #include "net/net.h"
>>> +#include "net/filter.h"
>>> #include "clients.h"
>>> #include "hub.h"
>>> #include "net/slirp.h"
>>> @@ -592,6 +593,42 @@ int qemu_can_send_packet(NetClientState *sender)
>>> return 1;
>>> }
>>>
>>> +static ssize_t filter_receive_iov(NetClientState *nc, int chain,
>>> + NetClientState *sender,
>>> + unsigned flags,
>>> + const struct iovec *iov,
>>> + int iovcnt) {
>>> + ssize_t ret = 0;
>>> + Filter *filter = NULL;
>>> + NetFilterState *nf = NULL;
>>> + ssize_t size = iov_size(iov, iovcnt);
>>> +
>>> + QTAILQ_FOREACH(filter, &nc->filters, next) {
>>> + nf = filter->nf;
>>> + if (nf->chain == chain || nf->chain == NET_FILTER_ALL) {
>>> + ret = nf->info->receive_iov(nf, sender, flags, iov,
>>> iovcnt);
>>> + if (ret == size) {
>>> + return ret;
>>> + }
>>> + }
>>> + }
>>
>> So if a packet is being stolen or blocked by one filter, it could only
>> be flushed to destination? I think we need an API to flush it into next
>> filter.
>
> Yes, we could, just call next filter's receive_iov, do I need to
> introduce
> the API now in this series? or introduce later when we actually need it?
Consider it is a public API. better in this patch.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v2 5/9] netfilter: hook packets before net queue send
2015-07-31 9:09 ` Jason Wang
@ 2015-07-31 9:58 ` Yang Hongyang
0 siblings, 0 replies; 23+ messages in thread
From: Yang Hongyang @ 2015-07-31 9:58 UTC (permalink / raw)
To: Jason Wang, qemu-devel
Cc: thuth, zhang.zhanghailiang, lizhijian, mrhines, stefanha
On 07/31/2015 05:09 PM, Jason Wang wrote:
>
>
> On 07/31/2015 04:24 PM, Yang Hongyang wrote:
>>
>>
>> On 07/31/2015 02:06 PM, Jason Wang wrote:
>>>
>>>
>>> On 07/31/2015 12:13 PM, Yang Hongyang wrote:
>>>> Capture packets that will be sent.
>>>>
>>>> Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
>>>> ---
>>>> include/net/filter.h | 8 +++++++
>>>> net/filter.c | 1 +
>>>> net/net.c | 67
>>>> +++++++++++++++++++++++++++++++++++++++++++++++++++-
>>>> 3 files changed, 75 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/include/net/filter.h b/include/net/filter.h
>>>> index 1b6f896..93579c1 100644
>>>> --- a/include/net/filter.h
>>>> +++ b/include/net/filter.h
>>>> @@ -19,11 +19,19 @@ enum {
>>>> };
>>>>
>>>> typedef void (FilterCleanup) (NetFilterState *);
>>>> +/*
>>>> + * Return:
>>>> + * 0: finished handling the packet, we should continue
>>>> + * size: filter stolen this packet, we stop pass this packet further
>>>> + */
>>>> +typedef ssize_t (FilterReceiveIOV)(NetFilterState *, NetClientState
>>>> *sender,
>>>> + unsigned flags, const struct
>>>> iovec *, int);
>>>>
>>>> typedef struct NetFilterInfo {
>>>> NetFilterOptionsKind type;
>>>> size_t size;
>>>> FilterCleanup *cleanup;
>>>> + FilterReceiveIOV *receive_iov;
>>>
>>> Please move this to patch 2.
>>
>> Ok, thanks!
>>
>>>
>>>> } NetFilterInfo;
>>>>
>>>> struct NetFilterState {
>>>> diff --git a/net/filter.c b/net/filter.c
>>>> index b3a2285..1ae9344 100644
>>>> --- a/net/filter.c
>>>> +++ b/net/filter.c
>>>> @@ -29,6 +29,7 @@ NetFilterState *qemu_new_net_filter(NetFilterInfo
>>>> *info,
>>>> NetFilterState *nf;
>>>>
>>>> assert(info->size >= sizeof(NetFilterState));
>>>> + assert(info->receive_iov);
>>>>
>>>> nf = g_malloc0(info->size);
>>>> nf->info = info;
>>>> diff --git a/net/net.c b/net/net.c
>>>> index 22748e0..b55d934 100644
>>>> --- a/net/net.c
>>>> +++ b/net/net.c
>>>> @@ -24,6 +24,7 @@
>>>> #include "config-host.h"
>>>>
>>>> #include "net/net.h"
>>>> +#include "net/filter.h"
>>>> #include "clients.h"
>>>> #include "hub.h"
>>>> #include "net/slirp.h"
>>>> @@ -592,6 +593,42 @@ int qemu_can_send_packet(NetClientState *sender)
>>>> return 1;
>>>> }
>>>>
>>>> +static ssize_t filter_receive_iov(NetClientState *nc, int chain,
>>>> + NetClientState *sender,
>>>> + unsigned flags,
>>>> + const struct iovec *iov,
>>>> + int iovcnt) {
>>>> + ssize_t ret = 0;
>>>> + Filter *filter = NULL;
>>>> + NetFilterState *nf = NULL;
>>>> + ssize_t size = iov_size(iov, iovcnt);
>>>> +
>>>> + QTAILQ_FOREACH(filter, &nc->filters, next) {
>>>> + nf = filter->nf;
>>>> + if (nf->chain == chain || nf->chain == NET_FILTER_ALL) {
>>>> + ret = nf->info->receive_iov(nf, sender, flags, iov,
>>>> iovcnt);
>>>> + if (ret == size) {
>>>> + return ret;
>>>> + }
>>>> + }
>>>> + }
>>>
>>> So if a packet is being stolen or blocked by one filter, it could only
>>> be flushed to destination? I think we need an API to flush it into next
>>> filter.
>>
>> Yes, we could, just call next filter's receive_iov, do I need to
>> introduce
>> the API now in this series? or introduce later when we actually need it?
>
> Consider it is a public API. better in this patch.
Ok, thanks, will add a patch to do this.
> .
>
--
Thanks,
Yang.
^ permalink raw reply [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v2 6/9] net/queue: export qemu_net_queue_append_iov
2015-07-31 4:13 [Qemu-devel] [PATCH v2 0/9] For QEMU 2.5: Add a netfilter object and netbuffer filter Yang Hongyang
` (4 preceding siblings ...)
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 5/9] netfilter: hook packets before net queue send Yang Hongyang
@ 2015-07-31 4:13 ` Yang Hongyang
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 7/9] move out net queue structs define Yang Hongyang
` (3 subsequent siblings)
9 siblings, 0 replies; 23+ messages in thread
From: Yang Hongyang @ 2015-07-31 4:13 UTC (permalink / raw)
To: qemu-devel
Cc: thuth, zhang.zhanghailiang, lizhijian, jasowang, mrhines,
stefanha, Yang Hongyang
Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
---
include/net/queue.h | 7 +++++++
net/queue.c | 12 ++++++------
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/include/net/queue.h b/include/net/queue.h
index fc02b33..f10fab0 100644
--- a/include/net/queue.h
+++ b/include/net/queue.h
@@ -36,6 +36,13 @@ typedef void (NetPacketSent) (NetClientState *sender, ssize_t ret);
NetQueue *qemu_new_net_queue(void *opaque);
+void qemu_net_queue_append_iov(NetQueue *queue,
+ NetClientState *sender,
+ unsigned flags,
+ const struct iovec *iov,
+ int iovcnt,
+ NetPacketSent *sent_cb);
+
void qemu_del_net_queue(NetQueue *queue);
ssize_t qemu_net_queue_send(NetQueue *queue,
diff --git a/net/queue.c b/net/queue.c
index ebbe2bb..c34a3e0 100644
--- a/net/queue.c
+++ b/net/queue.c
@@ -110,12 +110,12 @@ static void qemu_net_queue_append(NetQueue *queue,
QTAILQ_INSERT_TAIL(&queue->packets, packet, entry);
}
-static void qemu_net_queue_append_iov(NetQueue *queue,
- NetClientState *sender,
- unsigned flags,
- const struct iovec *iov,
- int iovcnt,
- NetPacketSent *sent_cb)
+void qemu_net_queue_append_iov(NetQueue *queue,
+ NetClientState *sender,
+ unsigned flags,
+ const struct iovec *iov,
+ int iovcnt,
+ NetPacketSent *sent_cb)
{
NetPacket *packet;
size_t max_len = 0;
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v2 7/9] move out net queue structs define
2015-07-31 4:13 [Qemu-devel] [PATCH v2 0/9] For QEMU 2.5: Add a netfilter object and netbuffer filter Yang Hongyang
` (5 preceding siblings ...)
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 6/9] net/queue: export qemu_net_queue_append_iov Yang Hongyang
@ 2015-07-31 4:13 ` Yang Hongyang
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 8/9] netfilter: add a netbuffer filter Yang Hongyang
` (2 subsequent siblings)
9 siblings, 0 replies; 23+ messages in thread
From: Yang Hongyang @ 2015-07-31 4:13 UTC (permalink / raw)
To: qemu-devel
Cc: thuth, zhang.zhanghailiang, lizhijian, jasowang, mrhines,
stefanha, Yang Hongyang
Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
---
include/net/queue.h | 19 +++++++++++++++++++
net/queue.c | 19 -------------------
2 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/include/net/queue.h b/include/net/queue.h
index f10fab0..e139cc7 100644
--- a/include/net/queue.h
+++ b/include/net/queue.h
@@ -31,6 +31,25 @@ typedef struct NetQueue NetQueue;
typedef void (NetPacketSent) (NetClientState *sender, ssize_t ret);
+struct NetPacket {
+ QTAILQ_ENTRY(NetPacket) entry;
+ NetClientState *sender;
+ unsigned flags;
+ int size;
+ NetPacketSent *sent_cb;
+ uint8_t data[0];
+};
+
+struct NetQueue {
+ void *opaque;
+ uint32_t nq_maxlen;
+ uint32_t nq_count;
+
+ QTAILQ_HEAD(packets, NetPacket) packets;
+
+ unsigned delivering:1;
+};
+
#define QEMU_NET_PACKET_FLAG_NONE 0
#define QEMU_NET_PACKET_FLAG_RAW (1<<0)
diff --git a/net/queue.c b/net/queue.c
index c34a3e0..428fdd6 100644
--- a/net/queue.c
+++ b/net/queue.c
@@ -39,25 +39,6 @@
* unbounded queueing.
*/
-struct NetPacket {
- QTAILQ_ENTRY(NetPacket) entry;
- NetClientState *sender;
- unsigned flags;
- int size;
- NetPacketSent *sent_cb;
- uint8_t data[0];
-};
-
-struct NetQueue {
- void *opaque;
- uint32_t nq_maxlen;
- uint32_t nq_count;
-
- QTAILQ_HEAD(packets, NetPacket) packets;
-
- unsigned delivering : 1;
-};
-
NetQueue *qemu_new_net_queue(void *opaque)
{
NetQueue *queue;
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v2 8/9] netfilter: add a netbuffer filter
2015-07-31 4:13 [Qemu-devel] [PATCH v2 0/9] For QEMU 2.5: Add a netfilter object and netbuffer filter Yang Hongyang
` (6 preceding siblings ...)
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 7/9] move out net queue structs define Yang Hongyang
@ 2015-07-31 4:13 ` Yang Hongyang
2015-07-31 6:08 ` Jason Wang
2015-07-31 18:58 ` Dr. David Alan Gilbert
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 9/9] filter/buffer: update command description and help Yang Hongyang
2015-07-31 5:58 ` [Qemu-devel] [PATCH v2 0/9] For QEMU 2.5: Add a netfilter object and netbuffer filter Jason Wang
9 siblings, 2 replies; 23+ messages in thread
From: Yang Hongyang @ 2015-07-31 4:13 UTC (permalink / raw)
To: qemu-devel
Cc: thuth, zhang.zhanghailiang, lizhijian, jasowang, mrhines,
stefanha, Yang Hongyang
This filter is to buffer/release packets, this feature can be used
when using MicroCheckpointing, or other Remus like VM FT solutions, you
can also use it to simulate the network delay.
It has an interval option, if supplied, this filter will release
packets by interval.
Usage:
-netdev tap,id=bn0
-netfilter buffer,id=f0,netdev=bn0,chain=in,interval=1000
NOTE:
the scale of interval is microsecond.
Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
---
net/Makefile.objs | 1 +
net/filter-buffer.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++
net/filter.c | 2 +
net/filters.h | 17 ++++++
qapi-schema.json | 18 +++++-
5 files changed, 197 insertions(+), 1 deletion(-)
create mode 100644 net/filter-buffer.c
create mode 100644 net/filters.h
diff --git a/net/Makefile.objs b/net/Makefile.objs
index 914aec0..5fa2f97 100644
--- a/net/Makefile.objs
+++ b/net/Makefile.objs
@@ -14,3 +14,4 @@ common-obj-$(CONFIG_SLIRP) += slirp.o
common-obj-$(CONFIG_VDE) += vde.o
common-obj-$(CONFIG_NETMAP) += netmap.o
common-obj-y += filter.o
+common-obj-y += filter-buffer.o
diff --git a/net/filter-buffer.c b/net/filter-buffer.c
new file mode 100644
index 0000000..7f2b050
--- /dev/null
+++ b/net/filter-buffer.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2015 FUJITSU LIMITED
+ * Author: Yang Hongyang <yanghy@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 "net/filter.h"
+#include "net/queue.h"
+#include "filters.h"
+#include "qemu-common.h"
+#include "qemu/error-report.h"
+#include "qemu/main-loop.h"
+#include "qemu/timer.h"
+#include "qemu/iov.h"
+
+typedef struct FILTERBUFFERState {
+ NetFilterState nf;
+ NetQueue *incoming_queue;
+ NetQueue *inflight_queue;
+ QEMUBH *flush_bh;
+ int64_t interval;
+ QEMUTimer release_timer;
+} FILTERBUFFERState;
+
+static void packet_send_completed(NetClientState *nc, ssize_t len)
+{
+ return;
+}
+
+static void filter_buffer_flush(NetFilterState *nf)
+{
+ FILTERBUFFERState *s = DO_UPCAST(FILTERBUFFERState, nf, nf);
+ NetQueue *queue = s->inflight_queue;
+ NetPacket *packet;
+
+ while (queue && !QTAILQ_EMPTY(&queue->packets)) {
+ packet = QTAILQ_FIRST(&queue->packets);
+ QTAILQ_REMOVE(&queue->packets, packet, entry);
+ queue->nq_count--;
+
+ qemu_net_queue_send(packet->sender->peer->incoming_queue,
+ packet->sender,
+ packet->flags,
+ packet->data,
+ packet->size,
+ packet->sent_cb);
+
+ /*
+ * now that we pass the packet to sender->peer->incoming_queue, we
+ * don't care the reture value here, because the peer's queue will
+ * take care of this packet
+ */
+ g_free(packet);
+ }
+
+ g_free(queue);
+ s->inflight_queue = NULL;
+}
+
+static void filter_buffer_flush_bh(void *opaque)
+{
+ FILTERBUFFERState *s = opaque;
+ NetFilterState *nf = &s->nf;
+ filter_buffer_flush(nf);
+}
+
+static void filter_buffer_release_one(NetFilterState *nf)
+{
+ FILTERBUFFERState *s = DO_UPCAST(FILTERBUFFERState, nf, nf);
+
+ /* flush inflight packets */
+ if (s->inflight_queue) {
+ filter_buffer_flush(nf);
+ }
+
+ s->inflight_queue = s->incoming_queue;
+ s->incoming_queue = qemu_new_net_queue(nf);
+ qemu_bh_schedule(s->flush_bh);
+}
+
+static void filter_buffer_release_timer(void *opaque)
+{
+ FILTERBUFFERState *s = opaque;
+ filter_buffer_release_one(&s->nf);
+ timer_mod(&s->release_timer,
+ qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + s->interval);
+}
+
+/* filter APIs */
+static ssize_t filter_buffer_receive_iov(NetFilterState *nf,
+ NetClientState *sender,
+ unsigned flags,
+ const struct iovec *iov,
+ int iovcnt)
+{
+ FILTERBUFFERState *s = DO_UPCAST(FILTERBUFFERState, nf, nf);
+ NetQueue *queue = s->incoming_queue;
+
+ qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt,
+ packet_send_completed);
+ return iov_size(iov, iovcnt);
+}
+
+static void filter_buffer_cleanup(NetFilterState *nf)
+{
+ FILTERBUFFERState *s = DO_UPCAST(FILTERBUFFERState, nf, nf);
+
+ if (s->interval) {
+ timer_del(&s->release_timer);
+ }
+
+ /* flush inflight packets */
+ filter_buffer_flush(nf);
+ /* flush incoming packets */
+ s->inflight_queue = s->incoming_queue;
+ s->incoming_queue = NULL;
+ filter_buffer_flush(nf);
+
+ if (s->flush_bh) {
+ qemu_bh_delete(s->flush_bh);
+ s->flush_bh = NULL;
+ }
+ return;
+}
+
+
+static NetFilterInfo net_filter_buffer_info = {
+ .type = NET_FILTER_OPTIONS_KIND_BUFFER,
+ .size = sizeof(FILTERBUFFERState),
+ .receive_iov = filter_buffer_receive_iov,
+ .cleanup = filter_buffer_cleanup,
+};
+
+int net_init_filter_buffer(const NetFilterOptions *opts, const char *name,
+ int chain, NetClientState *netdev, Error **errp)
+{
+ NetFilterState *nf;
+ FILTERBUFFERState *s;
+ const NetFilterBufferOptions *bufferopt;
+
+ assert(opts->kind == NET_FILTER_OPTIONS_KIND_BUFFER);
+ bufferopt = opts->buffer;
+
+ nf = qemu_new_net_filter(&net_filter_buffer_info,
+ netdev, "buffer", name, chain);
+ s = DO_UPCAST(FILTERBUFFERState, nf, nf);
+ s->incoming_queue = qemu_new_net_queue(nf);
+ s->flush_bh = qemu_bh_new(filter_buffer_flush_bh, s);
+ s->interval = bufferopt->has_interval ? bufferopt->interval : 0;
+ if (s->interval) {
+ timer_init_us(&s->release_timer, QEMU_CLOCK_VIRTUAL,
+ filter_buffer_release_timer, s);
+ timer_mod(&s->release_timer,
+ qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + s->interval);
+ }
+
+ return 0;
+}
diff --git a/net/filter.c b/net/filter.c
index 1ae9344..79351f3 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -17,6 +17,7 @@
#include "net/filter.h"
#include "net/net.h"
+#include "filters.h"
static QTAILQ_HEAD(, NetFilterState) net_filters;
@@ -137,6 +138,7 @@ typedef int (NetFilterInit)(const NetFilterOptions *opts,
static
NetFilterInit * const net_filter_init_fun[NET_FILTER_OPTIONS_KIND_MAX] = {
+ [NET_FILTER_OPTIONS_KIND_BUFFER] = net_init_filter_buffer,
};
static int net_filter_init1(const NetFilter *netfilter, Error **errp)
diff --git a/net/filters.h b/net/filters.h
new file mode 100644
index 0000000..3b546db
--- /dev/null
+++ b/net/filters.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 FUJITSU LIMITED
+ *
+ * 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_NET_FILTERS_H
+#define QEMU_NET_FILTERS_H
+
+#include "net/net.h"
+#include "net/filter.h"
+
+int net_init_filter_buffer(const NetFilterOptions *opts, const char *name,
+ int chain, NetClientState *netdev, Error **errp);
+
+#endif /* QEMU_NET_FILTERS_H */
diff --git a/qapi-schema.json b/qapi-schema.json
index 9d97c21..e51bb59 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2584,6 +2584,21 @@
{ 'command': 'netfilter_del', 'data': {'id': 'str'} }
##
+# @NetFilterBufferOptions
+#
+# a netbuffer filter for network backend.
+#
+# @interval: #optional release packets by interval, if no interval supplied,
+# will release packets when filter_buffer_release_all been called.
+# scale: microsecond
+#
+# Since 2.5
+##
+{ 'struct': 'NetFilterBufferOptions',
+ 'data': {
+ '*interval': 'int64' } }
+
+##
# @NetFilterOptions
#
# A discriminated record of network filters.
@@ -2592,7 +2607,8 @@
#
##
{ 'union': 'NetFilterOptions',
- 'data': { } }
+ 'data': {
+ 'buffer': 'NetFilterBufferOptions'} }
##
# @NetFilter
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v2 8/9] netfilter: add a netbuffer filter
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 8/9] netfilter: add a netbuffer filter Yang Hongyang
@ 2015-07-31 6:08 ` Jason Wang
2015-07-31 8:30 ` Yang Hongyang
2015-07-31 18:58 ` Dr. David Alan Gilbert
1 sibling, 1 reply; 23+ messages in thread
From: Jason Wang @ 2015-07-31 6:08 UTC (permalink / raw)
To: Yang Hongyang, qemu-devel
Cc: thuth, mrhines, stefanha, zhang.zhanghailiang, lizhijian
On 07/31/2015 12:13 PM, Yang Hongyang wrote:
> This filter is to buffer/release packets, this feature can be used
> when using MicroCheckpointing, or other Remus like VM FT solutions, you
> can also use it to simulate the network delay.
> It has an interval option, if supplied, this filter will release
> packets by interval.
>
> Usage:
> -netdev tap,id=bn0
> -netfilter buffer,id=f0,netdev=bn0,chain=in,interval=1000
>
> NOTE:
> the scale of interval is microsecond.
>
> Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
> ---
> net/Makefile.objs | 1 +
> net/filter-buffer.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> net/filter.c | 2 +
> net/filters.h | 17 ++++++
> qapi-schema.json | 18 +++++-
> 5 files changed, 197 insertions(+), 1 deletion(-)
> create mode 100644 net/filter-buffer.c
> create mode 100644 net/filters.h
>
> diff --git a/net/Makefile.objs b/net/Makefile.objs
> index 914aec0..5fa2f97 100644
> --- a/net/Makefile.objs
> +++ b/net/Makefile.objs
> @@ -14,3 +14,4 @@ common-obj-$(CONFIG_SLIRP) += slirp.o
> common-obj-$(CONFIG_VDE) += vde.o
> common-obj-$(CONFIG_NETMAP) += netmap.o
> common-obj-y += filter.o
> +common-obj-y += filter-buffer.o
> diff --git a/net/filter-buffer.c b/net/filter-buffer.c
> new file mode 100644
> index 0000000..7f2b050
> --- /dev/null
> +++ b/net/filter-buffer.c
> @@ -0,0 +1,160 @@
> +/*
> + * Copyright (c) 2015 FUJITSU LIMITED
> + * Author: Yang Hongyang <yanghy@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 "net/filter.h"
> +#include "net/queue.h"
> +#include "filters.h"
> +#include "qemu-common.h"
> +#include "qemu/error-report.h"
> +#include "qemu/main-loop.h"
> +#include "qemu/timer.h"
> +#include "qemu/iov.h"
> +
> +typedef struct FILTERBUFFERState {
> + NetFilterState nf;
> + NetQueue *incoming_queue;
> + NetQueue *inflight_queue;
> + QEMUBH *flush_bh;
> + int64_t interval;
> + QEMUTimer release_timer;
> +} FILTERBUFFERState;
> +
> +static void packet_send_completed(NetClientState *nc, ssize_t len)
> +{
> + return;
> +}
> +
> +static void filter_buffer_flush(NetFilterState *nf)
> +{
> + FILTERBUFFERState *s = DO_UPCAST(FILTERBUFFERState, nf, nf);
> + NetQueue *queue = s->inflight_queue;
> + NetPacket *packet;
> +
> + while (queue && !QTAILQ_EMPTY(&queue->packets)) {
> + packet = QTAILQ_FIRST(&queue->packets);
> + QTAILQ_REMOVE(&queue->packets, packet, entry);
> + queue->nq_count--;
> +
> + qemu_net_queue_send(packet->sender->peer->incoming_queue,
> + packet->sender,
> + packet->flags,
> + packet->data,
> + packet->size,
> + packet->sent_cb);
Need to check peer since it may be NULL e.g after it was deleted. And we
probably need to queue the packet into next filter.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v2 8/9] netfilter: add a netbuffer filter
2015-07-31 6:08 ` Jason Wang
@ 2015-07-31 8:30 ` Yang Hongyang
2015-07-31 9:15 ` Jason Wang
0 siblings, 1 reply; 23+ messages in thread
From: Yang Hongyang @ 2015-07-31 8:30 UTC (permalink / raw)
To: Jason Wang, qemu-devel
Cc: thuth, mrhines, stefanha, zhang.zhanghailiang, lizhijian
On 07/31/2015 02:08 PM, Jason Wang wrote:
>
>
> On 07/31/2015 12:13 PM, Yang Hongyang wrote:
>> This filter is to buffer/release packets, this feature can be used
>> when using MicroCheckpointing, or other Remus like VM FT solutions, you
>> can also use it to simulate the network delay.
>> It has an interval option, if supplied, this filter will release
>> packets by interval.
>>
>> Usage:
>> -netdev tap,id=bn0
>> -netfilter buffer,id=f0,netdev=bn0,chain=in,interval=1000
>>
>> NOTE:
>> the scale of interval is microsecond.
>>
>> Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
>> ---
>> net/Makefile.objs | 1 +
>> net/filter-buffer.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>> net/filter.c | 2 +
>> net/filters.h | 17 ++++++
>> qapi-schema.json | 18 +++++-
>> 5 files changed, 197 insertions(+), 1 deletion(-)
>> create mode 100644 net/filter-buffer.c
>> create mode 100644 net/filters.h
>>
>> diff --git a/net/Makefile.objs b/net/Makefile.objs
>> index 914aec0..5fa2f97 100644
>> --- a/net/Makefile.objs
>> +++ b/net/Makefile.objs
>> @@ -14,3 +14,4 @@ common-obj-$(CONFIG_SLIRP) += slirp.o
>> common-obj-$(CONFIG_VDE) += vde.o
>> common-obj-$(CONFIG_NETMAP) += netmap.o
>> common-obj-y += filter.o
>> +common-obj-y += filter-buffer.o
>> diff --git a/net/filter-buffer.c b/net/filter-buffer.c
>> new file mode 100644
>> index 0000000..7f2b050
>> --- /dev/null
>> +++ b/net/filter-buffer.c
>> @@ -0,0 +1,160 @@
>> +/*
>> + * Copyright (c) 2015 FUJITSU LIMITED
>> + * Author: Yang Hongyang <yanghy@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 "net/filter.h"
>> +#include "net/queue.h"
>> +#include "filters.h"
>> +#include "qemu-common.h"
>> +#include "qemu/error-report.h"
>> +#include "qemu/main-loop.h"
>> +#include "qemu/timer.h"
>> +#include "qemu/iov.h"
>> +
>> +typedef struct FILTERBUFFERState {
>> + NetFilterState nf;
>> + NetQueue *incoming_queue;
>> + NetQueue *inflight_queue;
>> + QEMUBH *flush_bh;
>> + int64_t interval;
>> + QEMUTimer release_timer;
>> +} FILTERBUFFERState;
>> +
>> +static void packet_send_completed(NetClientState *nc, ssize_t len)
>> +{
>> + return;
>> +}
>> +
>> +static void filter_buffer_flush(NetFilterState *nf)
>> +{
>> + FILTERBUFFERState *s = DO_UPCAST(FILTERBUFFERState, nf, nf);
>> + NetQueue *queue = s->inflight_queue;
>> + NetPacket *packet;
>> +
>> + while (queue && !QTAILQ_EMPTY(&queue->packets)) {
>> + packet = QTAILQ_FIRST(&queue->packets);
>> + QTAILQ_REMOVE(&queue->packets, packet, entry);
>> + queue->nq_count--;
>> +
>> + qemu_net_queue_send(packet->sender->peer->incoming_queue,
>> + packet->sender,
>> + packet->flags,
>> + packet->data,
>> + packet->size,
>> + packet->sent_cb);
>
> Need to check peer since it may be NULL e.g after it was deleted. And we
> probably need to queue the packet into next filter.
Yes, if the peer is NULL, we can just free the packet and continue.
we might need to check the sender too, because the sender might be deleted
too...
I was thinking when we remove the netdev, we also remove/free the filters
attached to it automatically, do you think it is reasonable? because if the
netdev is removed, the filters which attached to it is useless.
--
Thanks,
Yang.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v2 8/9] netfilter: add a netbuffer filter
2015-07-31 8:30 ` Yang Hongyang
@ 2015-07-31 9:15 ` Jason Wang
0 siblings, 0 replies; 23+ messages in thread
From: Jason Wang @ 2015-07-31 9:15 UTC (permalink / raw)
To: Yang Hongyang, qemu-devel
Cc: lizhijian, thuth, stefanha, mrhines, zhang.zhanghailiang
On 07/31/2015 04:30 PM, Yang Hongyang wrote:
> On 07/31/2015 02:08 PM, Jason Wang wrote:
>>
>>
>> On 07/31/2015 12:13 PM, Yang Hongyang wrote:
>>> This filter is to buffer/release packets, this feature can be used
>>> when using MicroCheckpointing, or other Remus like VM FT solutions, you
>>> can also use it to simulate the network delay.
>>> It has an interval option, if supplied, this filter will release
>>> packets by interval.
>>>
>>> Usage:
>>> -netdev tap,id=bn0
>>> -netfilter buffer,id=f0,netdev=bn0,chain=in,interval=1000
>>>
>>> NOTE:
>>> the scale of interval is microsecond.
>>>
>>> Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
>>> ---
>>> net/Makefile.objs | 1 +
>>> net/filter-buffer.c | 160
>>> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>>> net/filter.c | 2 +
>>> net/filters.h | 17 ++++++
>>> qapi-schema.json | 18 +++++-
>>> 5 files changed, 197 insertions(+), 1 deletion(-)
>>> create mode 100644 net/filter-buffer.c
>>> create mode 100644 net/filters.h
>>>
>>> diff --git a/net/Makefile.objs b/net/Makefile.objs
>>> index 914aec0..5fa2f97 100644
>>> --- a/net/Makefile.objs
>>> +++ b/net/Makefile.objs
>>> @@ -14,3 +14,4 @@ common-obj-$(CONFIG_SLIRP) += slirp.o
>>> common-obj-$(CONFIG_VDE) += vde.o
>>> common-obj-$(CONFIG_NETMAP) += netmap.o
>>> common-obj-y += filter.o
>>> +common-obj-y += filter-buffer.o
>>> diff --git a/net/filter-buffer.c b/net/filter-buffer.c
>>> new file mode 100644
>>> index 0000000..7f2b050
>>> --- /dev/null
>>> +++ b/net/filter-buffer.c
>>> @@ -0,0 +1,160 @@
>>> +/*
>>> + * Copyright (c) 2015 FUJITSU LIMITED
>>> + * Author: Yang Hongyang <yanghy@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 "net/filter.h"
>>> +#include "net/queue.h"
>>> +#include "filters.h"
>>> +#include "qemu-common.h"
>>> +#include "qemu/error-report.h"
>>> +#include "qemu/main-loop.h"
>>> +#include "qemu/timer.h"
>>> +#include "qemu/iov.h"
>>> +
>>> +typedef struct FILTERBUFFERState {
>>> + NetFilterState nf;
>>> + NetQueue *incoming_queue;
>>> + NetQueue *inflight_queue;
>>> + QEMUBH *flush_bh;
>>> + int64_t interval;
>>> + QEMUTimer release_timer;
>>> +} FILTERBUFFERState;
>>> +
>>> +static void packet_send_completed(NetClientState *nc, ssize_t len)
>>> +{
>>> + return;
>>> +}
>>> +
>>> +static void filter_buffer_flush(NetFilterState *nf)
>>> +{
>>> + FILTERBUFFERState *s = DO_UPCAST(FILTERBUFFERState, nf, nf);
>>> + NetQueue *queue = s->inflight_queue;
>>> + NetPacket *packet;
>>> +
>>> + while (queue && !QTAILQ_EMPTY(&queue->packets)) {
>>> + packet = QTAILQ_FIRST(&queue->packets);
>>> + QTAILQ_REMOVE(&queue->packets, packet, entry);
>>> + queue->nq_count--;
>>> +
>>> + qemu_net_queue_send(packet->sender->peer->incoming_queue,
>>> + packet->sender,
>>> + packet->flags,
>>> + packet->data,
>>> + packet->size,
>>> + packet->sent_cb);
>>
>> Need to check peer since it may be NULL e.g after it was deleted. And we
>> probably need to queue the packet into next filter.
>
> Yes, if the peer is NULL, we can just free the packet and continue.
> we might need to check the sender too, because the sender might be
> deleted
> too...
>
> I was thinking when we remove the netdev, we also remove/free the filters
> attached to it automatically, do you think it is reasonable? because
> if the
> netdev is removed, the filters which attached to it is useless.
Yes, please do this.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v2 8/9] netfilter: add a netbuffer filter
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 8/9] netfilter: add a netbuffer filter Yang Hongyang
2015-07-31 6:08 ` Jason Wang
@ 2015-07-31 18:58 ` Dr. David Alan Gilbert
2015-08-03 1:10 ` Yang Hongyang
1 sibling, 1 reply; 23+ messages in thread
From: Dr. David Alan Gilbert @ 2015-07-31 18:58 UTC (permalink / raw)
To: Yang Hongyang
Cc: thuth, zhang.zhanghailiang, lizhijian, jasowang, qemu-devel,
mrhines, stefanha
* Yang Hongyang (yanghy@cn.fujitsu.com) wrote:
> This filter is to buffer/release packets, this feature can be used
> when using MicroCheckpointing, or other Remus like VM FT solutions, you
> can also use it to simulate the network delay.
> It has an interval option, if supplied, this filter will release
> packets by interval.
>
> Usage:
> -netdev tap,id=bn0
> -netfilter buffer,id=f0,netdev=bn0,chain=in,interval=1000
>
Can I just check I understand what the 'interval' does - is that
you release one packet from the filter every 'interval' us ?
Is there anything that limits the size of the filter?
Dave
> NOTE:
> the scale of interval is microsecond.
>
> Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
> ---
> net/Makefile.objs | 1 +
> net/filter-buffer.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> net/filter.c | 2 +
> net/filters.h | 17 ++++++
> qapi-schema.json | 18 +++++-
> 5 files changed, 197 insertions(+), 1 deletion(-)
> create mode 100644 net/filter-buffer.c
> create mode 100644 net/filters.h
>
> diff --git a/net/Makefile.objs b/net/Makefile.objs
> index 914aec0..5fa2f97 100644
> --- a/net/Makefile.objs
> +++ b/net/Makefile.objs
> @@ -14,3 +14,4 @@ common-obj-$(CONFIG_SLIRP) += slirp.o
> common-obj-$(CONFIG_VDE) += vde.o
> common-obj-$(CONFIG_NETMAP) += netmap.o
> common-obj-y += filter.o
> +common-obj-y += filter-buffer.o
> diff --git a/net/filter-buffer.c b/net/filter-buffer.c
> new file mode 100644
> index 0000000..7f2b050
> --- /dev/null
> +++ b/net/filter-buffer.c
> @@ -0,0 +1,160 @@
> +/*
> + * Copyright (c) 2015 FUJITSU LIMITED
> + * Author: Yang Hongyang <yanghy@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 "net/filter.h"
> +#include "net/queue.h"
> +#include "filters.h"
> +#include "qemu-common.h"
> +#include "qemu/error-report.h"
> +#include "qemu/main-loop.h"
> +#include "qemu/timer.h"
> +#include "qemu/iov.h"
> +
> +typedef struct FILTERBUFFERState {
> + NetFilterState nf;
> + NetQueue *incoming_queue;
> + NetQueue *inflight_queue;
> + QEMUBH *flush_bh;
> + int64_t interval;
> + QEMUTimer release_timer;
> +} FILTERBUFFERState;
> +
> +static void packet_send_completed(NetClientState *nc, ssize_t len)
> +{
> + return;
> +}
> +
> +static void filter_buffer_flush(NetFilterState *nf)
> +{
> + FILTERBUFFERState *s = DO_UPCAST(FILTERBUFFERState, nf, nf);
> + NetQueue *queue = s->inflight_queue;
> + NetPacket *packet;
> +
> + while (queue && !QTAILQ_EMPTY(&queue->packets)) {
> + packet = QTAILQ_FIRST(&queue->packets);
> + QTAILQ_REMOVE(&queue->packets, packet, entry);
> + queue->nq_count--;
> +
> + qemu_net_queue_send(packet->sender->peer->incoming_queue,
> + packet->sender,
> + packet->flags,
> + packet->data,
> + packet->size,
> + packet->sent_cb);
> +
> + /*
> + * now that we pass the packet to sender->peer->incoming_queue, we
> + * don't care the reture value here, because the peer's queue will
> + * take care of this packet
> + */
> + g_free(packet);
> + }
> +
> + g_free(queue);
> + s->inflight_queue = NULL;
> +}
> +
> +static void filter_buffer_flush_bh(void *opaque)
> +{
> + FILTERBUFFERState *s = opaque;
> + NetFilterState *nf = &s->nf;
> + filter_buffer_flush(nf);
> +}
> +
> +static void filter_buffer_release_one(NetFilterState *nf)
> +{
> + FILTERBUFFERState *s = DO_UPCAST(FILTERBUFFERState, nf, nf);
> +
> + /* flush inflight packets */
> + if (s->inflight_queue) {
> + filter_buffer_flush(nf);
> + }
> +
> + s->inflight_queue = s->incoming_queue;
> + s->incoming_queue = qemu_new_net_queue(nf);
> + qemu_bh_schedule(s->flush_bh);
> +}
> +
> +static void filter_buffer_release_timer(void *opaque)
> +{
> + FILTERBUFFERState *s = opaque;
> + filter_buffer_release_one(&s->nf);
> + timer_mod(&s->release_timer,
> + qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + s->interval);
> +}
> +
> +/* filter APIs */
> +static ssize_t filter_buffer_receive_iov(NetFilterState *nf,
> + NetClientState *sender,
> + unsigned flags,
> + const struct iovec *iov,
> + int iovcnt)
> +{
> + FILTERBUFFERState *s = DO_UPCAST(FILTERBUFFERState, nf, nf);
> + NetQueue *queue = s->incoming_queue;
> +
> + qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt,
> + packet_send_completed);
> + return iov_size(iov, iovcnt);
> +}
> +
> +static void filter_buffer_cleanup(NetFilterState *nf)
> +{
> + FILTERBUFFERState *s = DO_UPCAST(FILTERBUFFERState, nf, nf);
> +
> + if (s->interval) {
> + timer_del(&s->release_timer);
> + }
> +
> + /* flush inflight packets */
> + filter_buffer_flush(nf);
> + /* flush incoming packets */
> + s->inflight_queue = s->incoming_queue;
> + s->incoming_queue = NULL;
> + filter_buffer_flush(nf);
> +
> + if (s->flush_bh) {
> + qemu_bh_delete(s->flush_bh);
> + s->flush_bh = NULL;
> + }
> + return;
> +}
> +
> +
> +static NetFilterInfo net_filter_buffer_info = {
> + .type = NET_FILTER_OPTIONS_KIND_BUFFER,
> + .size = sizeof(FILTERBUFFERState),
> + .receive_iov = filter_buffer_receive_iov,
> + .cleanup = filter_buffer_cleanup,
> +};
> +
> +int net_init_filter_buffer(const NetFilterOptions *opts, const char *name,
> + int chain, NetClientState *netdev, Error **errp)
> +{
> + NetFilterState *nf;
> + FILTERBUFFERState *s;
> + const NetFilterBufferOptions *bufferopt;
> +
> + assert(opts->kind == NET_FILTER_OPTIONS_KIND_BUFFER);
> + bufferopt = opts->buffer;
> +
> + nf = qemu_new_net_filter(&net_filter_buffer_info,
> + netdev, "buffer", name, chain);
> + s = DO_UPCAST(FILTERBUFFERState, nf, nf);
> + s->incoming_queue = qemu_new_net_queue(nf);
> + s->flush_bh = qemu_bh_new(filter_buffer_flush_bh, s);
> + s->interval = bufferopt->has_interval ? bufferopt->interval : 0;
> + if (s->interval) {
> + timer_init_us(&s->release_timer, QEMU_CLOCK_VIRTUAL,
> + filter_buffer_release_timer, s);
> + timer_mod(&s->release_timer,
> + qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + s->interval);
> + }
> +
> + return 0;
> +}
> diff --git a/net/filter.c b/net/filter.c
> index 1ae9344..79351f3 100644
> --- a/net/filter.c
> +++ b/net/filter.c
> @@ -17,6 +17,7 @@
>
> #include "net/filter.h"
> #include "net/net.h"
> +#include "filters.h"
>
> static QTAILQ_HEAD(, NetFilterState) net_filters;
>
> @@ -137,6 +138,7 @@ typedef int (NetFilterInit)(const NetFilterOptions *opts,
>
> static
> NetFilterInit * const net_filter_init_fun[NET_FILTER_OPTIONS_KIND_MAX] = {
> + [NET_FILTER_OPTIONS_KIND_BUFFER] = net_init_filter_buffer,
> };
>
> static int net_filter_init1(const NetFilter *netfilter, Error **errp)
> diff --git a/net/filters.h b/net/filters.h
> new file mode 100644
> index 0000000..3b546db
> --- /dev/null
> +++ b/net/filters.h
> @@ -0,0 +1,17 @@
> +/*
> + * Copyright (c) 2015 FUJITSU LIMITED
> + *
> + * 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_NET_FILTERS_H
> +#define QEMU_NET_FILTERS_H
> +
> +#include "net/net.h"
> +#include "net/filter.h"
> +
> +int net_init_filter_buffer(const NetFilterOptions *opts, const char *name,
> + int chain, NetClientState *netdev, Error **errp);
> +
> +#endif /* QEMU_NET_FILTERS_H */
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 9d97c21..e51bb59 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -2584,6 +2584,21 @@
> { 'command': 'netfilter_del', 'data': {'id': 'str'} }
>
> ##
> +# @NetFilterBufferOptions
> +#
> +# a netbuffer filter for network backend.
> +#
> +# @interval: #optional release packets by interval, if no interval supplied,
> +# will release packets when filter_buffer_release_all been called.
> +# scale: microsecond
> +#
> +# Since 2.5
> +##
> +{ 'struct': 'NetFilterBufferOptions',
> + 'data': {
> + '*interval': 'int64' } }
> +
> +##
> # @NetFilterOptions
> #
> # A discriminated record of network filters.
> @@ -2592,7 +2607,8 @@
> #
> ##
> { 'union': 'NetFilterOptions',
> - 'data': { } }
> + 'data': {
> + 'buffer': 'NetFilterBufferOptions'} }
>
> ##
> # @NetFilter
> --
> 1.9.1
>
>
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v2 8/9] netfilter: add a netbuffer filter
2015-07-31 18:58 ` Dr. David Alan Gilbert
@ 2015-08-03 1:10 ` Yang Hongyang
0 siblings, 0 replies; 23+ messages in thread
From: Yang Hongyang @ 2015-08-03 1:10 UTC (permalink / raw)
To: Dr. David Alan Gilbert
Cc: thuth, zhang.zhanghailiang, lizhijian, jasowang, qemu-devel,
mrhines, stefanha
On 08/01/2015 02:58 AM, Dr. David Alan Gilbert wrote:
> * Yang Hongyang (yanghy@cn.fujitsu.com) wrote:
>> This filter is to buffer/release packets, this feature can be used
>> when using MicroCheckpointing, or other Remus like VM FT solutions, you
>> can also use it to simulate the network delay.
>> It has an interval option, if supplied, this filter will release
>> packets by interval.
>>
>> Usage:
>> -netdev tap,id=bn0
>> -netfilter buffer,id=f0,netdev=bn0,chain=in,interval=1000
>>
>
> Can I just check I understand what the 'interval' does - is that
> you release one packet from the filter every 'interval' us ?
Release buffered packets between interval.
>
> Is there anything that limits the size of the filter?
Currently, no limits.
>
> Dave
>
>> NOTE:
>> the scale of interval is microsecond.
>>
>> Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
>> ---
>> net/Makefile.objs | 1 +
>> net/filter-buffer.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>> net/filter.c | 2 +
>> net/filters.h | 17 ++++++
>> qapi-schema.json | 18 +++++-
>> 5 files changed, 197 insertions(+), 1 deletion(-)
>> create mode 100644 net/filter-buffer.c
>> create mode 100644 net/filters.h
>>
>> diff --git a/net/Makefile.objs b/net/Makefile.objs
>> index 914aec0..5fa2f97 100644
>> --- a/net/Makefile.objs
>> +++ b/net/Makefile.objs
>> @@ -14,3 +14,4 @@ common-obj-$(CONFIG_SLIRP) += slirp.o
>> common-obj-$(CONFIG_VDE) += vde.o
>> common-obj-$(CONFIG_NETMAP) += netmap.o
>> common-obj-y += filter.o
>> +common-obj-y += filter-buffer.o
>> diff --git a/net/filter-buffer.c b/net/filter-buffer.c
>> new file mode 100644
>> index 0000000..7f2b050
>> --- /dev/null
>> +++ b/net/filter-buffer.c
>> @@ -0,0 +1,160 @@
>> +/*
>> + * Copyright (c) 2015 FUJITSU LIMITED
>> + * Author: Yang Hongyang <yanghy@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 "net/filter.h"
>> +#include "net/queue.h"
>> +#include "filters.h"
>> +#include "qemu-common.h"
>> +#include "qemu/error-report.h"
>> +#include "qemu/main-loop.h"
>> +#include "qemu/timer.h"
>> +#include "qemu/iov.h"
>> +
>> +typedef struct FILTERBUFFERState {
>> + NetFilterState nf;
>> + NetQueue *incoming_queue;
>> + NetQueue *inflight_queue;
>> + QEMUBH *flush_bh;
>> + int64_t interval;
>> + QEMUTimer release_timer;
>> +} FILTERBUFFERState;
>> +
>> +static void packet_send_completed(NetClientState *nc, ssize_t len)
>> +{
>> + return;
>> +}
>> +
>> +static void filter_buffer_flush(NetFilterState *nf)
>> +{
>> + FILTERBUFFERState *s = DO_UPCAST(FILTERBUFFERState, nf, nf);
>> + NetQueue *queue = s->inflight_queue;
>> + NetPacket *packet;
>> +
>> + while (queue && !QTAILQ_EMPTY(&queue->packets)) {
>> + packet = QTAILQ_FIRST(&queue->packets);
>> + QTAILQ_REMOVE(&queue->packets, packet, entry);
>> + queue->nq_count--;
>> +
>> + qemu_net_queue_send(packet->sender->peer->incoming_queue,
>> + packet->sender,
>> + packet->flags,
>> + packet->data,
>> + packet->size,
>> + packet->sent_cb);
>> +
>> + /*
>> + * now that we pass the packet to sender->peer->incoming_queue, we
>> + * don't care the reture value here, because the peer's queue will
>> + * take care of this packet
>> + */
>> + g_free(packet);
>> + }
>> +
>> + g_free(queue);
>> + s->inflight_queue = NULL;
>> +}
>> +
>> +static void filter_buffer_flush_bh(void *opaque)
>> +{
>> + FILTERBUFFERState *s = opaque;
>> + NetFilterState *nf = &s->nf;
>> + filter_buffer_flush(nf);
>> +}
>> +
>> +static void filter_buffer_release_one(NetFilterState *nf)
>> +{
>> + FILTERBUFFERState *s = DO_UPCAST(FILTERBUFFERState, nf, nf);
>> +
>> + /* flush inflight packets */
>> + if (s->inflight_queue) {
>> + filter_buffer_flush(nf);
>> + }
>> +
>> + s->inflight_queue = s->incoming_queue;
>> + s->incoming_queue = qemu_new_net_queue(nf);
>> + qemu_bh_schedule(s->flush_bh);
>> +}
>> +
>> +static void filter_buffer_release_timer(void *opaque)
>> +{
>> + FILTERBUFFERState *s = opaque;
>> + filter_buffer_release_one(&s->nf);
>> + timer_mod(&s->release_timer,
>> + qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + s->interval);
>> +}
>> +
>> +/* filter APIs */
>> +static ssize_t filter_buffer_receive_iov(NetFilterState *nf,
>> + NetClientState *sender,
>> + unsigned flags,
>> + const struct iovec *iov,
>> + int iovcnt)
>> +{
>> + FILTERBUFFERState *s = DO_UPCAST(FILTERBUFFERState, nf, nf);
>> + NetQueue *queue = s->incoming_queue;
>> +
>> + qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt,
>> + packet_send_completed);
>> + return iov_size(iov, iovcnt);
>> +}
>> +
>> +static void filter_buffer_cleanup(NetFilterState *nf)
>> +{
>> + FILTERBUFFERState *s = DO_UPCAST(FILTERBUFFERState, nf, nf);
>> +
>> + if (s->interval) {
>> + timer_del(&s->release_timer);
>> + }
>> +
>> + /* flush inflight packets */
>> + filter_buffer_flush(nf);
>> + /* flush incoming packets */
>> + s->inflight_queue = s->incoming_queue;
>> + s->incoming_queue = NULL;
>> + filter_buffer_flush(nf);
>> +
>> + if (s->flush_bh) {
>> + qemu_bh_delete(s->flush_bh);
>> + s->flush_bh = NULL;
>> + }
>> + return;
>> +}
>> +
>> +
>> +static NetFilterInfo net_filter_buffer_info = {
>> + .type = NET_FILTER_OPTIONS_KIND_BUFFER,
>> + .size = sizeof(FILTERBUFFERState),
>> + .receive_iov = filter_buffer_receive_iov,
>> + .cleanup = filter_buffer_cleanup,
>> +};
>> +
>> +int net_init_filter_buffer(const NetFilterOptions *opts, const char *name,
>> + int chain, NetClientState *netdev, Error **errp)
>> +{
>> + NetFilterState *nf;
>> + FILTERBUFFERState *s;
>> + const NetFilterBufferOptions *bufferopt;
>> +
>> + assert(opts->kind == NET_FILTER_OPTIONS_KIND_BUFFER);
>> + bufferopt = opts->buffer;
>> +
>> + nf = qemu_new_net_filter(&net_filter_buffer_info,
>> + netdev, "buffer", name, chain);
>> + s = DO_UPCAST(FILTERBUFFERState, nf, nf);
>> + s->incoming_queue = qemu_new_net_queue(nf);
>> + s->flush_bh = qemu_bh_new(filter_buffer_flush_bh, s);
>> + s->interval = bufferopt->has_interval ? bufferopt->interval : 0;
>> + if (s->interval) {
>> + timer_init_us(&s->release_timer, QEMU_CLOCK_VIRTUAL,
>> + filter_buffer_release_timer, s);
>> + timer_mod(&s->release_timer,
>> + qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + s->interval);
>> + }
>> +
>> + return 0;
>> +}
>> diff --git a/net/filter.c b/net/filter.c
>> index 1ae9344..79351f3 100644
>> --- a/net/filter.c
>> +++ b/net/filter.c
>> @@ -17,6 +17,7 @@
>>
>> #include "net/filter.h"
>> #include "net/net.h"
>> +#include "filters.h"
>>
>> static QTAILQ_HEAD(, NetFilterState) net_filters;
>>
>> @@ -137,6 +138,7 @@ typedef int (NetFilterInit)(const NetFilterOptions *opts,
>>
>> static
>> NetFilterInit * const net_filter_init_fun[NET_FILTER_OPTIONS_KIND_MAX] = {
>> + [NET_FILTER_OPTIONS_KIND_BUFFER] = net_init_filter_buffer,
>> };
>>
>> static int net_filter_init1(const NetFilter *netfilter, Error **errp)
>> diff --git a/net/filters.h b/net/filters.h
>> new file mode 100644
>> index 0000000..3b546db
>> --- /dev/null
>> +++ b/net/filters.h
>> @@ -0,0 +1,17 @@
>> +/*
>> + * Copyright (c) 2015 FUJITSU LIMITED
>> + *
>> + * 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_NET_FILTERS_H
>> +#define QEMU_NET_FILTERS_H
>> +
>> +#include "net/net.h"
>> +#include "net/filter.h"
>> +
>> +int net_init_filter_buffer(const NetFilterOptions *opts, const char *name,
>> + int chain, NetClientState *netdev, Error **errp);
>> +
>> +#endif /* QEMU_NET_FILTERS_H */
>> diff --git a/qapi-schema.json b/qapi-schema.json
>> index 9d97c21..e51bb59 100644
>> --- a/qapi-schema.json
>> +++ b/qapi-schema.json
>> @@ -2584,6 +2584,21 @@
>> { 'command': 'netfilter_del', 'data': {'id': 'str'} }
>>
>> ##
>> +# @NetFilterBufferOptions
>> +#
>> +# a netbuffer filter for network backend.
>> +#
>> +# @interval: #optional release packets by interval, if no interval supplied,
>> +# will release packets when filter_buffer_release_all been called.
>> +# scale: microsecond
>> +#
>> +# Since 2.5
>> +##
>> +{ 'struct': 'NetFilterBufferOptions',
>> + 'data': {
>> + '*interval': 'int64' } }
>> +
>> +##
>> # @NetFilterOptions
>> #
>> # A discriminated record of network filters.
>> @@ -2592,7 +2607,8 @@
>> #
>> ##
>> { 'union': 'NetFilterOptions',
>> - 'data': { } }
>> + 'data': {
>> + 'buffer': 'NetFilterBufferOptions'} }
>>
>> ##
>> # @NetFilter
>> --
>> 1.9.1
>>
>>
> --
> Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
> .
>
--
Thanks,
Yang.
^ permalink raw reply [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v2 9/9] filter/buffer: update command description and help
2015-07-31 4:13 [Qemu-devel] [PATCH v2 0/9] For QEMU 2.5: Add a netfilter object and netbuffer filter Yang Hongyang
` (7 preceding siblings ...)
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 8/9] netfilter: add a netbuffer filter Yang Hongyang
@ 2015-07-31 4:13 ` Yang Hongyang
2015-07-31 5:58 ` [Qemu-devel] [PATCH v2 0/9] For QEMU 2.5: Add a netfilter object and netbuffer filter Jason Wang
9 siblings, 0 replies; 23+ messages in thread
From: Yang Hongyang @ 2015-07-31 4:13 UTC (permalink / raw)
To: qemu-devel
Cc: thuth, zhang.zhanghailiang, lizhijian, jasowang,
Markus Armbruster, mrhines, Luiz Capitulino, stefanha,
Yang Hongyang
now that we have a buffer netfilter, update the command
description and help.
Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
CC: Luiz Capitulino <lcapitulino@redhat.com>
CC: Markus Armbruster <armbru@redhat.com>
---
hmp-commands.hx | 2 +-
qemu-options.hx | 5 ++++-
qmp-commands.hx | 2 +-
3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 902e2d1..63177a8 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1255,7 +1255,7 @@ ETEXI
{
.name = "netfilter_add",
.args_type = "netfilter:O",
- .params = "[type],id=str,netdev=str[,chain=in|out|all,prop=value][,...]",
+ .params = "[buffer],id=str,netdev=str[,chain=in|out|all,prop=value][,...]",
.help = "add netfilter",
.mhandler.cmd = hmp_netfilter_add,
.command_completion = netfilter_add_completion,
diff --git a/qemu-options.hx b/qemu-options.hx
index 0d52d02..4ca0a24 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1575,7 +1575,10 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
"socket][,vlan=n][,option][,option][,...]\n"
" old way to initialize a host network interface\n"
" (use the -netdev option if possible instead)\n", QEMU_ARCH_ALL)
-DEF("netfilter", HAS_ARG, QEMU_OPTION_netfilter, "", QEMU_ARCH_ALL)
+DEF("netfilter", HAS_ARG, QEMU_OPTION_netfilter,
+ "-netfilter buffer,id=str,netdev=str[,type=in|out|all,interval=n]\n"
+ " buffer netdev in/out packets. if interval provided, will release\n"
+ " packets by interval. interval scale: microsecond\n", QEMU_ARCH_ALL)
STEXI
@item -net nic[,vlan=@var{n}][,macaddr=@var{mac}][,model=@var{type}] [,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}]
@findex -net
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 4f0dc98..9419a6f 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -947,7 +947,7 @@ Arguments:
Example:
-> { "execute": "netfilter_add",
- "arguments": { "type": "type", "id": "nf0",
+ "arguments": { "type": "buffer", "id": "nf0",
"netdev": "bn",
"chain": "in" } }
<- { "return": {} }
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v2 0/9] For QEMU 2.5: Add a netfilter object and netbuffer filter
2015-07-31 4:13 [Qemu-devel] [PATCH v2 0/9] For QEMU 2.5: Add a netfilter object and netbuffer filter Yang Hongyang
` (8 preceding siblings ...)
2015-07-31 4:13 ` [Qemu-devel] [PATCH v2 9/9] filter/buffer: update command description and help Yang Hongyang
@ 2015-07-31 5:58 ` Jason Wang
2015-07-31 8:20 ` Yang Hongyang
9 siblings, 1 reply; 23+ messages in thread
From: Jason Wang @ 2015-07-31 5:58 UTC (permalink / raw)
To: Yang Hongyang, qemu-devel
Cc: thuth, zhang.zhanghailiang, lizhijian, mrhines, stefanha
On 07/31/2015 12:13 PM, Yang Hongyang wrote:
> This patch add a new object netfilter, capture all network packets.
> Also implement a netbuffer based on this object.
> the "buffer" netfilter could be used by VM FT solutions like
> MicroCheckpointing, to buffer/release packets. Or to simulate
> packet delay.
>
> Most of the changes of v2 are from Jason's comments.
> You can also get the series from:
> https://github.com/macrosheep/qemu/tree/netfilter-v2
>
> Usage:
> -netdev tap,id=bn0
> -netfilter buffer,id=f0,netdev=bn0,chain=in,interval=1000
> -device e1000,netdev=bn0
>
> dynamically add/remove netfilters:
> netfilter_add buffer,id=f0,netdev=bn0,chain=in,interval=1000
> netfilter_del f0
>
> NOTE:
> interval's scale is microsecond.
> chain is optional, and is one of in|out|all, default is "all".
> "in" means this filter will receive packets sent to the @netdev
> "out" means this filter will receive packets sent from the @netdev
> "all" means this filter will receive packets both sent to/from
> the @netdev
>
> TODO:
> - multiqueue support
> - dump
>
> v2:
> - add a chain option to netfilter object
> - move the hook place earlier, before net_queue_send
> - drop the unused api in buffer filter
> - squash buffer filter patches into one
> - remove receive() api from netfilter, only receive_iov() is enough
> - addressed comments from Jason&Thomas
>
> v1:
> initial patch.
>
> Yang Hongyang (9):
> net: add a new object netfilter
> init/cleanup of netfilter object
> netfilter: add netfilter_{add|del} commands
> net: add/remove filters from network backend
> netfilter: hook packets before net queue send
> net/queue: export qemu_net_queue_append_iov
> move out net queue structs define
> netfilter: add a netbuffer filter
> filter/buffer: update command description and help
>
> hmp-commands.hx | 30 ++++++
> hmp.c | 29 ++++++
> hmp.h | 4 +
> include/net/filter.h | 55 +++++++++++
> include/net/net.h | 8 ++
> include/net/queue.h | 26 +++++
> include/qemu/typedefs.h | 1 +
> include/sysemu/sysemu.h | 1 +
> monitor.c | 33 +++++++
> net/Makefile.objs | 2 +
> net/filter-buffer.c | 160 ++++++++++++++++++++++++++++++
> net/filter.c | 251 ++++++++++++++++++++++++++++++++++++++++++++++++
> net/filters.h | 17 ++++
> net/net.c | 105 +++++++++++++++++++-
> net/queue.c | 31 ++----
> qapi-schema.json | 100 +++++++++++++++++++
> qemu-options.hx | 4 +
> qmp-commands.hx | 57 +++++++++++
> vl.c | 13 +++
> 19 files changed, 901 insertions(+), 26 deletions(-)
> create mode 100644 include/net/filter.h
> create mode 100644 net/filter-buffer.c
> create mode 100644 net/filter.c
> create mode 100644 net/filters.h
>
Hi:
I would like to have some unit-tests with this series. It could be
started with very simple cases, e.g something like this:
1) adding or removing net filter
2) adding a net filter then destroy the netdev
3) adding and remove more than one net filters
4) adding more than one net filter and they delete the netdev
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v2 0/9] For QEMU 2.5: Add a netfilter object and netbuffer filter
2015-07-31 5:58 ` [Qemu-devel] [PATCH v2 0/9] For QEMU 2.5: Add a netfilter object and netbuffer filter Jason Wang
@ 2015-07-31 8:20 ` Yang Hongyang
2015-07-31 9:08 ` Jason Wang
0 siblings, 1 reply; 23+ messages in thread
From: Yang Hongyang @ 2015-07-31 8:20 UTC (permalink / raw)
To: Jason Wang, qemu-devel
Cc: thuth, zhang.zhanghailiang, lizhijian, mrhines, stefanha
On 07/31/2015 01:58 PM, Jason Wang wrote:
[...]
>>
>
> Hi:
>
> I would like to have some unit-tests with this series. It could be
> started with very simple cases, e.g something like this:
>
> 1) adding or removing net filter
> 2) adding a net filter then destroy the netdev
> 3) adding and remove more than one net filters
> 4) adding more than one net filter and they delete the netdev
Do you mean add some unit-tests cases in tests/*, for example
tests/test-netfilter.c?
> .
>
--
Thanks,
Yang.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v2 0/9] For QEMU 2.5: Add a netfilter object and netbuffer filter
2015-07-31 8:20 ` Yang Hongyang
@ 2015-07-31 9:08 ` Jason Wang
2015-07-31 9:51 ` Yang Hongyang
0 siblings, 1 reply; 23+ messages in thread
From: Jason Wang @ 2015-07-31 9:08 UTC (permalink / raw)
To: Yang Hongyang, qemu-devel
Cc: thuth, zhang.zhanghailiang, lizhijian, mrhines, stefanha
On 07/31/2015 04:20 PM, Yang Hongyang wrote:
> On 07/31/2015 01:58 PM, Jason Wang wrote:
> [...]
>>>
>>
>> Hi:
>>
>> I would like to have some unit-tests with this series. It could be
>> started with very simple cases, e.g something like this:
>>
>> 1) adding or removing net filter
>> 2) adding a net filter then destroy the netdev
>> 3) adding and remove more than one net filters
>> 4) adding more than one net filter and they delete the netdev
>
> Do you mean add some unit-tests cases in tests/*, for example
> tests/test-netfilter.c?
Yes.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v2 0/9] For QEMU 2.5: Add a netfilter object and netbuffer filter
2015-07-31 9:08 ` Jason Wang
@ 2015-07-31 9:51 ` Yang Hongyang
0 siblings, 0 replies; 23+ messages in thread
From: Yang Hongyang @ 2015-07-31 9:51 UTC (permalink / raw)
To: Jason Wang, qemu-devel
Cc: thuth, zhang.zhanghailiang, lizhijian, mrhines, stefanha
On 07/31/2015 05:08 PM, Jason Wang wrote:
>
>
> On 07/31/2015 04:20 PM, Yang Hongyang wrote:
>> On 07/31/2015 01:58 PM, Jason Wang wrote:
>> [...]
>>>>
>>>
>>> Hi:
>>>
>>> I would like to have some unit-tests with this series. It could be
>>> started with very simple cases, e.g something like this:
>>>
>>> 1) adding or removing net filter
>>> 2) adding a net filter then destroy the netdev
>>> 3) adding and remove more than one net filters
>>> 4) adding more than one net filter and they delete the netdev
>>
>> Do you mean add some unit-tests cases in tests/*, for example
>> tests/test-netfilter.c?
>
> Yes.
Ok, will do, thanks.
> .
>
--
Thanks,
Yang.
^ permalink raw reply [flat|nested] 23+ messages in thread