From patchwork Thu Aug 15 18:08:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1147749 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=web.de Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; secure) header.d=web.de header.i=@web.de header.b="Imy/ms8r"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 468ZR32kGYz9sND for ; Fri, 16 Aug 2019 04:16:46 +1000 (AEST) Received: from localhost ([::1]:45856 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1hyKIl-0004UX-Hw for incoming@patchwork.ozlabs.org; Thu, 15 Aug 2019 14:16:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:34312) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1hyKBI-0007iV-7V for qemu-devel@nongnu.org; Thu, 15 Aug 2019 14:09:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hyKBG-0006qo-5l for qemu-devel@nongnu.org; Thu, 15 Aug 2019 14:09:00 -0400 Received: from mout.web.de ([212.227.17.11]:35653) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hyKBE-0006kf-39 for qemu-devel@nongnu.org; Thu, 15 Aug 2019 14:08:57 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1565892513; bh=lWpltg5ktOFn/3NdP2OLih9c+P9SmdyvyAgJtuJDT7s=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=Imy/ms8r3hklR3pGNTHVuj1K8aNajJRvu4zKVMb+4uZ3N/Ws+6yTrvGb7OORC8ePs 0jmJn8eAtTNY68J4bKWImeqgx7/KH2Qx16J7eobW+kIpb/EcMlbeZXcbrdaEAYmA/q 5FxyMmPW0eeSZX/j3K72jgPCVDcCBBm5zzwVhG3c= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([89.247.255.245]) by smtp.web.de (mrweb101 [213.165.67.124]) with ESMTPSA (Nemesis) id 0MT8o6-1hp4Vy42lS-00S42u; Thu, 15 Aug 2019 20:08:33 +0200 Date: Thu, 15 Aug 2019 20:08:29 +0200 From: Lukas Straub To: qemu-devel Message-ID: <20190815200829.3a558eb8@luklap> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:OdPUBM2o7+QBccgn4o3g/7MZ6CLZ9QT4Eau3BLw2SO4aeBc1d7U pOYjuIfgGJOfW4+46S6ViSm0y3JVrZUv7yzCbWXgN7oFCRbZbCTu1xejNXM2dz9ZIXh/Vjs o2oduRhbes6+Uadmp0tWDvR5PmzyR8yoRA/rmPvbSljNJwwomNL22h9GsIX+azWU5GK4BqG 2/PG1mxl7ByqyrxNm6Ukw== X-UI-Out-Filterresults: notjunk:1; V03:K0:W8lim6rwjeM=:GBUnWdVPVRaZBXrZJFQXcz z2Qday3Y7rRwW1Uu/z6nBAQ3zw6vlNbRTCVLcW6LzSngoNqJOnqC/P7Mxw4IwPnZ8Mg//cNUP GZvaN4LFt9RGTGxNax3G643sfv7fOPe3dHPHUO70CSNjX4K+zQiEITt0k+Kh7zrSUN3I+NUTy ZPay6TshDBqdkThEDlToVEEQ8c1OfPjRjQX/LMBAAM4Ug/0A45KjpVmPpn1Fs6NwcOnzyAo46 RZYq0uAFx++3zqMYAOh1mjoJmypJdi98D5sooM9aaYD8MJezXeJEtQjqIHSlBner+MMtMTBaO nLSeIkJvK3zHlzCXAEAMP0AhSHkNaaeTeUF6jWcy1qs43aAb1vcqhN2e/SXvBAB4c6Vz2q7bb fANECEqtBLh0H2e1A3b7fpqRoUvr0gowtlWS+LsOjGsf7RppZ30GMJeAKiS4ffUlB25aJZxpy tY9MP9S5tPArEZ+IeLmLXELzFDAEVvle7IyXbtN4V4o3kPDwTHhh7nY68Wi+qS2Ii/tkFCH1B Feem5kl5RfeWArKzu48w2fhbTlK2jXvp959Uv91dMJdagX6NLoIhL8nT2Xn6QXQOENWsZgUe5 FOcbkGrl1r0IxIJ4u5Iu4QRtA1gbNkmttT26eh7CNue5CF921zPV9wRljzaKeqGu1qCHx2svk rm64SYEhcZXea+79aJUwsZbFr2AjqP222IVTlplvfXtMXMCCnNv5ghp7ZMcEsOn3sqtZ7rLy7 FGyXPHhf4oNpaCv0bVph4bC5ktn69z3Wdp6VjdUqLiFibOkn2lZXSjpG4kX1dTBWYhXI1ddin JHBBB0qGdpVe5YSs4iBlXUgtmTjRMUH0lSHVtOi+qasNjwt6Lzy//6XUk7ONctw72fsHBfwzy ZTj4WvxXkIJNhX2eciMOreHdb6qRq23nNjscAOem56wPjOjcY1+8YcMnCnIlXdaFjK3b3aTd/ chsWJe42lzm/QQY6HKnhcv6HsdUrj3xIBOea/uOG3y9sUBv3EqeU5vMCkbNwejK8AQ48GZQfL zU0HkA5PbjF0+9PTC5KfyXVdHq6lyrFLYmAtN8WiRM1adG9QkY/H3m21oVO9YopUvBzQRuADZ R/7c8wvvHd8CDEYOOcC/4mdHKkvljy8DiMhQHsX2UzfKlT0U5fxWwqiHLuYoRhPv2UpIN9ziu 1y2woGqS08w+oH502+3xv2Zw43rCAEQIAJ6WrVXCEHHG1kassLOTbYkOv8SivUM/YMDc8= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 212.227.17.11 Subject: [Qemu-devel] [PATCH v2 2/3] net/filter.c: Add Options to insert filters anywhere in the filter list X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Zhang Chen , Jason Wang , Xie Changlong , Wen Congyang Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" To switch the Secondary to Primary, we need to insert new filters before the filter-rewriter. Add the options insert= and position= to be able to insert filters anywhere in the filter list. position should be either "head", "tail" or the id of another filter. insert should be either "before" or "after" to specify where to insert the new filter relative to the one specified with position. Signed-off-by: Lukas Straub --- include/net/filter.h | 2 ++ net/filter.c | 71 +++++++++++++++++++++++++++++++++++++++++++- qemu-options.hx | 10 +++---- 3 files changed, 77 insertions(+), 6 deletions(-) -- 2.20.1 diff --git a/include/net/filter.h b/include/net/filter.h index 49da666ac0..355c178f75 100644 --- a/include/net/filter.h +++ b/include/net/filter.h @@ -62,6 +62,8 @@ struct NetFilterState { NetClientState *netdev; NetFilterDirection direction; bool on; + char *position; + bool insert_before; QTAILQ_ENTRY(NetFilterState) next; }; diff --git a/net/filter.c b/net/filter.c index 28d1930db7..309fd778df 100644 --- a/net/filter.c +++ b/net/filter.c @@ -171,11 +171,47 @@ static void netfilter_set_status(Object *obj, const char *str, Error **errp) } } +static char *netfilter_get_position(Object *obj, Error **errp) +{ + NetFilterState *nf = NETFILTER(obj); + + return g_strdup(nf->position); +} + +static void netfilter_set_position(Object *obj, const char *str, Error **errp) +{ + NetFilterState *nf = NETFILTER(obj); + + nf->position = g_strdup(str); +} + +static char *netfilter_get_insert(Object *obj, Error **errp) +{ + NetFilterState *nf = NETFILTER(obj); + + return nf->insert_before ? g_strdup("before") : g_strdup("after"); +} + +static void netfilter_set_insert(Object *obj, const char *str, Error **errp) +{ + NetFilterState *nf = NETFILTER(obj); + + if (strcmp(str, "before") && strcmp(str, "after")) { + error_setg(errp, "Invalid value for netfilter insert, " + "should be 'head' or 'tail'"); + return; + } + + nf->insert_before = !strcmp(str, "before"); +} + static void netfilter_init(Object *obj) { NetFilterState *nf = NETFILTER(obj); nf->on = true; + nf->insert_before = false; + nf->position = g_strdup("tail"); object_property_add_str(obj, "netdev", netfilter_get_netdev_id, netfilter_set_netdev_id, @@ -187,11 +223,18 @@ static void netfilter_init(Object *obj) object_property_add_str(obj, "status", netfilter_get_status, netfilter_set_status, NULL); + object_property_add_str(obj, "position", + netfilter_get_position, netfilter_set_position, + NULL); + object_property_add_str(obj, "insert", + netfilter_get_insert, netfilter_set_insert, + NULL); } static void netfilter_complete(UserCreatable *uc, Error **errp) { NetFilterState *nf = NETFILTER(uc); + NetFilterState *position = NULL; NetClientState *ncs[MAX_QUEUE_NUM]; NetFilterClass *nfc = NETFILTER_GET_CLASS(uc); int queues; @@ -219,6 +262,20 @@ static void netfilter_complete(UserCreatable *uc, Error **errp) return; } + if (strcmp(nf->position, "head") && strcmp(nf->position, "tail")) { + /* Search for the position to insert before/after */ + Object *container; + Object *obj; + + container = object_get_objects_root(); + obj = object_resolve_path_component(container, nf->position); + if (!obj) { + error_setg(errp, "filter '%s' not found", nf->position); + return; + } + position = NETFILTER(obj); + } + nf->netdev = ncs[0]; if (nfc->setup) { @@ -228,7 +285,18 @@ static void netfilter_complete(UserCreatable *uc, Error **errp) return; } } - QTAILQ_INSERT_TAIL(&nf->netdev->filters, nf, next); + + if (position) { + if (nf->insert_before) { + QTAILQ_INSERT_BEFORE(position, nf, next); + } else { + QTAILQ_INSERT_AFTER(&nf->netdev->filters, position, nf, next); + } + } else if (!strcmp(nf->position, "head")) { + QTAILQ_INSERT_HEAD(&nf->netdev->filters, nf, next); + } else if (!strcmp(nf->position, "tail")) { + QTAILQ_INSERT_TAIL(&nf->netdev->filters, nf, next); + } } static void netfilter_finalize(Object *obj) @@ -245,6 +313,7 @@ static void netfilter_finalize(Object *obj) QTAILQ_REMOVE(&nf->netdev->filters, nf, next); } g_free(nf->netdev_id); + g_free(nf->position); } static void default_handle_event(NetFilterState *nf, int event, Error **errp) diff --git a/qemu-options.hx b/qemu-options.hx index 08749a3391..f0a47a0746 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4368,7 +4368,7 @@ applications, they can do this through this parameter. Its format is a gnutls priority string as described at @url{https://gnutls.org/manual/html_node/Priority-Strings.html}. -@item -object filter-buffer,id=@var{id},netdev=@var{netdevid},interval=@var{t}[,queue=@var{all|rx|tx}][,status=@var{on|off}] +@item -object filter-buffer,id=@var{id},netdev=@var{netdevid},interval=@var{t}[,queue=@var{all|rx|tx}][,status=@var{on|off}][,position=@var{head|tail|id}][,insert=@var{after|before}] Interval @var{t} can't be 0, this filter batches the packet delivery: all packets arriving in a given interval on netdev @var{netdevid} are delayed @@ -4387,11 +4387,11 @@ queue @var{all|rx|tx} is an option that can be applied to any netfilter. @option{tx}: the filter is attached to the transmit queue of the netdev, where it will receive packets sent by the netdev. -@item -object filter-mirror,id=@var{id},netdev=@var{netdevid},outdev=@var{chardevid},queue=@var{all|rx|tx}[,vnet_hdr_support] +@item -object filter-mirror,id=@var{id},netdev=@var{netdevid},outdev=@var{chardevid},queue=@var{all|rx|tx}[,vnet_hdr_support][,position=@var{head|tail|id}][,insert=@var{after|before}] filter-mirror on netdev @var{netdevid},mirror net packet to chardev@var{chardevid}, if it has the vnet_hdr_support flag, filter-mirror will mirror packet with vnet_hdr_len. -@item -object filter-redirector,id=@var{id},netdev=@var{netdevid},indev=@var{chardevid},outdev=@var{chardevid},queue=@var{all|rx|tx}[,vnet_hdr_support] +@item -object filter-redirector,id=@var{id},netdev=@var{netdevid},indev=@var{chardevid},outdev=@var{chardevid},queue=@var{all|rx|tx}[,vnet_hdr_support][,position=@var{head|tail|id}][,insert=@var{after|before}] filter-redirector on netdev @var{netdevid},redirect filter's net packet to chardev @var{chardevid},and redirect indev's packet to filter.if it has the vnet_hdr_support flag, @@ -4400,7 +4400,7 @@ Create a filter-redirector we need to differ outdev id from indev id, id can not be the same. we can just use indev or outdev, but at least one of indev or outdev need to be specified. -@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid},queue=@var{all|rx|tx},[vnet_hdr_support] +@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid},queue=@var{all|rx|tx},[vnet_hdr_support][,position=@var{head|tail|id}][,insert=@var{after|before}] Filter-rewriter is a part of COLO project.It will rewrite tcp packet to secondary from primary to keep secondary tcp connection,and rewrite @@ -4413,7 +4413,7 @@ colo secondary: -object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1 -object filter-rewriter,id=rew0,netdev=hn0,queue=all -@item -object filter-dump,id=@var{id},netdev=@var{dev}[,file=@var{filename}][,maxlen=@var{len}] +@item -object filter-dump,id=@var{id},netdev=@var{dev}[,file=@var{filename}][,maxlen=@var{len}][,position=@var{head|tail|id}][,insert=@var{after|before}] Dump the network traffic on netdev @var{dev} to the file specified by @var{filename}. At most @var{len} bytes (64k by default) per packet are stored.