From patchwork Sun Sep 15 19:20:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1162502 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="gayAJpcO"; 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 46WfYh5Gf0z9sNT for ; Mon, 16 Sep 2019 05:28:40 +1000 (AEST) Received: from localhost ([::1]:56574 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i9aCM-0000bm-4p for incoming@patchwork.ozlabs.org; Sun, 15 Sep 2019 15:28:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39602) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i9a4d-0003ff-6n for qemu-devel@nongnu.org; Sun, 15 Sep 2019 15:20:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i9a4Z-00018W-5o for qemu-devel@nongnu.org; Sun, 15 Sep 2019 15:20:39 -0400 Received: from mout.web.de ([212.227.17.12]:34913) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1i9a4Y-00018F-ST for qemu-devel@nongnu.org; Sun, 15 Sep 2019 15:20:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1568575216; bh=bYRVmCXfWTISAMgenBJtNWjJCiJGXddMTiif/GPDVlI=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=gayAJpcOBTUSUEWtN3IkCj6JKRw5Yys1A+eGuzMHbcJV48Ph4843cEF1q14gTXOby I6H0EK7De53nKzhkUjCu987BxAbVUDSKDPJ3H2dA5mroOEM3gV7zw+R6UzOZYfj+f5 ilV58UmmtX3Z/anLB1CR/wJgJ3o2Xqx6lf9uTe28= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([88.130.61.53]) by smtp.web.de (mrweb101 [213.165.67.124]) with ESMTPSA (Nemesis) id 0Ls95v-1iEkwh0KRL-013yX9; Sun, 15 Sep 2019 21:20:16 +0200 Date: Sun, 15 Sep 2019 21:20:14 +0200 From: Lukas Straub To: qemu-devel Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:sEngW7Y9n3AfACaxfOoyxBEK/Ix+4SxuP7YwaONOsMxAb/0/LH1 epNIShIrKca6VPXBWDKltIZuZkilHCpmu2nSK8B9fAf1ck2ndf3kaPuQLwlInYmgHhaHHS4 A+Z3kM18LUKSiXAQsB9KynQPTsZKuNXzHp75mCkGr6P/aNpg4EexmLnzQa+gcklAU/E2Rwd BatC1kuj2sGYJXnln3B4Q== X-UI-Out-Filterresults: notjunk:1; V03:K0:qC9aMQaPfa0=:MSeq5Zz9eetrXM/QJih9E7 km9EcxeVjls2+vQs23HZ5CgyufVfgNNyDNZIum3Z8Phs1rjZCaOSwx5en0sCsD+FdBetCtV2W Wz1Sv2nVmuwtTkPLxYJ9zViYDFN+6WPwYNI6IZGPNwGuESVcfeQ9GgMIvgHx96GGdQgBqovBO mydozBlRQwMa8c2Lo0BsMBTsM7gmLwQGAuvJ6wSbtXqxhOQ2uJv52gG6c1HQxFSDzNHgFrfHj O4taQlAniqcDr6CxsehktWRKxDCYeTpVvcbfZPmnMZjWN3+eMUBB0CUKJNb3JqOIA3U3sIK7B E1vbndJnPeFSbmnZT9aBif+vIzwl5rhStotMoJ94yJhZqjKmMlBminJ/H/hKcn6sm7amXncZg 9LTaqCWxiAYG0M2WPA6e/gQ5Bkt9sZtW7ZeZ72ahN71ZwHM8cc568bZcXg+KRvNzDgF/hcXaR L3m+sZa0gayJ85lfy9CP/k5DYvV2R5IVNEoE+KuPt5rWImSmhb+OrnbT1yM0TvdA1DH7MbNPc n6otB56utwl2GcQm330UEss79Y5EOa8QVw5OCRZtJWmKF4uUROLC+L9QqNRFePzn2972Hu/pr PASCjfyfTNzekW/54KX7GagLbR6KFT7b/Km0TmjihR7hBSUgSrV93l6Z/qsrJrDfx1yvPZFUB 6ArpkvrLPfD8WVL6KX0cEJfMd5jp+O2+b7VHoOyiycQC35dY5Trmy8QPFI+LICzAFJM3XQd8l OFEKbHTfFhTptAs0GPDaCQBq3ZPp+SnU2y1z4GMLc6TWohqdUAA2U83p5ET8ljYxyVVKhlbcV 4F2FZyMqFgzcwWJb3ElaSKF3c2+EIiHxjJY+Sol5lpD+XgDJGcMrKWYSIFjPN3l/N+TYz48wm ziUrEoLul2fd8rQkcBV1SKCDCiKM3IW+LcR8Albrz9VSwQprN3ux+mIs6IiA2wrz4WzspbtM+ japeWd7v4oEXWB9GWE6mPsrA5kt7ItjrdyfpFlCWWsw4hgjbkH912SfjNsIDK67gaTC+SuPR8 vQOphivqMyrMMJ3XR/DFMzkb05nT1wV6DMqtVtOaHVdU7hzlYDVFIVef5g4RFbOu7JSUVKDTI qGPsVVJY5JV5PSZD58Mvj3H6UtIXgSvF7yvPdR1UiB5yoOKi6zGWs0h4WXX/N/0ptG6uM/hdw vO0wlKziEdxupI6AYI0rNqylNrUGNeul5WKN+H9tqnu1rYfo/bnG93UxLB/S0zZIGcjWkMyVE iwtC8x7q73KIZrluj3d7VBAqgBl7DwteMCSyW8x5FfJgvs7XYOIujancalvQ= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 212.227.17.12 Subject: [Qemu-devel] [PATCH v5 3/4] 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: kwolf@redhat.com, Wen Congyang , Jason Wang , mreitz@redhat.com, Zhang Chen , Xie Changlong 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 "head" or "tail" to insert at the head or tail of the filter list or it should be "id=" to specify the id of another filter. insert should be either "before" or "behind" to specify where to insert the new filter relative to the one specified with position. Signed-off-by: Lukas Straub Reviewed-by: Zhang Chen --- include/net/filter.h | 2 + net/filter.c | 92 +++++++++++++++++++++++++++++++++++++++++++- qemu-options.hx | 10 ++--- 3 files changed, 98 insertions(+), 6 deletions(-) -- 2.20.1 diff --git a/include/net/filter.h b/include/net/filter.h index 49da666ac0..22a723305b 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_flag; QTAILQ_ENTRY(NetFilterState) next; }; diff --git a/net/filter.c b/net/filter.c index 28d1930db7..cd2ef9e979 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_flag ? g_strdup("before") : g_strdup("behind"); +} + +static void netfilter_set_insert(Object *obj, const char *str, Error **errp) +{ + NetFilterState *nf = NETFILTER(obj); + + if (strcmp(str, "before") && strcmp(str, "behind")) { + error_setg(errp, "Invalid value for netfilter insert, " + "should be 'before' or 'behind'"); + return; + } + + nf->insert_before_flag = !strcmp(str, "before"); +} + static void netfilter_init(Object *obj) { NetFilterState *nf = NETFILTER(obj); nf->on = true; + nf->insert_before_flag = 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,41 @@ static void netfilter_complete(UserCreatable *uc, Error **errp) return; } + if (strcmp(nf->position, "head") && strcmp(nf->position, "tail")) { + Object *container; + Object *obj; + char *position_id; + + if (!g_str_has_prefix(nf->position, "id=")) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "position", + "'head', 'tail' or 'id='"); + return; + } + + /* get the id from the string */ + position_id = g_strndup(nf->position + 3, strlen(nf->position) - 3); + + /* Search for the position to insert before/behind */ + container = object_get_objects_root(); + obj = object_resolve_path_component(container, position_id); + if (!obj) { + error_setg(errp, "filter '%s' not found", position_id); + g_free(position_id); + return; + } + + position = NETFILTER(obj); + + if (position->netdev != ncs[0]) { + error_setg(errp, "filter '%s' belongs to a different netdev", + position_id); + g_free(position_id); + return; + } + + g_free(position_id); + } + nf->netdev = ncs[0]; if (nfc->setup) { @@ -228,7 +306,18 @@ static void netfilter_complete(UserCreatable *uc, Error **errp) return; } } - QTAILQ_INSERT_TAIL(&nf->netdev->filters, nf, next); + + if (position) { + if (nf->insert_before_flag) { + 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 +334,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..23fa5a344e 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{behind|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{behind|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{behind|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{behind|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{behind|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.