Signed-off-by: zhanghailiang <zhang.zhanghaili...@huawei.com> --- include/net/filter.h | 5 +++++ net/filter.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+)
diff --git a/include/net/filter.h b/include/net/filter.h index d797ee4..c7bd8f9 100644 --- a/include/net/filter.h +++ b/include/net/filter.h @@ -81,4 +81,9 @@ static inline bool qemu_need_skip_netfilter(NetFilterState *nf) void netfilter_print_info(NetFilterState *nf, char *output_str, int size); +void netdev_add_filter(const char *netdev_id, + const char *filter_type, + const char *id, + Error **errp); + #endif /* QEMU_NET_FILTER_H */ diff --git a/net/filter.c b/net/filter.c index f4933cc..4d96301 100644 --- a/net/filter.c +++ b/net/filter.c @@ -16,6 +16,10 @@ #include "qom/object_interfaces.h" #include "qemu/iov.h" #include "qapi/string-output-visitor.h" +#include "qapi/qmp/qdict.h" +#include "qapi/qmp-output-visitor.h" +#include "qapi/qmp-input-visitor.h" +#include "monitor/monitor.h" ssize_t qemu_netfilter_receive(NetFilterState *nf, NetFilterDirection direction, @@ -232,6 +236,65 @@ static void netfilter_complete(UserCreatable *uc, Error **errp) QTAILQ_INSERT_TAIL(&nf->netdev->filters, nf, next); } +/* +* This will be used by COLO or MC FT, for which they will need +* to buffer the packets of VM's net devices, Here we add a default +* buffer filter for each netdev. The name of default buffer filter is +* 'nop' +*/ +void netdev_add_filter(const char *netdev_id, + const char *filter_type, + const char *id, + Error **errp) +{ + QmpOutputVisitor *qov; + QmpInputVisitor *qiv; + Visitor *ov, *iv; + QObject *obj = NULL; + QDict *qdict; + void *dummy = NULL; + NetClientState *nc = qemu_find_netdev(netdev_id); + Error *err = NULL; + + /* FIXME: Not support multiple queues */ + if (!nc || nc->queue_index > 1) { + return; + } + /* Not support vhost-net */ + if (get_vhost_net(nc)) { + return; + } + + qov = qmp_output_visitor_new(); + ov = qmp_output_get_visitor(qov); + visit_start_struct(ov, &dummy, NULL, NULL, 0, &err); + if (err) { + goto out; + } + visit_type_str(ov, &nc->name, "netdev", &err); + if (err) { + goto out; + } + visit_end_struct(ov, &err); + if (err) { + goto out; + } + obj = qmp_output_get_qobject(qov); + g_assert(obj != NULL); + qdict = qobject_to_qdict(obj); + qmp_output_visitor_cleanup(qov); + + qiv = qmp_input_visitor_new(obj); + iv = qmp_input_get_visitor(qiv); + object_add(filter_type, id, qdict, iv, &err); + qmp_input_visitor_cleanup(qiv); + qobject_decref(obj); +out: + if (err) { + error_propagate(errp, err); + } +} + static void netfilter_finalize(Object *obj) { NetFilterState *nf = NETFILTER(obj); -- 1.8.3.1