From nobody Sat May 30 15:29:22 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) client-ip=38.145.34.151; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1779124792; cv=none; d=zohomail.com; s=zohoarc; b=iyDgI2FIql8O9k4wtk9masj0WPzyUv7UZJ1mMZMvvTB1Tn6diXMP4P7HWqCMoAVglwrNqLJWtWv7p/cxwqhfxpf49QNWozXFkgvN/0YhoHE6ra8Z+zJU3tHtBxKsWZFOB/3FcZjm/k4Wf4uVrpGa9qf8r3smghoS+RRKOLLXoZE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1779124792; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=A0L7Zj5fnVs5wIvcKRnW65AbRD42JcQu6Pcx4rPwcsk=; b=imbBziZPYj3uYsC54beHAe7AEOESPMmjlWE0Dwqmq6JkLhTf67ZJB9a3xO5pWsfexGW80tE60czPwE4RdnGu0imEVMFi2OfpFGwhk2hPnweijQNLv0FNWgaiVvx4u3TEbdrov3bD4OKXmudjDNHdOauVukMEhg9aHaGE3NyGUj0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [38.145.34.151]) by mx.zohomail.com with SMTPS id 1779124791969184.30774308549792; Mon, 18 May 2026 10:19:51 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 916E341960; Mon, 18 May 2026 13:19:50 -0400 (EDT) Received: from [172.19.199.5] (unknown [10.16.107.18]) by lists.libvirt.org (Postfix) with ESMTP id 3CBB341ADD; Mon, 18 May 2026 13:13:56 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 3B4304190D; Mon, 18 May 2026 13:13:44 -0400 (EDT) Received: from mx11.osci.io (polly.osci.io [IPv6:2620:52:6:3141:1::41]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 7AB5A459E6 for ; Mon, 18 May 2026 12:04:30 -0400 (EDT) Received: by mx11.osci.io (Postfix, from userid 994) id 6602268591; Mon, 18 May 2026 08:31:56 -0400 (EDT) Received: from mail-ej1-x630.google.com (mail-ej1-x630.google.com [IPv6:2a00:1450:4864:20::630]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by mx11.osci.io (Postfix) with ESMTPS id 6341B684F2 for ; Mon, 18 May 2026 08:31:54 -0400 (EDT) Received: by mail-ej1-x630.google.com with SMTP id a640c23a62f3a-bd6460b0d11so351932666b.1 for ; Mon, 18 May 2026 05:31:54 -0700 (PDT) Received: from thinkiepadje.home (2a02-a470-a384-0-b529-3d3d-353-106e.fixed6.kpn.net. [2a02:a470:a384:0:b529:3d3d:353:106e]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bd4f4e4d54dsm553354066b.47.2026.05.18.05.29.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 May 2026 05:29:51 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779107393; x=1779712193; darn=lists.libvirt.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=A0L7Zj5fnVs5wIvcKRnW65AbRD42JcQu6Pcx4rPwcsk=; b=heI1hz6at/FXjtb0pi4ZUNbONyIOss7uOlA05XVL3FzXv0ZnB9qwTrFoolwUnq5esM GgQvbb6AAwkqsvVFXvDc3h5yKzZ2a5BFT/UxsUKCNMWOOgLp8uf9YemfWvyZS+qjVl29 Zf/xkZX8GLQEoeGgW53MGMIDiwFrqRHjTPMyU7e2vEcGThhNG8usNg9EVnGMSPA1w1D/ /KQjRfbCKMoNnZQQUGDs2hGgaFRCsADydh1EzoTqQvPaJIt7DrWdGKXhrVmonU08PgMa flh1e69K/ROKDL+zB7WRiD8LoPlRe2UJImul5kjd+nwXQqs9ZLKv2JD8Rot2k65UvEfC cZaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779107393; x=1779712193; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=A0L7Zj5fnVs5wIvcKRnW65AbRD42JcQu6Pcx4rPwcsk=; b=FWsB3+j2jk/gFjgilNYzqTRQjhUt+o92gev22j86E/HZdmMyN5+r5DovJwQoGK9v4i JqVa2jn0aA1bdMNnmenTLt0fBYo/4Sbgv5wO+6YE/4uXxCo2tx3S0MNphCag7UcVmwE3 qWrsiiiYW3w1Ila4rphNjBpK5/gBN6A4jWqKbDozp9BFYA5ScdfrSLj0KU+5dayvW/rw wFO5kcAHMfsDsrSunciNvB7JmI/lo3OIKIxvz73mr/M3x0HbALKfpJUCxwcVv4wHFp1v Bv8Abx8utrGYFxl2sLHhihemSIWHuRuc9RPWh5Rjy8krVtz3ATdFKP8w3J3v2xAkPOu+ 3iBw== X-Gm-Message-State: AOJu0YzdfJ+AVt+C5xP5ZTSk48BuBDrNn/hl+wtywL4yus6Zc1GliuRl zVOO/I5HL3xBbyoyH63xccjVcKera3Os0wEN7sH250xcFOeJjIGreIMNrxRb X-Gm-Gg: Acq92OHfCDSPHYPlkM9nWTry5szrSHokB86Qx6QiVaxW09gCqoAZFYP8s1RcHUo0JWH lyshAWX/XJ4pTMvSmsW2iDGjvemDM0ALVpnG4H0xiGKSROYcL4J1EJebByco9cBaiuLexSVtpzJ 62zws3UnNTxEsE8fyyO5UBjnGK318rua1NyfMYpPmRM3HYdg3jybVJepxxi0MRefCjIy4Z97EjG 17OyfbqB5taPXjxOcy/lNoeKJ/+M5V+O+n8xjlcRKjrlNBEgV4r5+AnBzUb7fOJJWqDdCtLjN4s eJCt/ToqO6qR0PDVQ85hwNprv4artY1f3MMGGuoq6sTo9I68p+TEj0TxMDI8vYjUSfIpdZXz8zF pt+OX0Zq+OJkBfJAxpnyO4b/P5/YGJ6DU438zUbqfv05l1Z8klM0qKfLOD9ULpkWNLkCYFn+q2M xJvQegJ02CCB6vQPuAYq2Hpxq+HdvnbNs/m3rNw9QA0ztDlMg1hK7JuDSbc3aF2iT9ZesYgDKXH IWVHtYykc50if5VmRxe/MY= X-Received: by 2002:a17:906:6207:b0:bd4:f82c:7a44 with SMTP id a640c23a62f3a-bd517930c9dmr760683066b.37.1779107392559; Mon, 18 May 2026 05:29:52 -0700 (PDT) From: Dion Bosschieter To: devel@lists.libvirt.org Subject: [PATCH v7 1/4] nwfilter: add nwfilter nftables driver Date: Mon, 18 May 2026 14:25:43 +0200 Message-ID: <20260518122547.163157-2-dionbosschieter@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260518122547.163157-1-dionbosschieter@gmail.com> References: <20260518122547.163157-1-dionbosschieter@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: CWLPFECVTJINWFTUL75UGXWCOR4WS5CC X-Message-ID-Hash: CWLPFECVTJINWFTUL75UGXWCOR4WS5CC X-MailFrom: SRS0=UfGQ=DP=gmail.com=dionbosschieter@osci.io X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: jean-louis@dupond.be, Dion Bosschieter X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1779124793105158500 Content-Type: text/plain; charset="utf-8" Resolves issue: https://gitlab.com/libvirt/libvirt/-/issues/603 Benchmarks showed that the amount of iifname jumps for each interface is the cause for this. Switched the nftables driver towards a vmap (verdict map) so we can have 1 rule that jumps to the correct root input/output chain per interface. Which improves throughput as when the number of interface check and jump rules increases the throughput decreases. The issue describes the interface matching works using the interface name and the majority of the effort is the strncpy, this commit also switches nftables to an interface_index compare instead. However, just using the interface_index is not enough, the amount of oif and iif jump rules causes quite the performance degradation, the vmap instead solves this. Split rules into separate tables: "libvirt_nwfilter_ethernet" and "libvirt_nwfilter_inet" to preserve existing ebip firewall behavior. Reworked chain logic for clarity with root -input/-output chains per interface. input in the VM interface is filtered in the -input chain(s), output out of the VM inteface is filtered in the -output chain(s). Stuck with two tables for compatibility reasons with ebiptables. Unifying into a single table would break user firewall definitions, which depend on being able to accept traffic at the Ethernet layer (currently defined via ebtables) and apply additional filtering via IP rules (currently defined via ip(6)tables). The nwfilter_nftables_driver splits the ethernet and inet rules in seperate tables "libvirt_nwfilter_ethernet" and "libvirt_nwfilter_inet", for above mentioned compatibility reasons. Rewrote chain logic, so it is easier to understand, input in the VM interface is filtered in the -input chain(s), output out of the VM inteface is filtered in the -output chain(s). _ethernet and _inet table follow the same style and hook in the same way. Simplified conntrack handling: rules with accept+conntrack are duplicated to the opposite chain for symmetric behavior, to support the existing ebiptables logic. Firewall updates continue to use tmp names for atomic replacement. Unsupported nwfilter features (for now): - IPSets (potential future support via nft sets) - rejects (not allowed in bridge table and POST/PREROUTING hook) Signed-off-by: Dion Bosschieter --- po/POTFILES | 1 + src/nwfilter/meson.build | 1 + src/nwfilter/nwfilter_nftables_driver.c | 2883 +++++++++++++++++++++++ src/nwfilter/nwfilter_nftables_driver.h | 28 + 4 files changed, 2913 insertions(+) create mode 100644 src/nwfilter/nwfilter_nftables_driver.c create mode 100644 src/nwfilter/nwfilter_nftables_driver.h diff --git a/po/POTFILES b/po/POTFILES index 3d52f23002..a404b7a012 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -163,6 +163,7 @@ src/nwfilter/nwfilter_driver.c src/nwfilter/nwfilter_ebiptables_driver.c src/nwfilter/nwfilter_gentech_driver.c src/nwfilter/nwfilter_learnipaddr.c +src/nwfilter/nwfilter_nftables_driver.c src/nwfilter/nwfilter_tech_driver.c src/openvz/openvz_conf.c src/openvz/openvz_driver.c diff --git a/src/nwfilter/meson.build b/src/nwfilter/meson.build index 9e8a4797c5..a94d72d570 100644 --- a/src/nwfilter/meson.build +++ b/src/nwfilter/meson.build @@ -5,6 +5,7 @@ nwfilter_driver_sources =3D [ 'nwfilter_dhcpsnoop.c', 'nwfilter_ebiptables_driver.c', 'nwfilter_learnipaddr.c', + 'nwfilter_nftables_driver.c', ] =20 driver_source_files +=3D files(nwfilter_driver_sources) diff --git a/src/nwfilter/nwfilter_nftables_driver.c b/src/nwfilter/nwfilte= r_nftables_driver.c new file mode 100644 index 0000000000..317170d850 --- /dev/null +++ b/src/nwfilter/nwfilter_nftables_driver.c @@ -0,0 +1,2883 @@ +/* + * nwfilter_nftables_driver.c: driver for nftables on tap devices + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include +#include +#include + +#include "internal.h" + +#include "virbuffer.h" +#include "viralloc.h" +#include "virlog.h" +#include "virerror.h" +#include "nwfilter_conf.h" +#include "nwfilter_nftables_driver.h" +#include "nwfilter_tech_driver.h" +#include "virfile.h" +#include "configmake.h" +#include "virstring.h" +#include "virfirewall.h" + +#define VIR_FROM_THIS VIR_FROM_NWFILTER + +/* define nftable root table */ +#define NF_ETHERNET_TABLE "libvirt_nwfilter_ethernet" +#define NF_INET_TABLE "libvirt_nwfilter_inet" +#define NF_COMMENT \ + "{ comment \"Managed by libvirt for network filters: " \ + "https://libvirt.org/firewall.html#the-network-filter-driver\"; }" +/* nftables counter can be enabled for firewalls transparency */ +#ifndef NF_COUNTER +# define NF_COUNTER 0 +#endif + +/* define chains */ +#define IN_CHAIN "postrouting" +#define OUT_CHAIN "prerouting" + +/* Interface matches depend on interface index, in nftables you can supply + * an interface name as argument which will be turned into the interface i= ndex + * for matching purposes. oif / iif will throw an nft error if the specifi= ed + * interface doesn't exist */ +#define IN_IFMATCH "oif" +#define OUT_IFMATCH "iif" +/* depend on the ifname for a match during moments where the + * interface already has dissapeared (dropAllRules) */ +#define IN_IFNAMEMATCH "oifname" +#define OUT_IFNAMEMATCH "iifname" + +#define DEFAULT_POLICY "accept" + +#ifndef NF_TRACE +# define NF_TRACE 0 +#endif +#if NF_TRACE +# define TRACE_SETTING "meta nftrace set 1;" +#else +# define TRACE_SETTING "" +#endif + +#define CHAINSETTINGS "{ }" + +#define VMAP_IN "vmap-oif" +#define VMAP_OUT "vmap-iif" +#define VMAPSETTINGS "{ type iface_index: verdict; }" + +#define SAME_IP_SET_NAME "same-ip-set" + +#define ROOT_CHAINSETTINGS(chain, defaultPolicy) \ + "{ type filter hook "chain" priority %d;" \ + " policy "defaultPolicy"; "TRACE_SETTING" }" + +VIR_LOG_INIT("nwfilter.nwfilter_nftables_driver"); + +/* A lookup table for translating ethernet protocol IDs to human readable + * strings. None of the human readable strings must be found as a prefix + * in another entry here (example 'ab' would be found in 'abc') to allow + * for prefix matching. + */ +static const struct virNWFilterUShortMap l3_protocols[] =3D { + virNWFilterUShortMapEntryIdx(VIR_NWFILTER_PROTO_IDX_IPV4, ETHERTYPE_IP= , "ipv4"), + virNWFilterUShortMapEntryIdx(VIR_NWFILTER_PROTO_IDX_IPV6, ETHERTYPE_IP= V6, "ipv6"), + virNWFilterUShortMapEntryIdx(VIR_NWFILTER_PROTO_IDX_ARP, ETHERTYPE_AR= P, "arp"), + virNWFilterUShortMapEntryIdx(VIR_NWFILTER_PROTO_IDX_RARP, ETHERTYPE_RE= VARP, "rarp"), + virNWFilterUShortMapEntryIdx(VIR_NWFILTER_PROTO_IDX_VLAN, ETHERTYPE_VL= AN, "vlan"), + virNWFilterUShortMapEntryIdx(VIR_NWFILTER_PROTO_IDX_STP, 0, = "stp"), + virNWFilterUShortMapEntryIdx(VIR_NWFILTER_PROTO_IDX_MAC, 0, = "mac"), + virNWFilterUShortMapEntryIdx(VIR_NWFILTER_PROTO_IDX_LAST, 0, = NULL), +}; + +/* + * Given a filtername determine the protocol it is used for evaluating + * We do prefix-matching to determine the protocol. + */ +static enum virNWFilterProtoIdx +nftablesGetProtoIdxByFiltername(const char *filtername) +{ + enum virNWFilterProtoIdx idx; + + for (idx =3D 0; idx < VIR_NWFILTER_PROTO_IDX_LAST; idx++) { + if (STRPREFIX(filtername, l3_protocols[idx].val)) + return idx; + } + + return -1; +} + +/* + * nftablesCreateSameIPSet creates libvirts same-ip-set, + * this nft set is used in nftablesHandleGarp + * in order to see if 'arp saddr ip =3D=3D arp daddr ip' + * + * In nftables 'nft' we can't match 2 fields to eachother. + * In order to support GARP matching, we define a 'same-ip-set' + * which will be used with ip masking to see if + * ip[0] =3D=3D ip[0] && ip[1] =3D=3D ip[1] && ip[2] =3D=3D ip[2] && ip[3]= =3D=3D ip[3] + */ +static void nftablesCreateSameIPSet(virFirewall *fw, + virFirewallLayer layer, + const char *tableName) +{ + virFirewallCmd *fwrule =3D NULL; + size_t i, j; + virFirewallAddCmd(fw, layer, "add", "set", "bridge", tableName, + SAME_IP_SET_NAME, "{ type ipv4_addr . ipv4_addr; }",= NULL); + + fwrule =3D virFirewallAddCmd(fw, layer, "add", "element", "bridge", + tableName, SAME_IP_SET_NAME, "{", NULL); + + for (i =3D 1; i <=3D 4; i++) { + for (j =3D 0; j < 256; j++) { + virFirewallCmdAddArgFormat(fw, fwrule, "%ld.%ld.%ld.%ld", + i =3D=3D 1 ? j : 0, i =3D=3D 2 ? j = : 0, + i =3D=3D 3 ? j : 0, i =3D=3D 4 ? j = : 0); + virFirewallCmdAddArg(fw, fwrule, "."); + virFirewallCmdAddArgFormat(fw, fwrule, "%ld.%ld.%ld.%ld", + i =3D=3D 1 ? j : 0, i =3D=3D 2 ? j = : 0, + i =3D=3D 3 ? j : 0, i =3D=3D 4 ? j = : 0); + virFirewallCmdAddArg(fw, fwrule, ","); + } + } + + virFirewallCmdAddArg(fw, fwrule, "}"); +} + +static void nftablesCreateTable(virFirewall *fw, + virFirewallLayer layer, + const char *tableName) +{ + virFirewallCmd *fwrule =3D NULL; + int tablePriority =3D STREQ(tableName, NF_ETHERNET_TABLE) ? 0 : 1; + + /* define table */ + virFirewallAddCmd(fw, layer, + "add", "table", "bridge", + tableName, NF_COMMENT, NULL); + + if (STREQ(tableName, NF_ETHERNET_TABLE)) + nftablesCreateSameIPSet(fw, layer, tableName); + + /* create vmap for iface matches */ + virFirewallAddCmd(fw, layer, "add", "map", "bridge", tableName, VMAP_I= N, + VMAPSETTINGS, NULL); + virFirewallAddCmd(fw, layer, "add", "map", "bridge", tableName, VMAP_O= UT, + VMAPSETTINGS, NULL); + + /* define default chains */ + fwrule =3D virFirewallAddCmd(fw, layer, "add", "chain", "bridge", + tableName, IN_CHAIN, NULL); + virFirewallCmdAddArgFormat(fw, fwrule, + ROOT_CHAINSETTINGS(IN_CHAIN, DEFAULT_POLICY= ), + tablePriority); + fwrule =3D virFirewallAddCmd(fw, layer, "add", "chain", "bridge", + tableName, OUT_CHAIN, NULL); + virFirewallCmdAddArgFormat(fw, fwrule, + ROOT_CHAINSETTINGS(OUT_CHAIN, DEFAULT_POLIC= Y), + tablePriority); + + /* add the one jump rule based on the vmap */ + fwrule =3D virFirewallAddCmd(fw, layer, "add", "rule", "bridge", table= Name, + IN_CHAIN, IN_IFMATCH, "vmap", NULL); + virFirewallCmdAddArgFormat(fw, fwrule, "@%s", VMAP_IN); + fwrule =3D virFirewallAddCmd(fw, layer, "add", "rule", "bridge", table= Name, + OUT_CHAIN, OUT_IFMATCH, "vmap", NULL); + virFirewallCmdAddArgFormat(fw, fwrule, "@%s", VMAP_OUT); +} + +static int +nftablesHandleCreateRootTables(virFirewall *fw, + virFirewallLayer layer, + const char *const *lines, + void *opaque G_GNUC_UNUSED) +{ + bool ethernetTableDefined =3D false; + bool inetTableDefined =3D false; + size_t i; + + /* parse nft tables list output to see if tables exist */ + for (i =3D 0; lines[i] !=3D NULL; i++) { + const char *line =3D lines[i]; + if ((line =3D STRSKIP(line, "table bridge ")) =3D=3D NULL) { + continue; + } + + VIR_DEBUG("Considering table for comparison '%s'", lines[i]); + + /* if chain matches basechain */ + if (STRPREFIX(line, NF_ETHERNET_TABLE)) { + ethernetTableDefined =3D true; + } else if (STRPREFIX(line, NF_INET_TABLE)) { + inetTableDefined =3D true; + } + } + + /* if the ethernet table doesn't exist, + * we create it including the default chains*/ + if (!ethernetTableDefined) + nftablesCreateTable(fw, layer, NF_ETHERNET_TABLE); + /* if the inet table doesn't exist, + * we create it including the default chains */ + if (!inetTableDefined) + nftablesCreateTable(fw, layer, NF_INET_TABLE); + + return 0; +} + +static void nftablesAddCmdAction(virFirewall *fw, + virFirewallCmd *fwrule, + virNWFilterRuleActionType action) +{ + switch (action) { + case VIR_NWFILTER_RULE_ACTION_ACCEPT: + virFirewallCmdAddArg(fw, fwrule, "accept"); + break; + case VIR_NWFILTER_RULE_ACTION_DROP: + virFirewallCmdAddArg(fw, fwrule, "drop"); + break; + case VIR_NWFILTER_RULE_ACTION_REJECT: + virFirewallCmdAddArg(fw, fwrule, "drop"); + break; + case VIR_NWFILTER_RULE_ACTION_RETURN: + virFirewallCmdAddArg(fw, fwrule, "return"); + break; + case VIR_NWFILTER_RULE_ACTION_CONTINUE: + virFirewallCmdAddArg(fw, fwrule, "continue"); + break; + case VIR_NWFILTER_RULE_ACTION_LAST: + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unexpected action %1$d"), action); + } +} + +static const char *nftablesGetProtocolType(int protocol) +{ + switch (protocol) { + case VIR_NWFILTER_RULE_PROTOCOL_TCP: + case VIR_NWFILTER_RULE_PROTOCOL_TCPoIPV6: + return "tcp"; + case VIR_NWFILTER_RULE_PROTOCOL_UDP: + case VIR_NWFILTER_RULE_PROTOCOL_UDPoIPV6: + return "udp"; + case VIR_NWFILTER_RULE_PROTOCOL_UDPLITE: + case VIR_NWFILTER_RULE_PROTOCOL_UDPLITEoIPV6: + return "udplite"; + case VIR_NWFILTER_RULE_PROTOCOL_ESP: + case VIR_NWFILTER_RULE_PROTOCOL_ESPoIPV6: + return "esp"; + case VIR_NWFILTER_RULE_PROTOCOL_AH: + case VIR_NWFILTER_RULE_PROTOCOL_AHoIPV6: + return "ah"; + case VIR_NWFILTER_RULE_PROTOCOL_SCTP: + case VIR_NWFILTER_RULE_PROTOCOL_SCTPoIPV6: + return "sctp"; + case VIR_NWFILTER_RULE_PROTOCOL_ICMP: + return "icmp"; + case VIR_NWFILTER_RULE_PROTOCOL_ICMPV6: + return "icmpv6"; + case VIR_NWFILTER_RULE_PROTOCOL_IGMP: + return "igmp"; + case VIR_NWFILTER_RULE_PROTOCOL_ALL: + case VIR_NWFILTER_RULE_PROTOCOL_ALLoIPV6: + return "all"; + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unexpected protocol %1$d"), + protocol); + return ""; + } +} + +static const char * +nftablesGetIpTypeByDataType(nwItemDesc *item) +{ + return (item->datatype =3D=3D DATATYPE_IPV6ADDR) ? "ip6" : "ip"; +} + +static int +nftablesHandleIPHdr(virFirewall *fw, + virFirewallCmd *fwrule, + virNWFilterVarCombIter *vars, + ipHdrDataDef *ipHdr, + bool reverseRule) +{ + char ipaddr[INET6_ADDRSTRLEN]; + char ipaddralt[INET6_ADDRSTRLEN]; + char number[VIR_INT64_STR_BUFLEN]; + const char *ip =3D NULL; + const char *saddr =3D reverseRule ? "daddr" : "saddr"; + const char *daddr =3D reverseRule ? "saddr" : "daddr"; + + if (HAS_ENTRY_ITEM(&ipHdr->dataSrcIPAddr)) { + ip =3D nftablesGetIpTypeByDataType(&ipHdr->dataSrcIPAddr); + virFirewallCmdAddArgList(fw, fwrule, ip, saddr, NULL); + + if (virNWFilterPrintDataType(vars, + ipaddr, sizeof(ipaddr), + &ipHdr->dataSrcIPAddr) < 0) + return -1; + + if (ENTRY_WANT_NEG_SIGN(&ipHdr->dataSrcIPAddr)) + virFirewallCmdAddArg(fw, fwrule, "!"); + + if (HAS_ENTRY_ITEM(&ipHdr->dataSrcIPMask)) { + if (virNWFilterPrintDataType(vars, + number, sizeof(number), + &ipHdr->dataSrcIPMask) < 0) + return -1; + + virFirewallCmdAddArgFormat(fw, fwrule, + "%s/%s", ipaddr, number); + } else { + virFirewallCmdAddArg(fw, fwrule, ipaddr); + } + } else if (HAS_ENTRY_ITEM(&ipHdr->dataSrcIPFrom)) { + ip =3D nftablesGetIpTypeByDataType(&ipHdr->dataSrcIPFrom); + virFirewallCmdAddArgList(fw, fwrule, ip, saddr, NULL); + + if (virNWFilterPrintDataType(vars, + ipaddr, sizeof(ipaddr), + &ipHdr->dataSrcIPFrom) < 0) + return -1; + + if (ENTRY_WANT_NEG_SIGN(&ipHdr->dataSrcIPFrom)) + virFirewallCmdAddArg(fw, fwrule, "!"); + + if (HAS_ENTRY_ITEM(&ipHdr->dataSrcIPTo)) { + + if (virNWFilterPrintDataType(vars, + ipaddralt, sizeof(ipaddralt), + &ipHdr->dataSrcIPTo) < 0) + return -1; + + virFirewallCmdAddArgFormat(fw, fwrule, + "%s-%s", ipaddr, ipaddralt); + } else { + virFirewallCmdAddArg(fw, fwrule, ipaddr); + } + } + + if (HAS_ENTRY_ITEM(&ipHdr->dataDstIPAddr)) { + ip =3D nftablesGetIpTypeByDataType(&ipHdr->dataDstIPAddr); + virFirewallCmdAddArgList(fw, fwrule, ip, daddr, NULL); + + if (virNWFilterPrintDataType(vars, + ipaddr, sizeof(ipaddr), + &ipHdr->dataDstIPAddr) < 0) + return -1; + + if (ENTRY_WANT_NEG_SIGN(&ipHdr->dataDstIPAddr)) + virFirewallCmdAddArg(fw, fwrule, "!"); + + if (HAS_ENTRY_ITEM(&ipHdr->dataDstIPMask)) { + if (virNWFilterPrintDataType(vars, + number, sizeof(number), + &ipHdr->dataDstIPMask) < 0) + return -1; + + virFirewallCmdAddArgFormat(fw, fwrule, + "%s/%s", ipaddr, number); + } else { + virFirewallCmdAddArg(fw, fwrule, ipaddr); + } + } else if (HAS_ENTRY_ITEM(&ipHdr->dataDstIPFrom)) { + ip =3D nftablesGetIpTypeByDataType(&ipHdr->dataDstIPFrom); + virFirewallCmdAddArgList(fw, fwrule, ip, daddr, NULL); + + if (virNWFilterPrintDataType(vars, + ipaddr, sizeof(ipaddr), + &ipHdr->dataDstIPFrom) < 0) + return -1; + + if (ENTRY_WANT_NEG_SIGN(&ipHdr->dataDstIPFrom)) + virFirewallCmdAddArg(fw, fwrule, "!"); + + if (HAS_ENTRY_ITEM(&ipHdr->dataDstIPTo)) { + if (virNWFilterPrintDataType(vars, + ipaddralt, sizeof(ipaddralt), + &ipHdr->dataDstIPTo) < 0) + return -1; + + virFirewallCmdAddArgFormat(fw, fwrule, + "%s-%s", ipaddr, ipaddralt); + } else { + virFirewallCmdAddArg(fw, fwrule, ipaddr); + } + } + + if (HAS_ENTRY_ITEM(&ipHdr->dataDSCP)) { + if (!ip) + ip =3D nftablesGetIpTypeByDataType(&ipHdr->dataDSCP); + + if (virNWFilterPrintDataType(vars, + number, sizeof(number), + &ipHdr->dataDSCP) < 0) + return -1; + + virFirewallCmdAddArgList(fw, fwrule, ip, "dscp", NULL); + if (ENTRY_WANT_NEG_SIGN(&ipHdr->dataDSCP)) + virFirewallCmdAddArg(fw, fwrule, "!"); + virFirewallCmdAddArgList(fw, fwrule, number, NULL); + } + + return 0; +} + +static int +nftablesHandleEthHdr(virFirewall *fw, + virFirewallCmd *fwrule, + virNWFilterVarCombIter *vars, + ethHdrDataDef *ethHdr, + bool reverseRule) +{ + char macaddr[VIR_MAC_STRING_BUFLEN]; + char macmask[VIR_MAC_STRING_BUFLEN]; + const char *saddr =3D reverseRule ? "daddr" : "saddr"; + const char *daddr =3D reverseRule ? "saddr" : "daddr"; + + if (HAS_ENTRY_ITEM(ðHdr->dataSrcMACAddr)) { + const char *comparison =3D NULL; + if (virNWFilterPrintDataType(vars, + macaddr, sizeof(macaddr), + ðHdr->dataSrcMACAddr) < 0) + return -1; + + virFirewallCmdAddArgList(fw, fwrule, "ether", saddr, NULL); + comparison =3D ENTRY_WANT_NEG_SIGN(ðHdr->dataSrcMACAddr) ? + "!=3D" : "=3D=3D"; + + if (HAS_ENTRY_ITEM(ðHdr->dataSrcMACMask)) { + if (virNWFilterPrintDataType(vars, + macmask, sizeof(macmask), + ðHdr->dataSrcMACMask) < 0) + return -1; + + virFirewallCmdAddArgFormat(fw, fwrule, + "& %s %s %s", + macmask, comparison, macaddr); + } else { + virFirewallCmdAddArgList(fw, fwrule, comparison, macaddr, NULL= ); + } + } + + if (HAS_ENTRY_ITEM(ðHdr->dataDstMACAddr)) { + const char *comparison =3D NULL; + if (virNWFilterPrintDataType(vars, + macaddr, sizeof(macaddr), + ðHdr->dataDstMACAddr) < 0) + return -1; + + virFirewallCmdAddArgList(fw, fwrule, "ether", daddr, NULL); + comparison =3D ENTRY_WANT_NEG_SIGN(ðHdr->dataDstMACAddr) ? + "!=3D" : "=3D=3D"; + + if (HAS_ENTRY_ITEM(ðHdr->dataDstMACMask)) { + if (virNWFilterPrintDataType(vars, + macmask, sizeof(macmask), + ðHdr->dataDstMACMask) < 0) + return -1; + + virFirewallCmdAddArgFormat(fw, fwrule, + "& %s %s %s", + macmask, comparison, macaddr); + } else { + virFirewallCmdAddArgList(fw, fwrule, comparison, macaddr, NULL= ); + } + } + + return 0; +} + +static int +insertRuleArg2Param(virFirewall *fw, + virFirewallCmd *fwrule, + virNWFilterVarCombIter *vars, + nwItemDesc *itemLow, + nwItemDesc *itemHigh, + const char *argument1, + const char *argument2, + const char *seperator) +{ + char field[VIR_INT64_STR_BUFLEN]; + char fieldalt[VIR_INT64_STR_BUFLEN]; + + if (HAS_ENTRY_ITEM(itemLow)) { + if (virNWFilterPrintDataType(vars, + field, sizeof(field), + itemLow) < 0) + return -1; + virFirewallCmdAddArg(fw, fwrule, argument1); + virFirewallCmdAddArg(fw, fwrule, argument2); + if (ENTRY_WANT_NEG_SIGN(itemLow)) + virFirewallCmdAddArg(fw, fwrule, "!=3D"); + if (HAS_ENTRY_ITEM(itemHigh)) { + if (virNWFilterPrintDataType(vars, + fieldalt, sizeof(fieldalt), + itemHigh) < 0) + return -1; + virFirewallCmdAddArgFormat(fw, fwrule, + "%s%s%s", field, seperator, fieldal= t); + } else { + virFirewallCmdAddArg(fw, fwrule, field); + } + } + + return 0; +} + +static int +nftablesHandlePortData(virFirewall *fw, + virFirewallCmd *fwrule, + virNWFilterVarCombIter *vars, + const char *protocol, + portDataDef *portData, + bool reverseRule) +{ + if (insertRuleArg2Param(fw, fwrule, vars, + &portData->dataDstPortStart, + &portData->dataDstPortEnd, protocol, + reverseRule ? "sport" : "dport", "-") < 0) + return -1; + if (insertRuleArg2Param(fw, fwrule, vars, + &portData->dataSrcPortStart, + &portData->dataSrcPortEnd, protocol, + reverseRule ? "dport" : "sport", "-") < 0) + return -1; + + return 0; +} + +static int +nftablesHandleMacAddr(virFirewall *fw, + virFirewallCmd *fwrule, + virNWFilterVarCombIter *vars, + nwItemDesc *macaddr, + const char *argument1, + const char *argument2, + const char *argument3) +{ + char macstr[VIR_MAC_STRING_BUFLEN]; + + if (HAS_ENTRY_ITEM(macaddr)) { + if (virNWFilterPrintDataType(vars, + macstr, sizeof(macstr), + macaddr) < 0) + return -1; + + virFirewallCmdAddArg(fw, fwrule, argument1); + virFirewallCmdAddArg(fw, fwrule, argument2); + if (argument3 !=3D NULL) + virFirewallCmdAddArg(fw, fwrule, argument3); + + if (ENTRY_WANT_NEG_SIGN(macaddr)) + virFirewallCmdAddArg(fw, fwrule, "!=3D"); + virFirewallCmdAddArg(fw, fwrule, macstr); + } + + return 0; +} + +static int +nftablesHandleSrcMacAddr(virFirewall *fw, + virFirewallCmd *fwrule, + virNWFilterVarCombIter *vars, + nwItemDesc *srcMacAddr) +{ + return nftablesHandleMacAddr(fw, fwrule, vars, srcMacAddr, + "ether", "saddr", NULL); +} + + +static void +nftablesHandleGarpMask(virFirewall *fw, + virFirewallCmd *fwrule, + const char *mask, + const char *inOperator) +{ + virFirewallCmdAddArgList(fw, fwrule, + "arp", "saddr", "ip", "&", mask, ".", + "arp", "daddr", "ip", "&", mask, inOperator, + NULL); + virFirewallCmdAddArgFormat(fw, fwrule, "@%s", SAME_IP_SET_NAME); +} + +static void +nftablesHandleGarp(virFirewall *fw, + virFirewallCmd *fwrule, + nwItemDesc *garp) +{ + const char *inOperator =3D ENTRY_WANT_NEG_SIGN(garp) ? "!=3D" : "=3D= =3D"; + + if (!HAS_ENTRY_ITEM(garp) || !garp->u.boolean) + return; + + /* nftables 'nft' command can't handle garp nor field to field compari= son like: + * - arp saddr ip =3D=3D arp daddr ip + * we'll have to seperately compare ip[0..4] to the precreated same-ip= -set + * to see if the IP matches + * in order to not list all possible ipv4 ips in the same-ip-set, we'l= l mask + * with either 255.0.0.0 0.255.0.0 0.0.255.0 or 0.0.0.255 + * this ensures that we "only" have 1024 entries in our same-ip-set + * + * This will result in the following firewall rule: + * arp saddr ip & 255.0.0.0 . arp daddr ip & 255.0.0.0 @same-ip-set + * arp saddr ip & 0.255.0.0 . arp daddr ip & 0.255.0.0 @same-ip-set + * arp saddr ip & 0.0.255.0 . arp daddr ip & 0.0.255.0 @same-ip-set + * arp saddr ip & 0.0.0.255 . arp daddr ip & 0.0.0.255 @same-ip-set + * counter accept + */ + nftablesHandleGarpMask(fw, fwrule, "255.0.0.0", inOperator); + nftablesHandleGarpMask(fw, fwrule, "0.255.0.0", inOperator); + nftablesHandleGarpMask(fw, fwrule, "0.0.255.0", inOperator); + nftablesHandleGarpMask(fw, fwrule, "0.0.0.255", inOperator); +} + +static void +printStateMatchFlags(int32_t flags, char **bufptr) +{ + g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; + virNWFilterPrintStateMatchFlags(&buf, "", flags, false); + + /* str to lower needed as nft doesn't accept upper case states */ + g_string_ascii_down(buf.str); + + *bufptr =3D virBufferContentAndReset(&buf); +} + +static bool +nftablesRuleNeedsConntrack(virNWFilterRuleDef *rule) +{ + /* ip only */ + if (virNWFilterRuleIsProtocolEthernet(rule)) { + return false; + } + + /* Skip conntrack if statematch=3Dfalse flag has been set */ + if (rule->flags & RULE_FLAG_NO_STATEMATCH) { + return false; + } + + /* If no state flags are set and rule->action is not accept, + * we should skip conntrack */ + if (!(rule->flags & IPTABLES_STATE_FLAGS) && + rule->action !=3D VIR_NWFILTER_RULE_ACTION_ACCEPT) { + return false; + } + + return true; +} + +static bool +nftablesRuleNeedsConnLimit(ipHdrDataDef *ipHdr, + bool directionIn) +{ + return HAS_ENTRY_ITEM(&ipHdr->dataConnlimitAbove) && !directionIn; +} + +static char * +nftablesPrintTCPFlags(uint8_t flags) +{ + g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; + g_autofree char *flagsstr =3D NULL; + + if (flags =3D=3D 0) { + virBufferAddLit(&buf, "0"); + } else if (flags =3D=3D 0x3f) { + virBufferAddLit(&buf, "*"); + } else { + flagsstr =3D virNWFilterPrintTCPFlags(flags); + virBufferAdd(&buf, flagsstr, -1); + g_string_ascii_down(buf.str); + } + + return virBufferContentAndReset(&buf); +} + +/* + * nftablesHandleInetRule: + * @fw: the firewall ruleset to add to + * @fwrule: the firewall command to add arguments to + * @vars : A map containing the variables to resolve + * @rule: The rule of the filter to convert + * @directionIn: direction of the rule, true for in false for out + * directionIn is needed for additional conntrack logic + * @reverseRule: Whether to reverse src and dst attributes + * ethernet reverse flag is set conntrack requires a reverse + * rule on the opposite chain + * + * Set arguments on fwrule based on given struct *rule + * + */ +static int +nftablesHandleInetRule(virFirewall *fw, + virFirewallCmd *fwrule, + virNWFilterVarCombIter *vars, + virNWFilterRuleDef *rule, + bool directionIn, + bool reverseRule) +{ + char number[VIR_INT64_STR_BUFLEN]; + bool hasICMPType =3D false; + bool skipDirection =3D false; + g_autofree char *matchState =3D NULL; + ipHdrDataDef *ipHdr =3D NULL; + const char *protocol =3D nftablesGetProtocolType(rule->prtclType); + + virFirewallCmdAddArgList(fw, fwrule, "ether", "type", NULL); + if (virNWFilterRuleIsProtocolIPv6(rule) && + !virNWFilterRuleIsProtocolIPv4(rule)) { + virFirewallCmdAddArg(fw, fwrule, "ip6"); + } else if (virNWFilterRuleIsProtocolIPv4(rule) && + !virNWFilterRuleIsProtocolIPv6(rule)) { + virFirewallCmdAddArg(fw, fwrule, "ip"); + } + + switch ((int)rule->prtclType) { + case VIR_NWFILTER_RULE_PROTOCOL_TCP: + case VIR_NWFILTER_RULE_PROTOCOL_TCPoIPV6: + virFirewallCmdAddArgList(fw, fwrule, "meta", "l4proto", "tcp", NUL= L); + ipHdr =3D &rule->p.tcpHdrFilter.ipHdr; + + if (nftablesHandleSrcMacAddr(fw, fwrule, vars, + &rule->p.tcpHdrFilter.dataSrcMACAddr)= < 0) + return -1; + if (nftablesHandleIPHdr(fw, fwrule, vars, ipHdr, reverseRule) < 0) + return -1; + + if (HAS_ENTRY_ITEM(&rule->p.tcpHdrFilter.dataTCPFlags)) { + g_autofree char *mask =3D NULL; + g_autofree char *flags =3D NULL; + + /* flags & syn =3D=3D syn */ + virFirewallCmdAddArgList(fw, fwrule, "tcp", "flags", "&", NULL= ); + + if (!(mask =3D nftablesPrintTCPFlags( + rule->p.tcpHdrFilter.dataTCPFlags.u.tcpFlags.mas= k))) + return -1; + virFirewallCmdAddArgList(fw, fwrule, mask, ENTRY_WANT_NEG_SIGN( + &rule->p.tcpHdrFilter.dataTCPF= lags) + ? "!=3D" : "=3D=3D", NULL); + + if (!(flags =3D nftablesPrintTCPFlags( + rule->p.tcpHdrFilter.dataTCPFlags.u.tcpFlags.fl= ags))) + return -1; + virFirewallCmdAddArgList(fw, fwrule, "{", flags, "}", NULL); + } + + if (HAS_ENTRY_ITEM(&rule->p.tcpHdrFilter.dataTCPOption)) { + if (virNWFilterPrintDataType(vars, number, sizeof(number), + &rule->p.tcpHdrFilter.dataTCPOpti= on) < 0) + return -1; + + virFirewallCmdAddArgList(fw, fwrule, "tcp", "option", NULL); + if (ENTRY_WANT_NEG_SIGN(&rule->p.tcpHdrFilter.dataTCPOption)) + virFirewallCmdAddArg(fw, fwrule, "!"); + virFirewallCmdAddArg(fw, fwrule, number); + } + + if (nftablesHandlePortData(fw, fwrule, vars, protocol, + &rule->p.tcpHdrFilter.portData, reverseRule) < 0) + return -1; + + break; + case VIR_NWFILTER_RULE_PROTOCOL_UDP: + case VIR_NWFILTER_RULE_PROTOCOL_UDPoIPV6: + virFirewallCmdAddArgList(fw, fwrule, "meta", "l4proto", "udp", NUL= L); + ipHdr =3D &rule->p.udpHdrFilter.ipHdr; + + if (nftablesHandleSrcMacAddr(fw, fwrule, vars, + &rule->p.udpHdrFilter.dataSrcMACAddr)= < 0) + return -1; + if (nftablesHandleIPHdr(fw, fwrule, vars, ipHdr, reverseRule) < 0) + return -1; + if (nftablesHandlePortData(fw, fwrule, vars, protocol, + &rule->p.udpHdrFilter.portData, reverseRule) < 0) + return -1; + break; + case VIR_NWFILTER_RULE_PROTOCOL_UDPLITE: + case VIR_NWFILTER_RULE_PROTOCOL_UDPLITEoIPV6: + virFirewallCmdAddArgList(fw, fwrule, "meta", "l4proto", "udplite",= NULL); + ipHdr =3D &rule->p.udpliteHdrFilter.ipHdr; + + if (nftablesHandleSrcMacAddr(fw, fwrule, vars, + &rule->p.udpliteHdrFilter.dataSrcMACA= ddr) < 0) + return -1; + if (nftablesHandleIPHdr(fw, fwrule, vars, ipHdr, reverseRule) < 0) + return -1; + break; + case VIR_NWFILTER_RULE_PROTOCOL_ESP: + case VIR_NWFILTER_RULE_PROTOCOL_ESPoIPV6: + virFirewallCmdAddArgList(fw, fwrule, "meta", "l4proto", "esp", NUL= L); + ipHdr =3D &rule->p.espHdrFilter.ipHdr; + + if (nftablesHandleSrcMacAddr(fw, fwrule, vars, + &rule->p.espHdrFilter.dataSrcMACAddr) = < 0) + return -1; + if (nftablesHandleIPHdr(fw, fwrule, vars, ipHdr, reverseRule) < 0) + return -1; + break; + case VIR_NWFILTER_RULE_PROTOCOL_AH: + case VIR_NWFILTER_RULE_PROTOCOL_AHoIPV6: + virFirewallCmdAddArgList(fw, fwrule, "meta", "l4proto", "ah", NULL= ); + ipHdr =3D &rule->p.ahHdrFilter.ipHdr; + + if (nftablesHandleSrcMacAddr(fw, fwrule, vars, + &rule->p.ahHdrFilter.dataSrcMACAddr) <= 0) + return -1; + if (nftablesHandleIPHdr(fw, fwrule, vars, ipHdr, reverseRule) < 0) + return -1; + break; + case VIR_NWFILTER_RULE_PROTOCOL_SCTP: + case VIR_NWFILTER_RULE_PROTOCOL_SCTPoIPV6: + virFirewallCmdAddArgList(fw, fwrule, "meta", "l4proto", "sctp", NU= LL); + ipHdr =3D &rule->p.sctpHdrFilter.ipHdr; + + if (nftablesHandleSrcMacAddr(fw, fwrule, vars, + &rule->p.sctpHdrFilter.dataSrcMACAddr)= < 0) + return -1; + + if (nftablesHandleIPHdr(fw, fwrule, vars, ipHdr, reverseRule) < 0) + return -1; + + if (nftablesHandlePortData(fw, fwrule, vars, protocol, + &rule->p.sctpHdrFilter.portData, reverseRule) < 0) + return -1; + break; + case VIR_NWFILTER_RULE_PROTOCOL_ICMP: + case VIR_NWFILTER_RULE_PROTOCOL_ICMPV6: + if (rule->prtclType =3D=3D VIR_NWFILTER_RULE_PROTOCOL_ICMPV6) { + virFirewallCmdAddArgList(fw, fwrule, "ip6", "nexthdr", NULL); + } else { + virFirewallCmdAddArgList(fw, fwrule, "ip", "protocol", NULL); + } + virFirewallCmdAddArg(fw, fwrule, protocol); + + ipHdr =3D &rule->p.icmpHdrFilter.ipHdr; + hasICMPType =3D true; + + if (nftablesHandleSrcMacAddr(fw, fwrule, vars, + &rule->p.icmpHdrFilter.dataSrcMACAddr)= < 0) + return -1; + + if (nftablesHandleIPHdr(fw, fwrule, vars, ipHdr, reverseRule) < 0) + return -1; + + if (HAS_ENTRY_ITEM(&rule->p.icmpHdrFilter.dataICMPType)) { + virFirewallCmdAddArgList(fw, fwrule, protocol, "type", NULL); + + if (virNWFilterPrintDataType(vars, + number, sizeof(number), + &rule->p.icmpHdrFilter.dataICMPTy= pe) < 0) + return -1; + + if (ENTRY_WANT_NEG_SIGN(&rule->p.icmpHdrFilter.dataICMPType)) + virFirewallCmdAddArg(fw, fwrule, "!=3D"); + + virFirewallCmdAddArg(fw, fwrule, number); + + if (HAS_ENTRY_ITEM(&rule->p.icmpHdrFilter.dataICMPCode)) { + virFirewallCmdAddArgList(fw, fwrule, protocol, "code", NUL= L); + + if (virNWFilterPrintDataType(vars, + number, sizeof(number), + &rule->p.icmpHdrFilter.dataIC= MPCode) < 0) + return -1; + + if (ENTRY_WANT_NEG_SIGN(&rule->p.icmpHdrFilter.dataICMPCod= e)) + virFirewallCmdAddArg(fw, fwrule, "!=3D"); + + virFirewallCmdAddArg(fw, fwrule, number); + } + } + break; + case VIR_NWFILTER_RULE_PROTOCOL_IGMP: + virFirewallCmdAddArgList(fw, fwrule, "meta", "l4proto", "igmp", NU= LL); + ipHdr =3D &rule->p.igmpHdrFilter.ipHdr; + + if (nftablesHandleSrcMacAddr(fw, fwrule, vars, + &rule->p.igmpHdrFilter.dataSrcMACAddr)= < 0) + return -1; + + if (nftablesHandleIPHdr(fw, fwrule, vars, ipHdr, reverseRule) < 0) + return -1; + break; + case VIR_NWFILTER_RULE_PROTOCOL_ALL: + case VIR_NWFILTER_RULE_PROTOCOL_ALLoIPV6: + ipHdr =3D &rule->p.allHdrFilter.ipHdr; + if (nftablesHandleSrcMacAddr(fw, fwrule, vars, + &rule->p.allHdrFilter.dataSrcMACAddr) = < 0) + return -1; + + if (nftablesHandleIPHdr(fw, fwrule, vars, ipHdr, reverseRule) < 0) + return -1; + break; + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unexpected protocol %1$d"), + rule->prtclType); + return -1; + } + + /* no support for ipset */ + if (HAS_ENTRY_ITEM(&ipHdr->dataIPSet) && + HAS_ENTRY_ITEM(&ipHdr->dataIPSetFlags)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Rule contains unsupported ipset flags")); + } + + /* apply conn limit only to outgoing connections */ + if (nftablesRuleNeedsConnLimit(ipHdr, directionIn)) { + if (virNWFilterPrintDataType(vars, + number, sizeof(number), + &ipHdr->dataConnlimitAbove) < 0) + return -1; + + /* place connlimit after potential state logic + since this is the most useful order */ + virFirewallCmdAddArgList(fw, fwrule, "ct", "count", "over", NULL); + if (ENTRY_WANT_NEG_SIGN(&ipHdr->dataConnlimitAbove)) + virFirewallCmdAddArg(fw, fwrule, "!=3D"); + virFirewallCmdAddArgList(fw, fwrule, number, NULL); + } + + if (nftablesRuleNeedsConntrack(rule)) { + /* we skip direction when ct count is set or type is icmp */ + skipDirection =3D nftablesRuleNeedsConnLimit(ipHdr, directionIn) || + hasICMPType; + + /* no direction */ + if (!skipDirection) + /* reverse rules are replies, + * otherwise it is the originating direction */ + virFirewallCmdAddArgList(fw, fwrule, "ct", "direction", + (reverseRule ? "reply" : "original"), + NULL); + + if (rule->flags & IPTABLES_STATE_FLAGS && + !(rule->flags & RULE_FLAG_STATE_NONE)) { + printStateMatchFlags(rule->flags, &matchState); + } else { + /* static state match is needed because when no state flags + * have been set but statematch is enabled we need a default */ + /* reverse rules are established connections */ + matchState =3D g_strdup(reverseRule ? + "established" : + "new,established"); + } + virFirewallCmdAddArgList(fw, fwrule, "ct", "state", matchState, NU= LL); + } + + return 0; +} + +static int +insertRuleArgParam(virFirewall *fw, + virFirewallCmd *fwrule, + virNWFilterVarCombIter *vars, + nwItemDesc *item, + const char *argument1, + const char *argument2) +{ + char field[VIR_INT64_STR_BUFLEN]; + + if (HAS_ENTRY_ITEM(item)) { + if (virNWFilterPrintDataType(vars, + field, sizeof(field), + item) < 0) + return -1; + virFirewallCmdAddArg(fw, fwrule, argument1); + virFirewallCmdAddArg(fw, fwrule, argument2); + if (ENTRY_WANT_NEG_SIGN(item)) + virFirewallCmdAddArg(fw, fwrule, "!=3D"); + + virFirewallCmdAddArg(fw, fwrule, field); + } + + return 0; +} + +static int insertRuleArgParamHex(virFirewall *fw, + virFirewallCmd *fwrule, + virNWFilterVarCombIter *vars, + nwItemDesc *item, + const char *argument1, + const char *argument2) +{ + char field[VIR_INT64_STR_BUFLEN]; + + if (HAS_ENTRY_ITEM(item)) { + if (virNWFilterPrintDataTypeAsHex(vars, + field, sizeof(field), + item) < 0) + return -1; + virFirewallCmdAddArg(fw, fwrule, argument1); + if (argument2 !=3D NULL) + virFirewallCmdAddArg(fw, fwrule, argument2); + if (ENTRY_WANT_NEG_SIGN(item)) + virFirewallCmdAddArg(fw, fwrule, "!=3D"); + + virFirewallCmdAddArg(fw, fwrule, field); + } + + return 0; +} + +static int insertRuleArgParamHexRange(virFirewall *fw, + virFirewallCmd *fwrule, + virNWFilterVarCombIter *vars, + nwItemDesc *itemLow, + nwItemDesc *itemHigh, + const char *argument) +{ + char fieldLow[VIR_INT64_STR_BUFLEN]; + char fieldHigh[VIR_INT64_STR_BUFLEN]; + + if (!HAS_ENTRY_ITEM(itemLow)) + return 0; + + if (virNWFilterPrintDataTypeAsHex(vars, fieldLow, sizeof(fieldLow), + itemLow) < 0) + return -1; + virFirewallCmdAddArg(fw, fwrule, argument); + + virFirewallCmdAddArg(fw, fwrule, ENTRY_WANT_NEG_SIGN(itemLow) ? "=3D= =3D" : "!=3D"); + + if (HAS_ENTRY_ITEM(itemHigh)) { + if (virNWFilterPrintDataTypeAsHex(vars, fieldHigh, sizeof(fieldHig= h), + itemHigh) < 0) + return -1; + virFirewallCmdAddArgFormat(fw, fwrule, "%s-%s", fieldLow, fieldHig= h); + } else { + virFirewallCmdAddArg(fw, fwrule, fieldLow); + } + + return 0; +} + +static int insertRulePayloadHexIPv4(virFirewall *fw, + virFirewallCmd *fwrule, + virNWFilterVarCombIter *vars, + nwItemDesc *itemIPAddr, + nwItemDesc *itemIPMask, + const char *payloadLocFormat) +{ + unsigned char buf[4]; + char ip[INET_ADDRSTRLEN]; + char maskstr[INET_ADDRSTRLEN]; + g_autofree char *hexstr =3D NULL; + virSocketAddr addr; + unsigned int mask =3D 32; + + if (!HAS_ENTRY_ITEM(itemIPAddr)) + return 0; + + /* parse mask to mask len */ + if (HAS_ENTRY_ITEM(itemIPMask)) { + if (virNWFilterPrintDataType(vars, maskstr, + sizeof(maskstr), itemIPMask) < 0) + return -1; + + if (virStrToLong_ui(maskstr, NULL, 10, &mask) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Cannot convert ipv4 mask to int '%1$s'"), maskst= r); + return -1; + } + } + + /* parse or retrieve the ip str */ + if (virNWFilterPrintDataType(vars, ip, sizeof(ip), itemIPAddr) < 0) + return -1; + + /* convert ip into a virSockAddr */ + if (virSocketAddrParseIPv4(&addr, ip) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Cannot parse ipv4 address '%1$s' in"), ip); + return -1; + } + + if (virSocketAddrMaskByPrefix(&addr, mask, &addr) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failure to mask address %1$s & %2$d"), ip, mask); + return -1; + } + + /* convert to byte array */ + if (virSocketAddrBytes(&addr, buf, sizeof(buf)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Cannot convert ipv4 address to byte array '%1$s'= "), ip); + return -1; + } + + hexstr =3D g_strdup_printf("0x%02x%02x%02x%02x", + buf[0], buf[1], buf[2], buf[3]); + + virFirewallCmdAddArgFormat(fw, fwrule, payloadLocFormat, mask); + + if (ENTRY_WANT_NEG_SIGN(itemIPAddr)) + virFirewallCmdAddArg(fw, fwrule, "!=3D"); + + virFirewallCmdAddArg(fw, fwrule, hexstr); + + return 0; +} + +static int insertRuleArgParamHexMac(virFirewall *fw, + virFirewallCmd *fwrule, + virNWFilterVarCombIter *vars, + nwItemDesc *item) +{ + unsigned char buf[VIR_MAC_BUFLEN]; + char mac[VIR_MAC_STRING_BUFLEN]; + g_autofree char *hexstr =3D NULL; + virMacAddr addr; + + /* parse or retrieve the mac str */ + if (virNWFilterPrintDataType(vars, mac, sizeof(mac), item) < 0) + return -1; + + /* convert mac into a virMacAddr */ + if (virMacAddrParse(mac, &addr) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("Cannot parse MAC address '%1$s'"), mac); + return -1; + } + + virMacAddrGetRaw(&addr, buf); + hexstr =3D g_strdup_printf("0x%02x%02x%02x%02x%02x%02x", + buf[0], buf[1], buf[2], + buf[3], buf[4], buf[5]); + + virFirewallCmdAddArg(fw, fwrule, hexstr); + + return 0; +} + +static int insertRulePayloadHexMac(virFirewall *fw, + virFirewallCmd *fwrule, + virNWFilterVarCombIter *vars, + nwItemDesc *item, + const char *payloadLoc) +{ + if (!HAS_ENTRY_ITEM(item)) + return 0; + + virFirewallCmdAddArg(fw, fwrule, payloadLoc); + if (ENTRY_WANT_NEG_SIGN(item)) + virFirewallCmdAddArg(fw, fwrule, "!=3D"); + + return insertRuleArgParamHexMac(fw, fwrule, vars, item); +} + +static int insertRulePayloadHexMacMask(virFirewall *fw, + virFirewallCmd *fwrule, + virNWFilterVarCombIter *vars, + nwItemDesc *mac, + nwItemDesc *mask, + const char *payloadLoc) +{ + if (!HAS_ENTRY_ITEM(mac)) + return 0; + + virFirewallCmdAddArg(fw, fwrule, payloadLoc); + + if (HAS_ENTRY_ITEM(mask)) { + virFirewallCmdAddArg(fw, fwrule, "&"); + + if (insertRuleArgParamHexMac(fw, fwrule, vars, mac) < 0) + return -1; + } + + if (ENTRY_WANT_NEG_SIGN(mac)) + virFirewallCmdAddArg(fw, fwrule, "!=3D"); + + return insertRuleArgParamHexMac(fw, fwrule, vars, mac); +} + +/* + * nftablesHandleEthernetRule: + * @fw: the firewall ruleset to add to + * @vars : A map containing the variables to resolve + * @rule: The rule of the filter to convert + * @reverseRule : Whether to reverse src and dst attributes + * ethernet reverse flag is set when direction=3D'inout' is= set + * + * Set arguments on fwrule based on given struct *rule + * + */ +static int +nftablesHandleEthernetRule(virFirewall *fw, + virFirewallCmd *fwrule, + virNWFilterVarCombIter *vars, + virNWFilterRuleDef *rule, + bool reverseRule) +{ + char number[VIR_INT64_STR_BUFLEN]; + char ipaddr[INET_ADDRSTRLEN]; + char ipmask[INET_ADDRSTRLEN]; + char ipv6addr[INET6_ADDRSTRLEN]; + bool hasMask =3D false; + const char *saddr =3D reverseRule ? "daddr" : "saddr"; + const char *daddr =3D reverseRule ? "saddr" : "daddr"; + + switch ((int)rule->prtclType) { + case VIR_NWFILTER_RULE_PROTOCOL_MAC: + if (nftablesHandleEthHdr(fw, fwrule, + vars, + &rule->p.ethHdrFilter.ethHdr, reverseRule= ) < 0) + return -1; + + if (insertRuleArgParamHex(fw, fwrule, vars, + &rule->p.ethHdrFilter.dataProtocolID, + "ether", "type") < 0) + return -1; + break; + case VIR_NWFILTER_RULE_PROTOCOL_IP: + virFirewallCmdAddArgList(fw, fwrule, "ether", "type", NULL); + if (ENTRY_WANT_NEG_SIGN(&rule->p.ipHdrFilter.ipHdr.dataProtocolID)) + virFirewallCmdAddArg(fw, fwrule, "!=3D"); + virFirewallCmdAddArg(fw, fwrule, "ip"); + + if (nftablesHandleEthHdr(fw, fwrule, + vars, + &rule->p.ipHdrFilter.ethHdr, reverseRule)= < 0) + return -1; + + if (HAS_ENTRY_ITEM(&rule->p.ipHdrFilter.ipHdr.dataSrcIPAddr)) { + if (virNWFilterPrintDataType(vars, + ipaddr, sizeof(ipaddr), + &rule->p.ipHdrFilter.ipHdr.dataSr= cIPAddr) < 0) + return -1; + + virFirewallCmdAddArgList(fw, fwrule, "ip", saddr, NULL); + if (ENTRY_WANT_NEG_SIGN(&rule->p.ipHdrFilter.ipHdr.dataSrcIPAd= dr)) + virFirewallCmdAddArg(fw, fwrule, "!=3D"); + + if (HAS_ENTRY_ITEM(&rule->p.ipHdrFilter.ipHdr.dataSrcIPMask)) { + if (virNWFilterPrintDataType(vars, + number, sizeof(number), + &rule->p.ipHdrFilter.ipHdr.da= taSrcIPMask) < 0) + return -1; + virFirewallCmdAddArgFormat(fw, fwrule, + "%s/%s", ipaddr, number); + } else { + virFirewallCmdAddArg(fw, fwrule, ipaddr); + } + } + + if (HAS_ENTRY_ITEM(&rule->p.ipHdrFilter.ipHdr.dataDstIPAddr)) { + if (virNWFilterPrintDataType(vars, + ipaddr, sizeof(ipaddr), + &rule->p.ipHdrFilter.ipHdr.dataDs= tIPAddr) < 0) + return -1; + + virFirewallCmdAddArgList(fw, fwrule, "ip", daddr, NULL); + if (ENTRY_WANT_NEG_SIGN(&rule->p.ipHdrFilter.ipHdr.dataDstIPAd= dr)) + virFirewallCmdAddArg(fw, fwrule, "!=3D"); + + if (HAS_ENTRY_ITEM(&rule->p.ipHdrFilter.ipHdr.dataDstIPMask)) { + if (virNWFilterPrintDataType(vars, + number, sizeof(number), + &rule->p.ipHdrFilter.ipHdr.da= taDstIPMask) < 0) + return -1; + virFirewallCmdAddArgFormat(fw, fwrule, + "%s/%s", ipaddr, number); + } else { + virFirewallCmdAddArg(fw, fwrule, ipaddr); + } + } + + if (insertRuleArgParam(fw, fwrule, vars, + &rule->p.ipHdrFilter.ipHdr.dataProtocolID, + "ip", "protocol") < 0) + return -1; + if (insertRuleArg2Param(fw, fwrule, vars, + &rule->p.ipHdrFilter.portData.dataSrcPortS= tart, + &rule->p.ipHdrFilter.portData.dataSrcPortE= nd, + "th", reverseRule ? "dport" : "sport", "-"= ) < 0) + return -1; + if (insertRuleArg2Param(fw, fwrule, vars, + &rule->p.ipHdrFilter.portData.dataDstPortS= tart, + &rule->p.ipHdrFilter.portData.dataDstPortE= nd, + "th", reverseRule ? "sport" : "dport", "-"= ) < 0) + return -1; + if (insertRuleArgParamHex(fw, fwrule, vars, + &rule->p.ipHdrFilter.ipHdr.dataDSCP, + "ip", "dscp") < 0) + return -1; + break; + case VIR_NWFILTER_RULE_PROTOCOL_ARP: + if (nftablesHandleEthHdr(fw, fwrule, + vars, + &rule->p.arpHdrFilter.ethHdr, reverseRule= ) < 0) + return -1; + + virFirewallCmdAddArgList(fw, fwrule, "ether", "type", NULL); + virFirewallCmdAddArgFormat(fw, fwrule, "0x%x", + l3_protocols[VIR_NWFILTER_PROTO_IDX_ARP= ].attr); + + if (insertRuleArgParam(fw, fwrule, vars, + &rule->p.arpHdrFilter.dataHWType, + "arp", "htype") < 0) + return -1; + if (insertRuleArgParamHex(fw, fwrule, vars, + &rule->p.arpHdrFilter.dataProtocolType, + "arp", "ptype") < 0) + return -1; + if (insertRuleArgParam(fw, fwrule, vars, + &rule->p.arpHdrFilter.dataOpcode, + "arp", "operation") < 0) + return -1; + + if (HAS_ENTRY_ITEM(&rule->p.arpHdrFilter.dataARPSrcIPAddr)) { + if (virNWFilterPrintDataType(vars, + ipaddr, sizeof(ipaddr), + &rule->p.arpHdrFilter.dataARPSrcI= PAddr) < 0) + return -1; + + if (HAS_ENTRY_ITEM(&rule->p.arpHdrFilter.dataARPSrcIPMask)) { + if (virNWFilterPrintDataType(vars, + ipmask, sizeof(ipmask), + &rule->p.arpHdrFilter.dataARP= SrcIPMask) < 0) + return -1; + hasMask =3D true; + } + + virFirewallCmdAddArgList(fw, fwrule, "arp", saddr, "ip", NULL); + if (ENTRY_WANT_NEG_SIGN(&rule->p.arpHdrFilter.dataARPSrcIPAddr= )) + virFirewallCmdAddArg(fw, fwrule, "!=3D"); + virFirewallCmdAddArgFormat(fw, fwrule, + "%s/%s", ipaddr, hasMask ? ipmask := "32"); + } + + if (HAS_ENTRY_ITEM(&rule->p.arpHdrFilter.dataARPDstIPAddr)) { + if (virNWFilterPrintDataType(vars, + ipaddr, sizeof(ipaddr), + &rule->p.arpHdrFilter.dataARPDstI= PAddr) < 0) + return -1; + + if (HAS_ENTRY_ITEM(&rule->p.arpHdrFilter.dataARPDstIPMask)) { + if (virNWFilterPrintDataType(vars, + ipmask, sizeof(ipmask), + &rule->p.arpHdrFilter.dataARP= DstIPMask) < 0) + return -1; + hasMask =3D true; + } + + virFirewallCmdAddArgList(fw, fwrule, "arp", daddr, "ip", NULL); + if (ENTRY_WANT_NEG_SIGN(&rule->p.arpHdrFilter.dataARPDstIPAddr= )) + virFirewallCmdAddArg(fw, fwrule, "!=3D"); + virFirewallCmdAddArgFormat(fw, fwrule, + "%s/%s", ipaddr, hasMask ? ipmask := "32"); + } + + if (nftablesHandleMacAddr(fw, fwrule, vars, + &rule->p.arpHdrFilter.dataARPSrcMACAddr, + "arp", saddr, "ether") < 0) + return -1; + if (nftablesHandleMacAddr(fw, fwrule, vars, + &rule->p.arpHdrFilter.dataARPDstMACAddr, + "arp", daddr, "ether") < 0) + return -1; + + nftablesHandleGarp(fw, fwrule, &rule->p.arpHdrFilter.dataGratuitou= sARP); + break; + case VIR_NWFILTER_RULE_PROTOCOL_RARP: + if (nftablesHandleEthHdr(fw, fwrule, + vars, + &rule->p.arpHdrFilter.ethHdr, reverseRule= ) < 0) + return -1; + + virFirewallCmdAddArgList(fw, fwrule, "ether", "type", NULL); + virFirewallCmdAddArgFormat(fw, fwrule, "0x%x", + l3_protocols[VIR_NWFILTER_PROTO_IDX_RAR= P].attr); + + /* @nh (network header), N (bits offset), N (bits length) */ + if (insertRuleArgParamHex(fw, fwrule, vars, + &rule->p.arpHdrFilter.dataHWType, + "@nh,0,16", NULL) < 0) + return -1; + if (insertRuleArgParamHex(fw, fwrule, vars, + &rule->p.arpHdrFilter.dataProtocolType, + "@nh,40,16", NULL) < 0) + return -1; + if (insertRuleArgParamHex(fw, fwrule, vars, + &rule->p.arpHdrFilter.dataOpcode, + "@nh,48,16", NULL) < 0) + return -1; + if (insertRulePayloadHexIPv4(fw, fwrule, vars, + &rule->p.arpHdrFilter.dataARPSrcIPAdd= r, + &rule->p.arpHdrFilter.dataARPSrcIPMas= k, + "@nh,112,%d") < 0) + return -1; + if (insertRulePayloadHexIPv4(fw, fwrule, vars, + &rule->p.arpHdrFilter.dataARPDstIPAdd= r, + &rule->p.arpHdrFilter.dataARPDstIPMas= k, + "@nh,192,%d") < 0) + return -1; + if (insertRulePayloadHexMac(fw, fwrule, vars, + &rule->p.arpHdrFilter.dataARPSrcMACAdd= r, + "@nh,64,48") < 0) + return -1; + if (insertRulePayloadHexMac(fw, fwrule, vars, + &rule->p.arpHdrFilter.dataARPDstMACAdd= r, + "@nh,144,48") < 0) + return -1; + + nftablesHandleGarp(fw, fwrule, &rule->p.arpHdrFilter.dataGratuitou= sARP); + break; + case VIR_NWFILTER_RULE_PROTOCOL_IPV6: + if (nftablesHandleEthHdr(fw, fwrule, + vars, + &rule->p.ipv6HdrFilter.ethHdr, reverseRul= e) < 0) + return -1; + + virFirewallCmdAddArgList(fw, fwrule, "ether", "type", "ip6", NULL); + + if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.ipHdr.dataSrcIPAddr)) { + if (virNWFilterPrintDataType(vars, + ipv6addr, sizeof(ipv6addr), + &rule->p.ipv6HdrFilter.ipHdr.data= SrcIPAddr) < 0) + return -1; + + virFirewallCmdAddArgList(fw, fwrule, "ip6", saddr, NULL); + if (ENTRY_WANT_NEG_SIGN(&rule->p.ipv6HdrFilter.ipHdr.dataSrcIP= Addr)) + virFirewallCmdAddArg(fw, fwrule, "!=3D"); + + if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.ipHdr.dataSrcIPMask)= ) { + if (virNWFilterPrintDataType(vars, + number, sizeof(number), + &rule->p.ipv6HdrFilter.ipHdr.= dataSrcIPMask) < 0) + return -1; + virFirewallCmdAddArgFormat(fw, fwrule, + "%s/%s", ipv6addr, number); + } else { + virFirewallCmdAddArg(fw, fwrule, ipv6addr); + } + } + + if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.ipHdr.dataDstIPAddr)) { + + if (virNWFilterPrintDataType(vars, + ipv6addr, sizeof(ipv6addr), + &rule->p.ipv6HdrFilter.ipHdr.data= DstIPAddr) < 0) + return -1; + + virFirewallCmdAddArgList(fw, fwrule, "ip6", daddr, NULL); + if (ENTRY_WANT_NEG_SIGN(&rule->p.ipv6HdrFilter.ipHdr.dataDstIP= Addr)) + virFirewallCmdAddArg(fw, fwrule, "!=3D"); + + if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.ipHdr.dataDstIPMask)= ) { + if (virNWFilterPrintDataType(vars, + number, sizeof(number), + &rule->p.ipv6HdrFilter.ipHdr.= dataDstIPMask) < 0) + return -1; + virFirewallCmdAddArgFormat(fw, fwrule, + "%s/%s", ipv6addr, number); + } else { + virFirewallCmdAddArg(fw, fwrule, ipv6addr); + } + } + + if (insertRuleArgParam(fw, fwrule, vars, + &rule->p.ipv6HdrFilter.ipHdr.dataProtocolID, + "ip6", "nexthdr") < 0) + return -1; + if (insertRuleArg2Param(fw, fwrule, vars, + &rule->p.ipv6HdrFilter.portData.dataSrcPor= tStart, + &rule->p.ipv6HdrFilter.portData.dataSrcPor= tEnd, + "th", reverseRule ? "dport" : "sport", "-"= ) < 0) + return -1; + if (insertRuleArg2Param(fw, fwrule, vars, + &rule->p.ipv6HdrFilter.portData.dataDstPor= tStart, + &rule->p.ipv6HdrFilter.portData.dataDstPor= tEnd, + "th", reverseRule ? "sport" : "dport", "-"= ) < 0) + return -1; + if (HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.dataICMPTypeStart) || + HAS_ENTRY_ITEM(&rule->p.ipv6HdrFilter.dataICMPCodeStart)) { + + if (insertRuleArgParam(fw, fwrule, vars, + &rule->p.ipv6HdrFilter.dataICMPTypeStar= t, + "icmpv6", "type") < 0) + return -1; + if (insertRuleArgParam(fw, fwrule, vars, + &rule->p.ipv6HdrFilter.dataICMPCodeStar= t, + "icmpv6", "code") < 0) + return -1; + } + break; + case VIR_NWFILTER_RULE_PROTOCOL_VLAN: + if (nftablesHandleEthHdr(fw, fwrule, + vars, + &rule->p.vlanHdrFilter.ethHdr, reverseRul= e) < 0) + return -1; + + virFirewallCmdAddArgList(fw, fwrule, "ether", "type", "0x8100", NU= LL); + + if (insertRuleArgParam(fw, fwrule, vars, + &rule->p.vlanHdrFilter.dataVlanID, + "vlan", "id") < 0) + return -1; + if (insertRuleArgParam(fw, fwrule, vars, + &rule->p.vlanHdrFilter.dataVlanEncap, + "vlan", "type") < 0) + return -1; + break; + case VIR_NWFILTER_RULE_PROTOCOL_STP: + if (reverseRule && + HAS_ENTRY_ITEM(&rule->p.stpHdrFilter.ethHdr.dataSrcMACAddr)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("STP filtering in %1$s direction with source = MAC address set is not supported"), + virNWFilterRuleDirectionTypeToString( + VIR_NWFILTER_RULE_DIRECTION_INOUT)); + return -1; + } + if (nftablesHandleEthHdr(fw, fwrule, + vars, + &rule->p.stpHdrFilter.ethHdr, reverseRule= ) < 0) + return -1; + + virFirewallCmdAddArgList(fw, fwrule, "ether", "daddr", + NWFILTER_MAC_BGA, NULL); + + /* @nh (network header), N (bits offset), N (bits length) */ + + if (insertRuleArgParamHex(fw, fwrule, vars, + &rule->p.stpHdrFilter.dataType, + "@nh,48,8", NULL) < 0) + return -1; + if (insertRuleArgParamHex(fw, fwrule, vars, + &rule->p.stpHdrFilter.dataFlags, + "@nh,56,8", NULL) < 0) + return -1; + if (insertRuleArgParamHexRange(fw, fwrule, vars, + &rule->p.stpHdrFilter.dataRootPri, + &rule->p.stpHdrFilter.dataRootPriHi, + "@nh,64,16") < 0) + return -1; + if (insertRulePayloadHexMacMask(fw, fwrule, vars, + &rule->p.stpHdrFilter.dataRootAddr, + &rule->p.stpHdrFilter.dataRootAddr= Mask, + "@nh,80,48") < 0) + return -1; + if (insertRuleArgParamHexRange(fw, fwrule, vars, + &rule->p.stpHdrFilter.dataRootCost, + &rule->p.stpHdrFilter.dataRootCostH= i, + "@nh,128,32") < 0) + return -1; + if (insertRuleArgParamHexRange(fw, fwrule, vars, + &rule->p.stpHdrFilter.dataSndrPrio, + &rule->p.stpHdrFilter.dataSndrPrioH= i, + "@nh,160,16") < 0) + return -1; + if (insertRulePayloadHexMacMask(fw, fwrule, vars, + &rule->p.stpHdrFilter.dataSndrAddr, + &rule->p.stpHdrFilter.dataSndrAddr= Mask, + "@nh,176,48") < 0) + return -1; + if (insertRuleArgParamHexRange(fw, fwrule, vars, + &rule->p.stpHdrFilter.dataPort, + &rule->p.stpHdrFilter.dataPortHi, + "@nh,224,16") < 0) + return -1; + if (insertRuleArgParamHexRange(fw, fwrule, vars, + &rule->p.stpHdrFilter.dataAge, + &rule->p.stpHdrFilter.dataAgeHi, + "@nh,240,16") < 0) + return -1; + if (insertRuleArgParamHexRange(fw, fwrule, vars, + &rule->p.stpHdrFilter.dataMaxAge, + &rule->p.stpHdrFilter.dataMaxAgeHi, + "@nh,256,16") < 0) + return -1; + if (insertRuleArgParamHexRange(fw, fwrule, vars, + &rule->p.stpHdrFilter.dataHelloTime, + &rule->p.stpHdrFilter.dataHelloTime= Hi, + "@nh,272,16") < 0) + return -1; + if (insertRuleArgParamHexRange(fw, fwrule, vars, + &rule->p.stpHdrFilter.dataFwdDelay, + &rule->p.stpHdrFilter.dataFwdDelayH= i, + "@nh,288,16") < 0) + return -1; + + break; + case VIR_NWFILTER_RULE_PROTOCOL_NONE: + break; + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unexpected rule protocol '%1$d', priority '%2$d'= "), + rule->prtclType, + rule->priority); + return -1; + } + + return 0; +} + +/* + * nftablesGetNFTable: + * + * @rule: The rule of the filter + * + * We have a seperate table, due to eb/iptables compatibilty + * Ideally we allow users to have only 1 table in which all rules are plac= ed + * We'll need to turn that into a nwfilter feature + */ +static const char *nftablesGetNFTable(virNWFilterRuleDef *rule) +{ + return virNWFilterRuleIsProtocolEthernet(rule) ? + NF_ETHERNET_TABLE : + NF_INET_TABLE; +} + +static void +nftablesAddCmdUserComment(virFirewall *fw, + virFirewallCmd *fwrule, + virNWFilterRuleDef *rule) +{ + g_autofree char *comment =3D NULL; + comment =3D virStringReplace( + rule->p.allHdrFilter.ipHdr.dataComment.u.string, + "\"", "'"); + + virFirewallCmdAddArg(fw, fwrule, "comment"); + virFirewallCmdAddArgFormat(fw, fwrule, "\"usercomment=3D%s\"", comment= ); +} + +/* + * nftablesCreateRuleInstance: + * @fw: the firewall ruleset instance + * @layer: the firewall layer + * @chainPrefix: The suffix to put on the end of the name of the chain + * @rule: The rule of the filter to convert + * @ifname : The name of the interface to apply the rule to + * @vars : A map containing the variables to resolve + * @res : The data structure to store the result(s) into + * + * Convert a single rule into its representation for later instantiation + * + * Returns 0 in case of success with the result stored in the data structu= re + * pointed to by res, -1 otherwise + */ +static int +nftablesCreateRuleInstance(virFirewall *fw, + virFirewallLayer layer, + const char *chainPrefix, + virNWFilterRuleDef *rule, + const char *ifname, + virNWFilterVarCombIter *vars, + bool directionIn, + bool reverseRule) +{ + int ret =3D -1; + char chain[MAX_NF_CHAINNAME_LENGTH]; + virFirewallCmd *fwrule =3D NULL; + const char *root =3D virNWFilterChainSuffixTypeToString( + VIR_NWFILTER_CHAINSUFFIX_ROOT); + const char *nftablesRootTable =3D nftablesGetNFTable(rule); + + /* apply root rules directly on the root chain, for example: + * vnet1-in vnet1-out */ + if (STREQ(chainPrefix, root)) { + g_snprintf(chain, sizeof(chain), "n-%s-%s", ifname, + directionIn ? "in" : "out"); + } else { + g_snprintf(chain, sizeof(chain), "n-%s-%s-%s", ifname, chainPrefix, + directionIn ? "in" : "out"); + } + + fwrule =3D virFirewallAddCmd(fw, layer, + "add", "rule", "bridge", + nftablesRootTable, chain, NULL); + + if (virNWFilterRuleIsProtocolEthernet(rule)) { + if (nftablesHandleEthernetRule(fw, fwrule, vars, rule, reverseRule= ) < 0) + goto cleanup; + } else { + if (nftablesHandleInetRule(fw, fwrule, vars, rule, + directionIn, reverseRule) < 0) + goto cleanup; + } + + if (NF_COUNTER) + virFirewallCmdAddArg(fw, fwrule, "counter"); + + /* specify the action for this rule */ + nftablesAddCmdAction(fw, fwrule, rule->action); + + + /* ethernet rules don't have the allHdrFilter */ + if (HAS_ENTRY_ITEM(&rule->p.allHdrFilter.ipHdr.dataComment) && + !virNWFilterRuleIsProtocolEthernet(rule)) { + nftablesAddCmdUserComment(fw, fwrule, rule); + } + + ret =3D 0; + + cleanup: + if (ret =3D=3D -1) + virFirewallRemoveCmd(fw, fwrule); + + return ret; +} + +static int +nftablesRuleInstCommand(virFirewall *fw, + virFirewallLayer layer, + const char *ifname, + virNWFilterRuleInst *rule) +{ + int ret =3D -1; + virNWFilterVarCombIter *vciter; + virNWFilterVarCombIter *tmp; + virNWFilterRuleDirectionType direction =3D rule->def->tt; + + /* rule->vars holds all the variables names that this rule will access. + * iterate over all combinations of the variables' values and instanti= ate + * the filtering rule with each combination. + */ + tmp =3D vciter =3D virNWFilterVarCombIterCreate(rule->vars, + rule->def->varAccess, + rule->def->nVarAccess); + if (!vciter) + return -1; + + do { + bool reverseRule =3D false; + + VIR_DEBUG("rule[chain=3D'%s', dir=3D'%d', prio=3D'%d', action=3D'%= d', chainPrio=3D'%d']", + rule->chainSuffix, + direction, + rule->priority, + rule->def->action, + rule->chainPriority); + + if (direction =3D=3D VIR_NWFILTER_RULE_DIRECTION_INOUT) { + /* for direction inout we run the create instance twice, + * with directionIn set to true and false */ + + /* in */ + if (nftablesCreateRuleInstance(fw, layer, rule->chainSuffix, + rule->def, ifname, tmp, + true, reverseRule) < 0) + goto cleanup; + + /* for ethernet rules, to comply to what ebiptables did, + * we set reverseRule to true on direction inout */ + reverseRule =3D virNWFilterRuleIsProtocolEthernet(rule->def); + + /* out */ + if (nftablesCreateRuleInstance(fw, layer, rule->chainSuffix, + rule->def, ifname, tmp, + false, reverseRule) < 0) + goto cleanup; + } else { + bool directionIn =3D direction =3D=3D VIR_NWFILTER_RULE_DIRECT= ION_IN; + /* otherwise we provide directionIn */ + if (nftablesCreateRuleInstance(fw, layer, rule->chainSuffix, + rule->def, ifname, tmp, + directionIn, reverseRule) < 0) + goto cleanup; + + /* rules that do conntrack matching and have action accept nee= d a + * reverse rule on the other chain to accept the reply directi= on + * so if we accept outbound we need an accept on the inbound f= or + * established connections */ + if (nftablesRuleNeedsConntrack(rule->def) && + rule->def->action =3D=3D VIR_NWFILTER_RULE_ACTION_ACCEPT) { + reverseRule =3D true; + if (nftablesCreateRuleInstance(fw, layer, rule->chainSuffi= x, + rule->def, ifname, tmp, + !directionIn, reverseRule) = < 0) + goto cleanup; + } + } + + tmp =3D virNWFilterVarCombIterNext(tmp); + } while (tmp !=3D NULL); + + ret =3D 0; + cleanup: + virNWFilterVarCombIterFree(vciter); + + return ret; +} + +/* + * nftablesCreateSubChain: + * @fw: the firewall ruleset instance + * @layer: the firewall layer + * @ifname : The name of the interface to apply the chain to + * @chainPrefix: The prefix to put on the beginning of the name of the cha= in + * @protoidx: Protocol id for conditional jump + * @rootChain: The chain to define the jump on + * @chainPostfix: The postfix to put at the end of the name of the chain + * + * Creates the user defined chain, chain=3D'mac', with chainPostfix set to= 'in' + * on vnet1 for example leads to: + * - vnet1-mac-in + * + * Rules get defined on the corresponding chain based on the chosen direct= ion, + * either in or out or both (in and out) when direction has been set to 'i= nout' + */ +static void +nftablesCreateSubChain(virFirewall *fw, + virFirewallLayer layer, + const char *nftablesTableName, + const char *chainPrefix, + enum virNWFilterProtoIdx protoidx, + const char *rootChain, + const char *chainPostfix) +{ + char chain[MAX_NF_CHAINNAME_LENGTH]; + virFirewallCmd *fwrule =3D NULL; + g_snprintf(chain, sizeof(chain), "%s-%s", chainPrefix, chainPostfix); + + VIR_DEBUG("Defining chain '%s'", chain); + + virFirewallAddCmd(fw, layer, "add", "chain", "bridge", + nftablesTableName, chain, CHAINSETTINGS, NULL); + + /* add VM interface jump */ + fwrule =3D virFirewallAddCmd(fw, layer, "add", "rule", "bridge", + nftablesTableName, rootChain, NULL); + if (protoidx !=3D -1 && l3_protocols[protoidx].attr) { + virFirewallCmdAddArgList(fw, fwrule, "ether", "type", NULL); + virFirewallCmdAddArgFormat(fw, fwrule, + "0x%04x", l3_protocols[protoidx].attr); + } else if (protoidx =3D=3D VIR_NWFILTER_PROTO_IDX_STP) { + virFirewallCmdAddArgList(fw, fwrule, "ether", "daddr", + NWFILTER_MAC_BGA, NULL); + } + + virFirewallCmdAddArgList(fw, fwrule, "jump", chain, NULL); +} + +static void +nftablesCreateRootChainJump(virFirewall *fw, + virFirewallLayer layer, + const char *ifname, + const char *ifMatch, + const char *topChain, + const char *rootChain, + bool addTmpJump) +{ + virFirewallCmd *fwrule =3D NULL; + + /* add a tmp jump to avoid a firewall hole between + * updating vmap */ + if (addTmpJump) { + /* tmp iif oif jump */ + virFirewallAddCmd(fw, layer, "add", "rule", "bridge", NF_INET_TABL= E, + topChain, ifMatch, ifname, "jump", rootChain, NU= LL); + virFirewallAddCmd(fw, layer, "add", "rule", "bridge", NF_ETHERNET_= TABLE, + topChain, ifMatch, ifname, "jump", rootChain, NU= LL); + } + + /* remove VM interface jump */ + fwrule =3D virFirewallAddCmdFull(fw, layer, true, NULL, NULL, "delete", + "element", "bridge", NF_INET_TABLE, NUL= L); + virFirewallCmdAddArgFormat(fw, fwrule, "vmap-%s", ifMatch); + virFirewallCmdAddArgList(fw, fwrule, "{", ifname, "}", NULL); + /* add VM interface jump */ + fwrule =3D virFirewallAddCmd(fw, layer, "add", "element", "bridge", + NF_INET_TABLE, NULL); + virFirewallCmdAddArgFormat(fw, fwrule, "vmap-%s", ifMatch); + virFirewallCmdAddArgList(fw, fwrule, "{", ifname, ":", "jump", + rootChain, "}", NULL); + + /* remove VM interface jump */ + fwrule =3D virFirewallAddCmdFull(fw, layer, true, NULL, NULL, "delete", + "element", "bridge", + NF_ETHERNET_TABLE, NULL); + virFirewallCmdAddArgFormat(fw, fwrule, "vmap-%s", ifMatch); + virFirewallCmdAddArgList(fw, fwrule, "{", ifname, "}", NULL); + /* add VM interface jump */ + fwrule =3D virFirewallAddCmd(fw, layer, "add", "element", "bridge", + NF_ETHERNET_TABLE, NULL); + virFirewallCmdAddArgFormat(fw, fwrule, "vmap-%s", ifMatch); + virFirewallCmdAddArgList(fw, fwrule, "{", ifname, ":", "jump", rootCha= in, + "}", NULL); +} + +/* + * nftablesCreateRootChain: + * @fw: the firewall ruleset instance + * @layer: the firewall layer + * @ifname : The name of the interface to apply the chain to + * @ifMatch : The matcher to use for this root chain, iif/oif + * @chainPrefix: The prefix to put on the beginning of the name of the cha= in + * @protoidx: Protocol id for conditional jump + * @topChain: The chain to define the jump on + * @rootChain: The root chain for the interface to create + * + * Creates the interface root chain, chainPostfix set to 'in' + * on vnet1 for example, leads to: + * - vnet1-in + * + * These root chains are the chains where all the subchains jumps get adde= d to + * vnet1-in -> jump vnet-mac-in; ether type ip jump vnet-ip-in; + */ +static void +nftablesCreateRootChain(virFirewall *fw, + virFirewallLayer layer, + const char *rootChain) +{ + VIR_DEBUG("Defining root chain '%s'", rootChain); + + virFirewallAddCmd(fw, layer, "add", "chain", "bridge", + NF_ETHERNET_TABLE, rootChain, CHAINSETTINGS, NULL); + + virFirewallAddCmd(fw, layer, "add", "chain", "bridge", + NF_INET_TABLE, rootChain, CHAINSETTINGS, NULL); +} + +typedef struct _nftablesSubChain nftablesSubChain; +struct _nftablesSubChain { + /* we use the lowest rule priority in a chain to compare root rule ins= erts + * see nftablesHandleCreateChains for the explanation */ + virNWFilterRulePriority lowestRulePriority; + virNWFilterChainPriority priority; + enum virNWFilterProtoIdx protoidx; + char prefix[MAX_NF_CHAINNAME_LENGTH]; + const char *suffix; + bool hasEthernetRules; + bool hasInetRules; + /* to prevent creation of empty chains, + * we track wether or not there are in/out | inout directions */ + bool ethernetOutChain; + bool ethernetInChain; + bool inetOutChain; + bool inetInChain; +}; + +static int nftablesChainCreateSort(const void *a, const void *b, + void *opaque G_GNUC_UNUSED) +{ + const nftablesSubChain *insta =3D *(const nftablesSubChain **)a; + const nftablesSubChain *instb =3D *(const nftablesSubChain **)b; + const char *root =3D virNWFilterChainSuffixTypeToString( + VIR_NWFILTER_CHAINSUFFIX_ROOT); + bool root_a =3D STREQ(insta->suffix, root); + bool root_b =3D STREQ(instb->suffix, root); + + /* ensure root chain commands appear before all others since + we will need them to create the child chains */ + if (root_a) { + if (!root_b) + return -1; /* a before b */ + } else if (root_b) { + return 1; /* b before a */ + } + + /* priorities are limited to range [-1000, 1000] */ + return insta->priority - instb->priority; +} + +static void +updateChainFlags(nftablesSubChain *chain, virNWFilterRuleDef *rule) +{ + bool isEthernet =3D virNWFilterRuleIsProtocolEthernet(rule); + bool in =3D rule->tt =3D=3D VIR_NWFILTER_RULE_DIRECTION_IN || + rule->tt =3D=3D VIR_NWFILTER_RULE_DIRECTION_INOUT; + bool out =3D rule->tt =3D=3D VIR_NWFILTER_RULE_DIRECTION_OUT || + rule->tt =3D=3D VIR_NWFILTER_RULE_DIRECTION_INOUT; + + if (isEthernet) { + chain->hasEthernetRules =3D true; + chain->ethernetInChain |=3D in; + chain->ethernetOutChain |=3D out; + } else { + chain->hasInetRules =3D true; + chain->inetInChain |=3D in; + chain->inetOutChain |=3D out; + } +} + +static void +nftablesGetSubChains(nftablesSubChain ***chains, + size_t *nchains, + virNWFilterRuleInst **rules, + size_t nrules, + const char *ifname) +{ + size_t i, j; + + for (i =3D 0; i < nrules; i++) { + g_autofree nftablesSubChain *chain =3D NULL; + nftablesSubChain **chainst =3D *chains; + + for (j =3D 0; j < *nchains; j++) { + if (STRNEQ(rules[i]->chainSuffix, chainst[j]->suffix)) + continue; + + VIR_DEBUG("Chain already registered '%s'", chainst[j]->suffix); + updateChainFlags(chainst[j], rules[i]->def); + goto next_rule; + } + + /* filter out the root chain */ + if (STREQ(rules[i]->chainSuffix, + virNWFilterChainSuffixTypeToString(VIR_NWFILTER_CHAINSUFFIX_RO= OT))) + continue; + + /* register the chain for creation */ + chain =3D g_new0(nftablesSubChain, 1); + + updateChainFlags(chain, rules[i]->def); + chain->priority =3D rules[i]->chainPriority; + chain->lowestRulePriority =3D rules[i]->priority; + chain->suffix =3D rules[i]->chainSuffix; + g_snprintf(chain->prefix, sizeof(chain->prefix), + "n-%s-%s", ifname, chain->suffix); + + VIR_APPEND_ELEMENT(*chains, *nchains, chain); + + next_rule: + continue; + } +} + +static int +nftablesHandleCreateChains(virFirewall *fw, + virFirewallLayer layer, + const char *const *lines G_GNUC_UNUSED, + void *opaque) +{ + size_t i, j, nchains =3D 0; + size_t lastProcessedRootRuleIndex =3D 0; + int ret =3D -1; + virNWFilterChainCreateCallbackData *cbdata =3D opaque; + nftablesSubChain **chains =3D NULL; + char rootChainIn[MAX_NF_CHAINNAME_LENGTH]; + char rootChainOut[MAX_NF_CHAINNAME_LENGTH]; + bool ethernetRootRuleSorting, inetRootRuleSorting; + const char *rootChainName =3D virNWFilterChainSuffixTypeToString( + VIR_NWFILTER_CHAINSUFFIX_ROOT); + g_snprintf(rootChainIn, sizeof(rootChainIn), "n-%s-in", cbdata->ifname= ); + g_snprintf(rootChainOut, sizeof(rootChainOut), "n-%s-out", cbdata->ifn= ame); + + nftablesGetSubChains(&chains, + &nchains, + cbdata->rules, + cbdata->nrules, + cbdata->ifname); + + /* sort chains on their chain priority */ + g_qsort_with_data(chains, nchains, sizeof(chains[0]), + nftablesChainCreateSort, NULL); + + /* first we create the root interface in-out chains */ + nftablesCreateRootChain(fw, layer, rootChainIn); + nftablesCreateRootChain(fw, layer, rootChainOut); + + /* + * Root chain ordering is special. + * + * Filtering rules on the root chain must be interleaved with subchain + * definitions and jumps based on priority. This is required to stay + * compatible with behavior from the ebiptables driver, where root rul= es + * may need to appear before or after chain jumps depending on priorit= y. + * + * Historical note: + * - In the ebiptables driver, iptables/ip6tables had no subchains; + * all inet rules lived directly on the root chain. + * - To avoid duplicating logic for ethernet and inet, we now define + * chains and rules once and apply table-specific ordering instead. + * + * Only the root chain needs this handling. All other chains are alrea= dy + * sorted correctly. Chains cannot be created lazily during rule + * processing, as chains themselves have priorities. + * + * Therefor we apply the following logic: + * - Create the root chain first + * - Process root rules and subchains in priority order + * - Root rules are inserted according to rule priority + * - Subchains are created (with their jump) when their priority req= uires it + * + * Table specific behavior (ethernetRootRuleSorting/inetRootRuleSortin= g): + * - inet: rule->priority vs chain->lowestRulePriority + * - enet: rule->priority vs chain->priority + */ + + /* create chain if it doesn't exist */ + /* define undefined sub chains */ + for (i =3D 0; i < nchains; i++) { + enum virNWFilterProtoIdx protoidx; + + /* root chain firewall rules, if there are root chain firewall rul= es + * with a lower priority than this chains lowest rule priority */ + for (j =3D lastProcessedRootRuleIndex; j < cbdata->nrules; j++) { + /* as root rules are inserted before all other rules, + * we stop walking the rules list when we've hit a no root rul= e*/ + if (STRNEQ(cbdata->rules[j]->chainSuffix, rootChainName)) { + break; + } + + ethernetRootRuleSorting =3D virNWFilterRuleIsProtocolEthernet(= cbdata->rules[j]->def); + inetRootRuleSorting =3D !ethernetRootRuleSorting; + + lastProcessedRootRuleIndex =3D j; + if ((inetRootRuleSorting && chains[i]->lowestRulePriority > cb= data->rules[j]->priority) || + (ethernetRootRuleSorting && chains[i]->priority > cbdata->= rules[j]->priority)) { + if (nftablesRuleInstCommand(fw, layer, + cbdata->ifname, + cbdata->rules[j]) < 0) + goto cleanup; + } else { + break; + } + } + + protoidx =3D nftablesGetProtoIdxByFiltername(chains[i]->suffix); + if (chains[i]->ethernetInChain) + nftablesCreateSubChain(fw, layer, NF_ETHERNET_TABLE, + chains[i]->prefix, protoidx, + rootChainIn, "in"); + if (chains[i]->ethernetOutChain) + nftablesCreateSubChain(fw, layer, NF_ETHERNET_TABLE, + chains[i]->prefix, protoidx, + rootChainOut, "out"); + if (chains[i]->inetInChain) + nftablesCreateSubChain(fw, layer, NF_INET_TABLE, + chains[i]->prefix, protoidx, + rootChainIn, "in"); + if (chains[i]->inetOutChain) + nftablesCreateSubChain(fw, layer, NF_INET_TABLE, + chains[i]->prefix, protoidx, + rootChainOut, "out"); + } + + /* process the firewall rules and chains */ + /* everything before lastProcessedRootRuleIndex has been created */ + for (i =3D lastProcessedRootRuleIndex; i < cbdata->nrules; i++) { + if (nftablesRuleInstCommand(fw, layer, + cbdata->ifname, cbdata->rules[i]) < 0) + goto cleanup; + } + + /* creation of temp jumps is done as libvirt doesn't execute + * atomic nft changes (yet) */ + nftablesCreateRootChainJump(fw, layer, cbdata->ifname, IN_IFMATCH, + IN_CHAIN, rootChainIn, true); + nftablesCreateRootChainJump(fw, layer, cbdata->ifname, OUT_IFMATCH, + OUT_CHAIN, rootChainOut, true); + + ret =3D 0; + + cleanup: + for (i =3D 0; i < nchains; i++) + g_free(chains[i]); + + return ret; +} + +/** + * nftablesCreateRootTables + * + * @fw: the firewall instance + * + * Run nft list tables and parse if the table already exist + * skips creation of base table if possible + * see handler in nftablesHandleCreateRootTables + */ +static void nftablesCreateRootTables(virFirewall *fw) +{ + virFirewallAddCmdFull(fw, VIR_FIREWALL_LAYER_ETHERNET, + false, nftablesHandleCreateRootTables, + NULL, + "list", "tables", NULL); +} + +/** + * nftablesEnsureRootTablesExist + * + * Run nftablesCreateRootTables in a seperate transaction, + * Follow up commands like: + * - "nft list -a" commands in nftablesRemoveAllInterfaceChains + * - "add chain" commands in nftablesApplyBasicRules + * Can then run and be assured that the tables should exist. + */ +static int nftablesEnsureRootTablesExist(void) +{ + g_autoptr(virFirewall) fw =3D virFirewallNew(VIR_FIREWALL_BACKEND_NFTA= BLES); + virFirewallStartTransaction(fw, 0); + + /* remove interface chains and rules */ + nftablesCreateRootTables(fw); + + return virFirewallApply(fw); +} + +/** + * nftablesCreateChains + * + * @fw: the firewleset instance + * @cbdata: callback data struct which holds variables that + * the call back handler needs in order to create + * the base table and the dependant rules + * + * Run nft list table libvirt-nwfilter and parse if the chains already exi= st + * skips creation of chains if possible + * see handler in nftablesHandleCreateChains + */ +static void nftablesCreateChains(virFirewall *fw, + virNWFilterChainCreateCallbackData *cbdat= a) +{ + virFirewallAddCmdFull(fw, VIR_FIREWALL_LAYER_ETHERNET, + false, nftablesHandleCreateChains, + (void *)cbdata, + "list", "chains", NULL); +} + +static const char *breakStrAt(const char *str, char untilc) +{ + const char *untilPtr =3D strchr(str, untilc); + if (untilPtr) { + *(char *)untilPtr =3D '\0'; + } + + return str; +} + +static int +nftablesHandleRenameChains(virFirewall *fw, + virFirewallLayer layer, + const char *const *lines, + void *opaque) +{ + size_t i =3D 0; + const char *ifname =3D opaque; + const char *tableName =3D NULL; + const char *chain =3D NULL; + const char *newName =3D NULL; + char chainCompare[MAX_NF_CHAINNAME_LENGTH]; + g_snprintf(chainCompare, sizeof(chainCompare), "n-%s-", ifname); + + /* parse nft tables list output to see if chains exist */ + for (i =3D 0; lines[i] !=3D NULL; i++) { + const char *line =3D lines[i]; + + /* first we'll have to parse the table name */ + if (tableName =3D=3D NULL && STRPREFIX(line, "table bridge ")) { + line =3D STRSKIP(line, "table bridge "); + /* parse table that we want to clean */ + tableName =3D breakStrAt(line, ' '); + continue; + } + + virSkipSpaces(&line); + + if ((line =3D STRSKIP(line, "chain ")) =3D=3D NULL) { + continue; + } + chain =3D breakStrAt(line, ' '); + + if (STRPREFIX(chain, chainCompare) && STRPREFIX(chain, "n-")) { + /* new name is name without n- at the prefix */ + newName =3D chain + strlen("n-"); + VIR_DEBUG("Scheduling chain rename '%s'->'%s' on table '%s'", + chain, newName, tableName); + /* delete the chain */ + virFirewallAddCmd(fw, layer, + "rename", "chain", "bridge", + tableName, chain, newName, NULL); + } + } + + return 0; +} + +static void +nftablesRemoveVmapElementList(virFirewall *fw, + virFirewallLayer layer, + const char *line, + const char *tableName, + const char *vmapName, + const char *chainCompare) +{ + const char *vmapKey =3D NULL; + if (STRPREFIX(line, "elements =3D {")) + line =3D STRSKIP(line, "elements =3D {"); + + /* skip spaces up to vmap key */ + virSkipSpaces(&line); + + /* walk the elements */ + while (line && STRNEQ(line, "}") && STRNEQ(line, ",")) { + g_autofree char *vmap =3D g_strdup(line); + vmapKey =3D breakStrAt(vmap, ' '); + + /* skip past this vmap key */ + line =3D STRSKIP(line, vmapKey); + + /* skip " : jump" or ":jump" */ + virSkipSpaces(&line); + if ((line =3D STRSKIP(line, ":")) =3D=3D NULL) + break; + virSkipSpaces(&line); + if ((line =3D STRSKIP(line, "jump")) =3D=3D NULL) + break; + virSkipSpaces(&line); + + if (STRPREFIX(line, chainCompare)) { + VIR_DEBUG("Scheduling vmap element '%s' on '%s' for deletion", + vmapKey, vmapName); + virFirewallAddCmd(fw, layer, + "delete", "element", "bridge", tableName, + vmapName, "{", vmapKey, "}", NULL); + } + + if (strchr(line, ',') !=3D NULL) + line =3D strchr(line, ','); + if (strchr(line, ' ') !=3D NULL) + line =3D strchr(line, ' '); + + /* skip spaces up to next vmap key */ + virSkipSpaces(&line); + } +} + +static int +nftablesHandleRemoveAll(virFirewall *fw, + virFirewallLayer layer, + const char *const *lines, + void *opaque) +{ + size_t i =3D 0; + const char *ifname =3D opaque; + const char *tableName =3D NULL; + const char *chain =3D NULL; + const char *vmapName =3D NULL; + bool vmapParsing =3D false; + char chainCompare[MAX_NF_CHAINNAME_LENGTH]; + char fwCompare[MAX_NF_CHAINNAME_LENGTH]; + char tmpFwCompare[MAX_NF_CHAINNAME_LENGTH]; + g_snprintf(chainCompare, sizeof(chainCompare), "%s-", ifname); + g_snprintf(fwCompare, sizeof(fwCompare), "\"%s\" jump %s-", ifname, if= name); + /* match possible tmp jump on tmp name "\"vnet0\"" jump n-vnet0-" */ + g_snprintf(tmpFwCompare, sizeof(tmpFwCompare), "\"%s\" jump n-%s-", if= name, + ifname); + + /* parse nft tables list output to see if chains exist */ + for (i =3D 0; lines[i] !=3D NULL; i++) { + const char *line =3D lines[i]; + + /* first we'll have to parse the table name */ + if (tableName =3D=3D NULL && STRPREFIX(line, "table bridge ")) { + line =3D STRSKIP(line, "table bridge "); + /* parse table that we want to clean */ + tableName =3D breakStrAt(line, ' '); + continue; + } + + virSkipSpaces(&line); + + /* delete tmp jumps */ + if (strstr(line, fwCompare) !=3D NULL || + strstr(line, tmpFwCompare) !=3D NULL) { + line =3D strchr(line, '#'); + if ((line =3D STRSKIP(line, "# handle ")) =3D=3D NULL) + continue; + + /* delete tmp jump */ + virFirewallAddCmd(fw, layer, + "delete", "rule", "bridge", tableName, chain, + "handle", line, NULL); + + continue; + } + + /* parse current vmap name*/ + if (STRPREFIX(line, "map ") && + (line =3D STRSKIP(line, "map ")) !=3D NULL) { + vmapName =3D breakStrAt(line, ' '); + continue; + } + + /* if we come acros map elements, we enable element list parsing */ + if (STRPREFIX(line, "elements =3D {")) + vmapParsing =3D true; + + /* remove old map elements, if they exist */ + /* we are in process of parsing a vmap elements list */ + if (vmapParsing) { + /* reached end of list */ + if (strstr(line, "}") !=3D NULL) + vmapParsing =3D false; + + nftablesRemoveVmapElementList(fw, layer, line, tableName, + vmapName, chainCompare); + + continue; + } + + if ((line =3D STRSKIP(line, "chain ")) =3D=3D NULL) { + continue; + } + chain =3D breakStrAt(line, ' '); + + if (STRPREFIX(chain, chainCompare)) { + VIR_DEBUG("Scheduling chain '%s' on table '%s' for deletion", + chain, tableName); + /* delete the chain */ + virFirewallAddCmd(fw, layer, + "delete", "chain", "bridge", + tableName, chain, NULL); + } + } + + return 0; +} + +static void +nftablesRemoveAllInterfaceChains(virFirewall *fw, const char *ifname) +{ + virFirewallAddCmdFull(fw, VIR_FIREWALL_LAYER_ETHERNET, + false, nftablesHandleRemoveAll, + (void *)ifname, + "-a", "list", "table", "bridge", + NF_ETHERNET_TABLE, NULL); + + virFirewallAddCmdFull(fw, VIR_FIREWALL_LAYER_ETHERNET, + false, nftablesHandleRemoveAll, + (void *)ifname, + "-a", "list", "table", "bridge", + NF_INET_TABLE, NULL); +} + +static void +nftablesRenameAllInterfaceChains(virFirewall *fw, const char *ifname) +{ + virFirewallAddCmdFull(fw, VIR_FIREWALL_LAYER_ETHERNET, + false, nftablesHandleRenameChains, + (void *)ifname, + "-a", "list", "table", "bridge", + NF_ETHERNET_TABLE, NULL); + + virFirewallAddCmdFull(fw, VIR_FIREWALL_LAYER_ETHERNET, + false, nftablesHandleRenameChains, + (void *)ifname, + "-a", "list", "table", "bridge", + NF_INET_TABLE, NULL); +} + +static int +nftablesApplyNewRules(const char *ifname, + virNWFilterRuleInst **rules, + size_t nrules) +{ + size_t i; + g_autoptr(GHashTable) chains_in_set =3D virHashNew(NULL); + g_autoptr(GHashTable) chains_out_set =3D virHashNew(NULL); + g_autoptr(virFirewall) fw =3D virFirewallNew(VIR_FIREWALL_BACKEND_NFTA= BLES); + virNWFilterChainCreateCallbackData chainCallbackData =3D {ifname, nrul= es, rules}; + + /* nwfilter_nftables applies new rules first, then remove old rules + * in order to do this we: + * - place the new chains under a name prefixed with "n-" + * - create tmp jump that catches vmap switch moment, + * traffic will temporarily not be matched as an entry from the vmap= will + * be deleted and then recreated as you can't atomic update vmaps vi= a a + * single command + * - in the tearOldRules function, we also remove the tmp interface ju= mp to + * the new chains + * - in tearOldRules we remove the old chains + * - in tearOldRules we rename the "n-" chains by removing "n-" from t= he + * chain name + * + * This allows us in a rollback scenario to simply remove the new chai= ns + * and jumps + */ + char tmpIfname[VIR_INT64_STR_BUFLEN]; + g_snprintf(tmpIfname, sizeof(tmpIfname), "n-%s", ifname); + + /* walk the list of rules and increase the priority + * of rules in case the chain priority is of higher value; + * this preserves the order of the rules and ensures that + * the chain will be created before the chain's rules + * are created; don't adjust rules in the root chain + * example: a rule of priority -510 will be adjusted to + * priority -500 and the chain with priority -500 will + * then be created before it. + */ + for (i =3D 0; i < nrules; i++) { + if (rules[i]->chainPriority > rules[i]->priority && + !strstr("root", rules[i]->chainSuffix)) { + + rules[i]->priority =3D rules[i]->chainPriority; + } + } + + /* sort rules */ + if (nrules) { + g_qsort_with_data(rules, nrules, sizeof(rules[0]), + virNWFilterRuleInstSortPtr, NULL); + } + + virFirewallStartTransaction(fw, 0); + + /* create root tables if they don't exist already */ + nftablesCreateRootTables(fw); + /* create user chains and rules */ + nftablesCreateChains(fw, &chainCallbackData); + + /* rollback commands, if necessary */ + virFirewallStartRollback(fw, 0); + nftablesRemoveAllInterfaceChains(fw, tmpIfname); + + /* process rules and apply them */ + return virFirewallApply(fw); +} + +static int +nftablesTeardownNewRules(const char *ifname) +{ + char matchIfname[VIR_INT64_STR_BUFLEN]; + g_autoptr(virFirewall) fw =3D virFirewallNew(VIR_FIREWALL_BACKEND_NFTA= BLES); + + g_snprintf(matchIfname, sizeof(matchIfname), "n-%s", ifname); + + virFirewallStartTransaction(fw, 0); + + /* remove tmp interface chains and rules */ + nftablesRemoveAllInterfaceChains(fw, matchIfname); + + return virFirewallApply(fw); +} + +static int +nftablesTeardownOldRules(const char *ifname) +{ + g_autoptr(virFirewall) fw =3D virFirewallNew(VIR_FIREWALL_BACKEND_NFTA= BLES); + virFirewallStartTransaction(fw, 0); + + /* remove old interface chains and rules */ + nftablesRemoveAllInterfaceChains(fw, ifname); + + /* rename new temp interface chains and rules */ + nftablesRenameAllInterfaceChains(fw, ifname); + + return virFirewallApply(fw); +} + +/** + * nftablesAllTeardown: + * @ifname : the name of the interface to which the rules apply + * + * Unconditionally remove all possible user defined tables and rules + * that were created for the given interface (ifname). + * + * Returns 0 on success, -1 on OOM + */ +static int +nftablesAllTeardown(const char *ifname) +{ + g_autoptr(virFirewall) fw =3D virFirewallNew(VIR_FIREWALL_BACKEND_NFTA= BLES); + virFirewallStartTransaction(fw, 0); + + /* remove interface chains and rules */ + nftablesRemoveAllInterfaceChains(fw, ifname); + + return virFirewallApply(fw); +} + +/** + * nftablesCanApplyBasicRules + * + * Determine whether this driver can apply the basic rules, meaning + * run nftablesApplyBasicRules and nftablesApplyDHCPOnlyRules. + * In case of this driver we need the nft tool available. + */ +static bool nftablesCanApplyBasicRules(void) +{ + return true; +} + +/** + * nftablesApplyBasicRules + * + * @ifname: name of the backend-interface to which to apply the rules + * @macaddr: MAC address the VM is using in packets sent through the + * interface + * + * Returns 0 on success, -1 on failure with the rules removed + * + * Apply basic filtering rules on the given interface + * - filtering for MAC address spoofing + * - allowing IPv4 & ARP traffic + */ +static int +nftablesApplyBasicRules(const char *ifname, + const virMacAddr *macaddr) +{ + g_autoptr(virFirewall) fw =3D virFirewallNew(VIR_FIREWALL_BACKEND_NFTA= BLES); + char macaddr_str[VIR_MAC_STRING_BUFLEN]; + char rootChainIn[MAX_NF_CHAINNAME_LENGTH]; + char rootChainOut[MAX_NF_CHAINNAME_LENGTH]; + + virMacAddrFormat(macaddr, macaddr_str); + + if (nftablesEnsureRootTablesExist() < 0) + return -1; + + if (nftablesAllTeardown(ifname) < 0) + return -1; + + virFirewallStartTransaction(fw, 0); + + /* create root chain */ + g_snprintf(rootChainIn, sizeof(rootChainIn), "%s-in", ifname); + g_snprintf(rootChainOut, sizeof(rootChainOut), "%s-out", ifname); + nftablesCreateRootChain(fw, VIR_FIREWALL_LAYER_ETHERNET, rootChainIn); + nftablesCreateRootChain(fw, VIR_FIREWALL_LAYER_ETHERNET, rootChainOut); + + + /* apply rules to root chain */ + virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_ETHERNET, "add", "rule", "bri= dge", + NF_ETHERNET_TABLE, rootChainOut, "ether", "saddr", + "!=3D", macaddr_str, "drop", NULL); + virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_ETHERNET, "add", "rule", "bri= dge", + NF_ETHERNET_TABLE, rootChainOut, "ether", "type", "i= p", + "accept", NULL); + virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_ETHERNET, "add", "rule", "bri= dge", + NF_ETHERNET_TABLE, rootChainOut, "ether", "type", "a= rp", + "accept", NULL); + virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_ETHERNET, "add", "rule", "bri= dge", + NF_ETHERNET_TABLE, rootChainOut, "accept", NULL); + + nftablesCreateRootChainJump(fw, VIR_FIREWALL_LAYER_ETHERNET, ifname, + IN_IFMATCH, IN_CHAIN, rootChainIn, false); + nftablesCreateRootChainJump(fw, VIR_FIREWALL_LAYER_ETHERNET, ifname, + OUT_IFMATCH, OUT_CHAIN, rootChainOut, fals= e); + + if (virFirewallApply(fw) < 0) { + nftablesAllTeardown(ifname); + return -1; + } + + return 0; +} + +/** + * nftablesApplyDHCPOnlyRules + * + * @ifname: name of the backend-interface to which to apply the rules + * @macaddr: MAC address the VM is using in packets sent through the + * interface + * @dhcpsrvrs: The DHCP server(s) from which the VM may receive traffic + * from; may be NULL + * @leaveTemporary: Whether to leave the table names with their temporary + * names (true) or also perform the renaming to their final names as + * part of this call (false) + * + * Returns 0 on success, -1 on failure with the rules removed + * + * Apply filtering rules so that the VM can only send and receive + * DHCP traffic and nothing else. + */ +static int +nftablesApplyDHCPOnlyRules(const char *ifname, + const virMacAddr *macaddr, + virNWFilterVarValue *dhcpsrvrs, + bool leaveTemporary G_GNUC_UNUSED) +{ + char rootChainIn [MAX_NF_CHAINNAME_LENGTH], + rootChainOut[MAX_NF_CHAINNAME_LENGTH]; + char macaddr_str[VIR_MAC_STRING_BUFLEN]; + unsigned int idx =3D 0; + unsigned int num_dhcpsrvrs; + g_autoptr(virFirewall) fw =3D virFirewallNew(VIR_FIREWALL_BACKEND_NFTA= BLES); + + virMacAddrFormat(macaddr, macaddr_str); + + if (nftablesEnsureRootTablesExist() < 0) + return -1; + + if (nftablesAllTeardown(ifname) < 0) + return -1; + + virFirewallStartTransaction(fw, 0); + + /* create root chain */ + g_snprintf(rootChainIn, sizeof(rootChainIn), "%s-in", ifname); + g_snprintf(rootChainOut, sizeof(rootChainOut), "%s-out", ifname); + nftablesCreateRootChain(fw, VIR_FIREWALL_LAYER_ETHERNET, rootChainIn); + nftablesCreateRootChain(fw, VIR_FIREWALL_LAYER_ETHERNET, rootChainOut); + + virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_ETHERNET, "add", "rule", "bri= dge", + NF_ETHERNET_TABLE, rootChainOut, "ether", "saddr", + macaddr_str, "ether", "type", "ip", + "udp", "sport", "68", "udp", "dport", "67", "accept", NU= LL); + + virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_ETHERNET, "add", "rule", "bri= dge", + NF_ETHERNET_TABLE, rootChainOut, "drop", NULL); + + num_dhcpsrvrs =3D (dhcpsrvrs !=3D NULL) + ? virNWFilterVarValueGetCardinality(dhcpsrvrs) + : 0; + + while (true) { + const char *dhcpserver =3D NULL; + int ctr; + + if (idx < num_dhcpsrvrs) + dhcpserver =3D virNWFilterVarValueGetNthValue(dhcpsrvrs, idx); + + /* + * create two rules allowing response to MAC address of VM + * or to broadcast MAC address + */ + for (ctr =3D 0; ctr < 2; ctr++) { + if (dhcpserver) + virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_ETHERNET, + "add", "rule", "bridge", + NF_ETHERNET_TABLE, rootChainIn, "ether", + "daddr", + (ctr =3D=3D 0) ? macaddr_str : "ff:ff:ff= :ff:ff:ff", + "ether", "type", "ip", + "ip", "saddr", dhcpserver, + "udp", "sport", "67", + "udp", "dport", "68", "accept", NULL); + else + virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_ETHERNET, + "add", "rule", "bridge", + NF_ETHERNET_TABLE, rootChainIn, "ether", + "daddr", + (ctr =3D=3D 0) ? macaddr_str : "ff:ff:ff= :ff:ff:ff", + "ether", "type", "ip", + "udp", "sport", "67", + "udp", "dport", "68", "accept", NULL); + } + + idx++; + + if (idx >=3D num_dhcpsrvrs) + break; + } + + virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_ETHERNET, "add", "rule", "bri= dge", + NF_ETHERNET_TABLE, rootChainIn, "drop", NULL); + + nftablesCreateRootChainJump(fw, VIR_FIREWALL_LAYER_ETHERNET, ifname, + IN_IFMATCH, IN_CHAIN, rootChainIn, false); + nftablesCreateRootChainJump(fw, VIR_FIREWALL_LAYER_ETHERNET, ifname, + OUT_IFMATCH, OUT_CHAIN, rootChainOut, fals= e); + + if (virFirewallApply(fw) < 0) { + nftablesAllTeardown(ifname); + return -1; + } + + return 0; +} + +static int +nftablesRemoveBasicRules(const char *ifname) +{ + return nftablesAllTeardown(ifname); +} + +/** + * nftablesApplyDropAllRules + * + * @ifname: name of the backend-interface to which to apply the rules + * + * Returns 0 on success, -1 on failure with the rules removed + * + * Apply filtering rules so that the VM cannot receive or send traffic. + */ +static int +nftablesDropAllRules(const char *ifname) +{ + char rootChainIn [MAX_NF_CHAINNAME_LENGTH], + rootChainOut[MAX_NF_CHAINNAME_LENGTH]; + g_autoptr(virFirewall) fw =3D virFirewallNew(VIR_FIREWALL_BACKEND_NFTA= BLES); + + if (nftablesEnsureRootTablesExist() < 0) + return -1; + if (nftablesAllTeardown(ifname) < 0) + return -1; + + virFirewallStartTransaction(fw, 0); + + /* create root chain */ + g_snprintf(rootChainIn, sizeof(rootChainIn), "%s-in", ifname); + g_snprintf(rootChainOut, sizeof(rootChainOut), "%s-out", ifname); + nftablesCreateRootChain(fw, VIR_FIREWALL_LAYER_ETHERNET, rootChainIn); + nftablesCreateRootChain(fw, VIR_FIREWALL_LAYER_ETHERNET, rootChainOut); + + virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_ETHERNET, "add", "rule", "bri= dge", + NF_ETHERNET_TABLE, rootChainOut, "drop", NULL); + virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_ETHERNET, "add", "rule", "bri= dge", + NF_ETHERNET_TABLE, rootChainIn, "drop", NULL); + + /* tmp iif oif jump */ + virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_ETHERNET, "add", "rule", "bri= dge", + NF_ETHERNET_TABLE, IN_CHAIN, IN_IFNAMEMATCH, ifname, + "jump", rootChainIn, NULL); + virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_ETHERNET, "add", "rule", "bri= dge", + NF_ETHERNET_TABLE, OUT_CHAIN, OUT_IFNAMEMATCH, ifnam= e, + "jump", rootChainOut, NULL); + + if (virFirewallApply(fw) < 0) { + nftablesAllTeardown(ifname); + return -1; + } + + return 0; +} + +static int +nftablesDriverInit(bool privileged) +{ + if (!privileged) + return 0; + + nftables_driver.flags =3D TECHDRV_FLAG_INITIALIZED; + + return 0; +} + +static void +nftablesDriverShutdown(void) +{ + nftables_driver.flags =3D 0; +} + +virNWFilterTechDriver nftables_driver =3D { + .name =3D NFTABLES_DRIVER_ID, + .flags =3D 0, + + .init =3D nftablesDriverInit, + .shutdown =3D nftablesDriverShutdown, + + .applyNewRules =3D nftablesApplyNewRules, + .tearNewRules =3D nftablesTeardownNewRules, + .tearOldRules =3D nftablesTeardownOldRules, + .allTeardown =3D nftablesAllTeardown, + + .canApplyBasicRules =3D nftablesCanApplyBasicRules, + .applyBasicRules =3D nftablesApplyBasicRules, + .applyDHCPOnlyRules =3D nftablesApplyDHCPOnlyRules, + .applyDropAllRules =3D nftablesDropAllRules, + .removeBasicRules =3D nftablesRemoveBasicRules, +}; diff --git a/src/nwfilter/nwfilter_nftables_driver.h b/src/nwfilter/nwfilte= r_nftables_driver.h new file mode 100644 index 0000000000..a767413208 --- /dev/null +++ b/src/nwfilter/nwfilter_nftables_driver.h @@ -0,0 +1,28 @@ +/* + * nwfilter_nftables_driver.h: nftables driver support + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#pragma once + +#include "nwfilter_tech_driver.h" + +extern virNWFilterTechDriver nftables_driver; + +#define NFTABLES_DRIVER_ID "nftables" + +/* see source/include/uapi/linux/netfilter/nf_tables.h */ +#define MAX_NF_CHAINNAME_LENGTH 256 --=20 2.43.0 From nobody Sat May 30 15:29:22 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) client-ip=38.145.34.151; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1779123560; cv=none; d=zohomail.com; s=zohoarc; b=c3yjNR6+l7hYCCtizA6zniIc96WA3nFGtvlDdsMAuDgiDJr8D/RUNzDpqEHA9iRl055j7O4WkTPGgWbK8J9aj5rCxdDm/NmL52u1v6oipBMCJ9xPwSaq3M6dT4uj5uOMSZtdfULxlEXNWAqlZL3PozTvtnM3TRiULiXpMTTuOAg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1779123560; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=FmqDUgb2q2w60WFX2TAHq/uhLi458wkToMxH3bh2krY=; b=Oi/r3PuTX7+m02AJ4r/L4H4rCczJlfJcEIa7djMPTuxwrvTNxsrcrk+ANHBIY5G8XWkurkAhNZeMm4M4yRBgrszl/9ZeJ4zGKfBT51v9NPxTMTfd6Dj/DTyfO2Am4hKA9lGAxfM5jNHYxCn4CHB/4jWcGjetxqp2HSG9fntcuTw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [38.145.34.151]) by mx.zohomail.com with SMTPS id 1779123560318543.7788478276386; Mon, 18 May 2026 09:59:20 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 4973241920; Mon, 18 May 2026 12:59:19 -0400 (EDT) Received: from [172.19.199.5] (unknown [10.16.107.18]) by lists.libvirt.org (Postfix) with ESMTP id 494C94198A; Mon, 18 May 2026 12:52:35 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 9BA18418EE; Mon, 18 May 2026 12:52:24 -0400 (EDT) Received: from mx11.osci.io (polly.osci.io [IPv6:2620:52:6:3141:1::41]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 4FAD545719 for ; Mon, 18 May 2026 12:03:51 -0400 (EDT) Received: by mx11.osci.io (Postfix, from userid 994) id 8D12E68573; Mon, 18 May 2026 08:31:56 -0400 (EDT) Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by mx11.osci.io (Postfix) with ESMTPS id 006BD6858F for ; Mon, 18 May 2026 08:31:54 -0400 (EDT) Received: by mail-ed1-x52b.google.com with SMTP id 4fb4d7f45d1cf-67fd8befac7so5573031a12.2 for ; Mon, 18 May 2026 05:31:54 -0700 (PDT) Received: from thinkiepadje.home (2a02-a470-a384-0-b529-3d3d-353-106e.fixed6.kpn.net. [2a02:a470:a384:0:b529:3d3d:353:106e]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bd4f4e4d54dsm553354066b.47.2026.05.18.05.29.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 May 2026 05:29:53 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779107394; x=1779712194; darn=lists.libvirt.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=FmqDUgb2q2w60WFX2TAHq/uhLi458wkToMxH3bh2krY=; b=nGmzZgFkQjd8bgdeRlxErmXOAAdEkfch4qJWQEhNYD6aLZoa4HNTapQF2Mdu3drLjO +lTRE0VUPf2EdSoH/gc4y0u13fakZ6e0B0FXVQyre9AdYIPRqdXQFgz9Bd/jxX2Jd3w3 HbaZJejL0Vf4G9hPah0ZEdy7SY38F74Pcy8L4n9HVGrQQP0P6P6f5VGlkhMj74AQy2dR rtTmim/XqJClSuEybFwPrickdsEwzr6XL1X/scaazZu7nPkS/4zA2ZVzYSqAz1d9x/28 9hwM9PXzJNXPkFAjP3K7oKBk+CpEmg5XCDdMkA7vVVXniqGo2GaPkv8koOfh793B4k/I adUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779107394; x=1779712194; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=FmqDUgb2q2w60WFX2TAHq/uhLi458wkToMxH3bh2krY=; b=NAL/HpvRJFA1Q3zz47ujX2eOQHCFAEX5ADG3AQ9MHGY1K/lBq3lmWGuMg8coq5C/7J R6REk4EnOhioRrQLBZJ3I34n9aZbR3aakXM3bvmGJhMc5K6AZE5Tjo8Czyjd7JSKnqJF 9cWddOdf2biKs6ureN6IGWwHkFArSjbIX7lEC7JXnRzlX7fbZucD6aGSUO6ZILEjG32D d9mZ7g5wfKM+7Ev0RKTctYgSgPbyMuSlR35EXm2lBTgjCBqKnCb1LuXHG83AFMFtA0Oh EP8pteMO1UOrdLYQU0ZdYJmtis/u5da/UojT/6+oQWjnDvEfwQgqZY9y7hxdWXMm5VoQ XUVA== X-Gm-Message-State: AOJu0YwvDNQ3xrgQpW4wX6Or62Uzhv6tpTOQmTQRzqKPAyPPn83AihdP uS7nePRNyXNBY7Aqypzp7XVnvpeXa4ef1JylR5aMTB/Z20jPGTea5fvOc6v7 X-Gm-Gg: Acq92OF4dKIYbCDLtDYP7VOkr3QEwIzasRgS38PHSPjyS08Jvm2VMPrkRl+UcJzGheP ZELnwZpO2vE6FZPN9bWHfZNrzBUv89gglPuK9EaHF4AR35aiEPcS1ICOUcI0PtdM+iP9URqT/kS A0SO9ldNpk1mC62mZG3wI2g5QNuy+AiZ+rm80paz8QOwOBdxwF6Wlp1PZGlj6Nynt6/R/gV5rwt +w9QT0flczkOIGD1vwYzsv6DUS6jnnw+4s7t9gFlD1y/cAP2lsR1nIUzpjkEW6uwtC+05Y9AEzC emR00O+yuAsrciuMlxX8rWaGFMEBFpo8eYxjJfQHjUcIgbFAw6Ckre2hwlJ6rlcCTZnnU/kGxbF oapvWrtvPJzDNZ7rXlgH25q0bNqaW8Wu96wyaCMJcNR9w1mOH5ejVSNMCTRkJu1mmOtCEqdgAPG D43XgBaHQdEksCWd4I03molC+48kZq3MGJkRB3C6eQGwOUZIWJ62NHzom8heZCKzh+FqD1OoSbg fP+COpEY27BDWw85dyhmJs= X-Received: by 2002:a17:907:9286:b0:bd8:bd2b:abbb with SMTP id a640c23a62f3a-bd8bd2bac1dmr92607966b.10.1779107393598; Mon, 18 May 2026 05:29:53 -0700 (PDT) From: Dion Bosschieter To: devel@lists.libvirt.org Subject: [PATCH v7 2/4] nwfilter: allow use of nftables nwfilter driver via nwfilter.conf Date: Mon, 18 May 2026 14:25:44 +0200 Message-ID: <20260518122547.163157-3-dionbosschieter@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260518122547.163157-1-dionbosschieter@gmail.com> References: <20260518122547.163157-1-dionbosschieter@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: 2UAM74Q3BPFHIKGFTGWGCFL3WCJSJB4V X-Message-ID-Hash: 2UAM74Q3BPFHIKGFTGWGCFL3WCJSJB4V X-MailFrom: SRS0=UfGQ=DP=gmail.com=dionbosschieter@osci.io X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: jean-louis@dupond.be, Dion Bosschieter X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1779123562185154100 Content-Type: text/plain; charset="utf-8" Change the nwfilter driver loading mechanism to read from nwfilter.conf. By default, it will use the nftables driver, which follows the firewall_backend bridge driver config logic. Added extra nwfilter config options "enable_trace" and "enable_counters" to allow users to toggle nftable driver specific features. Added nftables to *filter_tech_drivers as an available driver option for users to choose from. Signed-off-by: Dion Bosschieter --- libvirt.spec.in | 7 + po/POTFILES | 1 + src/conf/virnwfilterobj.h | 20 -- src/nwfilter/libvirtd_nwfilter.aug | 45 +++++ src/nwfilter/meson.build | 37 ++++ src/nwfilter/nwfilter.conf.in | 50 +++++ src/nwfilter/nwfilter_driver.c | 66 +++---- src/nwfilter/nwfilter_driver_conf.c | 214 +++++++++++++++++++++ src/nwfilter/nwfilter_driver_conf.h | 69 +++++++ src/nwfilter/nwfilter_ebiptables_driver.c | 4 +- src/nwfilter/nwfilter_ebiptables_driver.h | 2 +- src/nwfilter/nwfilter_gentech_driver.c | 65 +++---- src/nwfilter/nwfilter_gentech_driver.h | 5 +- src/nwfilter/nwfilter_nftables_driver.c | 35 ++-- src/nwfilter/nwfilter_tech_driver.h | 3 +- src/nwfilter/test_libvirtd_nwfilter.aug.in | 7 + 16 files changed, 511 insertions(+), 119 deletions(-) create mode 100644 src/nwfilter/libvirtd_nwfilter.aug create mode 100644 src/nwfilter/nwfilter.conf.in create mode 100644 src/nwfilter/nwfilter_driver_conf.c create mode 100644 src/nwfilter/nwfilter_driver_conf.h create mode 100644 src/nwfilter/test_libvirtd_nwfilter.aug.in diff --git a/libvirt.spec.in b/libvirt.spec.in index 2fddfcd606..5373f80869 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -617,8 +617,12 @@ bridge capabilities. Summary: Nwfilter driver plugin for the libvirtd daemon Requires: libvirt-daemon-common =3D %{version}-%{release} Requires: libvirt-libs =3D %{version}-%{release} + %if %{prefer_nftables} +Requires: nftables + %else Requires: iptables Requires: ebtables + %endif =20 %description daemon-driver-nwfilter The nwfilter driver plugin for the libvirtd daemon, providing @@ -2235,6 +2239,9 @@ exit 0 %config(noreplace) %{_sysconfdir}/libvirt/virtnwfilterd.conf %{_datadir}/augeas/lenses/virtnwfilterd.aug %{_datadir}/augeas/lenses/tests/test_virtnwfilterd.aug +%config(noreplace) %{_sysconfdir}/libvirt/nwfilter.conf +%{_datadir}/augeas/lenses/libvirtd_nwfilter.aug +%{_datadir}/augeas/lenses/tests/test_libvirtd_nwfilter.aug %{_unitdir}/virtnwfilterd.service %{_unitdir}/virtnwfilterd.socket %{_unitdir}/virtnwfilterd-ro.socket diff --git a/po/POTFILES b/po/POTFILES index a404b7a012..e800410850 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -160,6 +160,7 @@ src/node_device/node_device_driver.c src/node_device/node_device_udev.c src/nwfilter/nwfilter_dhcpsnoop.c src/nwfilter/nwfilter_driver.c +src/nwfilter/nwfilter_driver_conf.c src/nwfilter/nwfilter_ebiptables_driver.c src/nwfilter/nwfilter_gentech_driver.c src/nwfilter/nwfilter_learnipaddr.c diff --git a/src/conf/virnwfilterobj.h b/src/conf/virnwfilterobj.h index b67dc017c5..2c5df3e9ac 100644 --- a/src/conf/virnwfilterobj.h +++ b/src/conf/virnwfilterobj.h @@ -28,26 +28,6 @@ typedef struct _virNWFilterObj virNWFilterObj; =20 typedef struct _virNWFilterObjList virNWFilterObjList; =20 -typedef struct _virNWFilterDriverState virNWFilterDriverState; -struct _virNWFilterDriverState { - bool privileged; - - /* pid file FD, ensures two copies of the driver can't use the same ro= ot */ - int lockFD; - - virNWFilterObjList *nwfilters; - - virNWFilterBindingObjList *bindings; - - char *stateDir; - char *configDir; - char *bindingDir; - - /* Recursive. Hold for filter changes, instantiation or deletion */ - virMutex updateLock; - bool updateLockInitialized; -}; - virNWFilterDef * virNWFilterObjGetDef(virNWFilterObj *obj); =20 diff --git a/src/nwfilter/libvirtd_nwfilter.aug b/src/nwfilter/libvirtd_nwf= ilter.aug new file mode 100644 index 0000000000..2a8475b680 --- /dev/null +++ b/src/nwfilter/libvirtd_nwfilter.aug @@ -0,0 +1,45 @@ +(* /etc/libvirt/nwfilter.conf *) + +module Libvirtd_nwfilter =3D + autoload xfm + + let eol =3D del /[ \t]*\n/ "\n" + let value_sep =3D del /[ \t]*=3D[ \t]*/ " =3D " + let indent =3D del /[ \t]*/ "" + + let array_sep =3D del /,[ \t\n]*/ ", " + let array_start =3D del /\[[ \t\n]*/ "[ " + let array_end =3D del /\]/ "]" + + let str_val =3D del /\"/ "\"" . store /[^\"]*/ . del /\"/ "\"" + let bool_val =3D store /0|1/ + let int_val =3D store /[0-9]+/ + let str_array_element =3D [ seq "el" . str_val ] . del /[ \t\n]*/ "" + let str_array_val =3D counter "el" . array_start . ( str_array_element = . ( array_sep . str_array_element ) * ) ? . array_end + + let str_entry (kw:string) =3D [ key kw . value_sep . str_val ] + let bool_entry (kw:string) =3D [ key kw . value_sep . bool_val ] + let int_entry (kw:string) =3D [ key kw . value_sep . int_val ] + let str_array_entry (kw:string) =3D [ key kw . value_sep . str_array_va= l ] + + (* Config entries *) + let firewall_backend_entry =3D str_entry "firewall_backend" + let trace_entry =3D bool_entry "enable_trace" + let counters_entry =3D bool_entry "enable_counters" + + (* Each entry in the config is one of the following ... *) + let entry =3D firewall_backend_entry + | trace_entry + | counters_entry + + let comment =3D [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \= t\n][^\n]*)?/ . del /\n/ "\n" ] + let empty =3D [ label "#empty" . eol ] + + let record =3D indent . entry . eol + + let lns =3D ( record | comment | empty ) * + + let filter =3D incl "/etc/libvirt/nwfilter.conf" + . Util.stdexcl + + let xfm =3D transform lns filter diff --git a/src/nwfilter/meson.build b/src/nwfilter/meson.build index a94d72d570..4d8abc7deb 100644 --- a/src/nwfilter/meson.build +++ b/src/nwfilter/meson.build @@ -1,5 +1,6 @@ nwfilter_driver_sources =3D [ 'nwfilter_driver.c', + 'nwfilter_driver_conf.c', 'nwfilter_gentech_driver.c', 'nwfilter_tech_driver.c', 'nwfilter_dhcpsnoop.c', @@ -46,6 +47,42 @@ if conf.has('WITH_NWFILTER') ], } =20 + nwfilter_options_conf =3D configuration_data({ + 'FIREWALL_BACKEND_PRIORITY': ', '.join(firewall_backend_priority), + 'FIREWALL_BACKEND': firewall_backend_priority[0], + }) + + nwfilter_conf =3D configure_file( + input: 'nwfilter.conf.in', + output: 'nwfilter.conf', + configuration: nwfilter_options_conf, + ) + + nwfilter_options_hack_conf =3D configuration_data({ + 'FIREWALL_BACKEND_PRIORITY': ', '.join(firewall_backend_priority), + 'FIREWALL_BACKEND': firewall_backend_priority[0], + # This hack is necessary because the output file is going to be + # used as input for another configure_file() call later, which + # will take care of substituting @CONFIG@ with useful data + 'CONFIG': '@CONFIG@', + }) + test_libvirtd_network_aug_tmp =3D configure_file( + input: 'test_libvirtd_nwfilter.aug.in', + output: 'test_libvirtd_nwfilter.aug.tmp', + configuration: nwfilter_options_hack_conf, + ) + + virt_conf_files +=3D nwfilter_conf + virt_aug_files +=3D files('libvirtd_nwfilter.aug') + virt_test_aug_files +=3D { + 'name': 'test_libvirtd_nwfilter.aug', + 'aug': test_libvirtd_network_aug_tmp, + 'conf': nwfilter_conf, + 'test_name': 'libvirtd_nwfilter', + 'test_srcdir': meson.current_source_dir(), + 'test_builddir': meson.current_build_dir(), + } + virt_daemon_confs +=3D { 'name': 'virtnwfilterd', } diff --git a/src/nwfilter/nwfilter.conf.in b/src/nwfilter/nwfilter.conf.in new file mode 100644 index 0000000000..f535a34dae --- /dev/null +++ b/src/nwfilter/nwfilter.conf.in @@ -0,0 +1,50 @@ +# Master configuration file for the nwfilter driver. +# All settings described here are optional - if omitted, sensible +# defaults are used. + +# firewall_backend: +# +# determines which driver to use to setup nwfilter firewall rules +# +# Supported settings: +# +# iptables - use ebtables and iptables commands to construct the user +# defined firewall +# nftables - use nft commands to construct the user defined firewall +# +# If firewall_backend isn't configured, libvirt will choose the +# first available backend from the following list: +# +# [@FIREWALL_BACKEND_PRIORITY@] +# +# (NB: switching from one backend to another while libvirtd/virtnwfilterd +# has started *isn't* supported. The change will take place the +# next time that libvirtd/virtnwfilterd is restarted - all existing crea= ted +# firewall rules remain and have to be cleaned up manually.) +# +#firewall_backend =3D "@FIREWALL_BACKEND@" + +# enable_trace: +# +# Enables packet tracing for debugging firewall rules +# +# Supported backends: +# +# nftables - Creates nftables tables root chains with "meta nftrace se= t 1;" setting +# +# Possible values are 0 or 1. Default value is 0. +# +#enable_trace =3D 0 + +# enable_counters: +# +# Enables adding a counter to each rule, helpfull for counting +# how many tracking packets traversed each rule +# +# Supported backends: +# +# nftables - Adds the "counter" argument to nft rules nwfilter creates +# +# Possible values are 0 or 1. Default value is 0. +# +#enable_counters =3D 0 diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c index 522cfda022..66f5fa7c18 100644 --- a/src/nwfilter/nwfilter_driver.c +++ b/src/nwfilter/nwfilter_driver.c @@ -26,17 +26,15 @@ =20 #include "virgdbus.h" #include "virlog.h" - #include "internal.h" - #include "virerror.h" #include "datatypes.h" #include "nwfilter_driver.h" +#include "nwfilter_driver_conf.h" #include "nwfilter_gentech_driver.h" #include "configmake.h" #include "virpidfile.h" #include "viraccessapicheck.h" - #include "nwfilter_ipaddrmap.h" #include "nwfilter_dhcpsnoop.h" #include "nwfilter_learnipaddr.h" @@ -159,9 +157,12 @@ virNWFilterTriggerRebuildImpl(void *opaque) static int nwfilterStateCleanupLocked(void) { + g_autoptr(virNWFilterDriverConfig) cfg =3D NULL; if (!driver) return -1; =20 + cfg =3D virNWFilterDriverGetConfig(driver); + if (driver->privileged) { virNWFilterConfLayerShutdown(); virNWFilterDHCPSnoopShutdown(); @@ -171,11 +172,7 @@ nwfilterStateCleanupLocked(void) nwfilterDriverRemoveDBusMatches(); =20 if (driver->lockFD !=3D -1) - virPidFileRelease(driver->stateDir, "driver", driver->lockFD); - - g_free(driver->stateDir); - g_free(driver->configDir); - g_free(driver->bindingDir); + virPidFileRelease(cfg->stateDir, "driver", driver->lockFD); } =20 virObjectUnref(driver->bindings); @@ -216,6 +213,7 @@ nwfilterStateInitialize(bool privileged, void *opaque G_GNUC_UNUSED) { VIR_LOCK_GUARD lock =3D virLockGuardLock(&driverMutex); + virNWFilterDriverConfig *cfg; GDBusConnection *sysbus =3D NULL; =20 if (root !=3D NULL) { @@ -236,6 +234,9 @@ nwfilterStateInitialize(bool privileged, driver->updateLockInitialized =3D true; driver->privileged =3D privileged; =20 + if (!(driver->config =3D cfg =3D virNWFilterDriverConfigNew(privileged= ))) + goto error; + if (!(driver->nwfilters =3D virNWFilterObjListNew())) goto error; =20 @@ -245,16 +246,8 @@ nwfilterStateInitialize(bool privileged, if (!privileged) return VIR_DRV_STATE_INIT_SKIPPED; =20 - driver->stateDir =3D g_strdup(RUNSTATEDIR "/libvirt/nwfilter"); - - if (g_mkdir_with_parents(driver->stateDir, S_IRWXU) < 0) { - virReportSystemError(errno, _("cannot create state directory '%1$s= '"), - driver->stateDir); - goto error; - } - if ((driver->lockFD =3D - virPidFileAcquire(driver->stateDir, "driver", getpid())) < 0) + virPidFileAcquire(cfg->stateDir, "driver", getpid())) < 0) goto error; =20 if (virNWFilterIPAddrMapInit() < 0) @@ -266,7 +259,7 @@ nwfilterStateInitialize(bool privileged, if (virNWFilterDHCPSnoopInit() < 0) goto error; =20 - if (virNWFilterTechDriversInit(privileged) < 0) + if (virNWFilterTechDriversInit(privileged, cfg) < 0) goto error; =20 if (virNWFilterConfLayerInit(virNWFilterTriggerRebuildImpl, driver) < = 0) @@ -279,26 +272,10 @@ nwfilterStateInitialize(bool privileged, if (sysbus) nwfilterDriverInstallDBusMatches(sysbus); =20 - driver->configDir =3D g_strdup(SYSCONFDIR "/libvirt/nwfilter"); - - if (g_mkdir_with_parents(driver->configDir, S_IRWXU) < 0) { - virReportSystemError(errno, _("cannot create config directory '%1$= s'"), - driver->configDir); - goto error; - } - - driver->bindingDir =3D g_strdup(RUNSTATEDIR "/libvirt/nwfilter-binding= "); - - if (g_mkdir_with_parents(driver->bindingDir, S_IRWXU) < 0) { - virReportSystemError(errno, _("cannot create config directory '%1$= s'"), - driver->bindingDir); + if (virNWFilterObjListLoadAllConfigs(driver->nwfilters, cfg->configDir= ) < 0) goto error; - } =20 - if (virNWFilterObjListLoadAllConfigs(driver->nwfilters, driver->config= Dir) < 0) - goto error; - - if (virNWFilterBindingObjListLoadAllConfigs(driver->bindings, driver->= bindingDir) < 0) + if (virNWFilterBindingObjListLoadAllConfigs(driver->bindings, cfg->bin= dingDir) < 0) goto error; =20 if (virNWFilterBuildAll(driver, false) < 0) @@ -320,19 +297,22 @@ nwfilterStateInitialize(bool privileged, static int nwfilterStateReload(void) { + g_autoptr(virNWFilterDriverConfig) cfg =3D NULL; if (!driver) return -1; =20 if (!driver->privileged) return 0; =20 + cfg =3D virNWFilterDriverGetConfig(driver); + virNWFilterDHCPSnoopEnd(NULL); /* shut down all threads -- they will be restarted if necessary */ virNWFilterLearnThreadsTerminate(true); =20 VIR_WITH_MUTEX_LOCK_GUARD(&driverMutex) { VIR_WITH_MUTEX_LOCK_GUARD(&driver->updateLock) { - virNWFilterObjListLoadAllConfigs(driver->nwfilters, driver->co= nfigDir); + virNWFilterObjListLoadAllConfigs(driver->nwfilters, cfg->confi= gDir); } =20 =20 @@ -535,6 +515,7 @@ nwfilterDefineXMLFlags(virConnectPtr conn, virNWFilterObj *obj =3D NULL; virNWFilterDef *objdef; virNWFilterPtr nwfilter =3D NULL; + g_autoptr(virNWFilterDriverConfig) cfg =3D virNWFilterDriverGetConfig(= driver); =20 virCheckFlags(VIR_NWFILTER_DEFINE_VALIDATE, NULL); =20 @@ -558,7 +539,7 @@ nwfilterDefineXMLFlags(virConnectPtr conn, def =3D NULL; objdef =3D virNWFilterObjGetDef(obj); =20 - if (virNWFilterSaveConfig(driver->configDir, objdef) < 0) { + if (virNWFilterSaveConfig(cfg->configDir, objdef) < 0) { virNWFilterObjListRemove(driver->nwfilters, obj); goto cleanup; } @@ -588,6 +569,7 @@ nwfilterUndefine(virNWFilterPtr nwfilter) virNWFilterObj *obj; virNWFilterDef *def; int ret =3D -1; + g_autoptr(virNWFilterDriverConfig) cfg =3D virNWFilterDriverGetConfig(= driver); =20 VIR_WITH_MUTEX_LOCK_GUARD(&driver->updateLock) { if (!(obj =3D nwfilterObjFromNWFilter(nwfilter->uuid))) @@ -604,7 +586,7 @@ nwfilterUndefine(virNWFilterPtr nwfilter) goto cleanup; } =20 - if (virNWFilterDeleteDef(driver->configDir, def) < 0) + if (virNWFilterDeleteDef(cfg->configDir, def) < 0) goto cleanup; =20 virNWFilterObjListRemove(driver->nwfilters, obj); @@ -730,6 +712,7 @@ nwfilterBindingCreateXML(virConnectPtr conn, virNWFilterBindingDef *def; virNWFilterBindingObj *obj =3D NULL; virNWFilterBindingPtr ret =3D NULL; + g_autoptr(virNWFilterDriverConfig) cfg =3D virNWFilterDriverGetConfig(= driver); =20 virCheckFlags(VIR_NWFILTER_BINDING_CREATE_VALIDATE, NULL); =20 @@ -772,7 +755,7 @@ nwfilterBindingCreateXML(virConnectPtr conn, } } =20 - virNWFilterBindingObjSave(obj, driver->bindingDir); + virNWFilterBindingObjSave(obj, cfg->bindingDir); =20 cleanup: if (!obj) @@ -799,6 +782,7 @@ nwfilterBindingDelete(virNWFilterBindingPtr binding) virNWFilterBindingObj *obj; virNWFilterBindingDef *def; int ret =3D -1; + g_autoptr(virNWFilterDriverConfig) cfg =3D virNWFilterDriverGetConfig(= driver); =20 obj =3D virNWFilterBindingObjListFindByPortDev(driver->bindings, bindi= ng->portdev); if (!obj) { @@ -814,7 +798,7 @@ nwfilterBindingDelete(virNWFilterBindingPtr binding) VIR_WITH_MUTEX_LOCK_GUARD(&driver->updateLock) { virNWFilterTeardownFilter(def); } - virNWFilterBindingObjDelete(obj, driver->bindingDir); + virNWFilterBindingObjDelete(obj, cfg->bindingDir); virNWFilterBindingObjListRemove(driver->bindings, obj); =20 ret =3D 0; diff --git a/src/nwfilter/nwfilter_driver_conf.c b/src/nwfilter/nwfilter_dr= iver_conf.c new file mode 100644 index 0000000000..88ed10bfdb --- /dev/null +++ b/src/nwfilter/nwfilter_driver_conf.c @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2022 Red Hat, Inc. + * + * nwfilter_driver_conf.c: nwfilter.conf config file inspection + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + */ + +#include +#include "configmake.h" +#include "datatypes.h" +#include "virlog.h" +#include "virerror.h" +#include "virfile.h" +#include "virutil.h" +#include "virfirewall.h" /* for binary names */ +#include "nwfilter_driver_conf.h" + + +#define VIR_FROM_THIS VIR_FROM_NWFILTER + +VIR_LOG_INIT("nwfilter.nwfilter_driver"); + +static virClass *virNWFilterDriverConfigClass; +static void virNWFilterDriverConfigDispose(void *obj); + +static int +virNWFilterConfigOnceInit(void) +{ + if (!VIR_CLASS_NEW(virNWFilterDriverConfig, virClassForObject())) + return -1; + + return 0; +} + + +VIR_ONCE_GLOBAL_INIT(virNWFilterConfig); + + +static int +virNWFilterLoadDriverConfig(virNWFilterDriverConfig *cfg, + const char *filename) +{ + g_autoptr(virConf) conf =3D NULL; + g_autofree char *fwBackendStr =3D NULL; + bool fwBackendSelected =3D false; + size_t i; + int fwBackends[] =3D { + FIREWALL_BACKENDS + }; + G_STATIC_ASSERT(G_N_ELEMENTS(fwBackends) > 0 && + G_N_ELEMENTS(fwBackends) <=3D VIR_FIREWALL_BACKEND_LAS= T); + int nFwBackends =3D G_N_ELEMENTS(fwBackends); + + if (access(filename, R_OK) =3D=3D 0) { + + conf =3D virConfReadFile(filename, 0); + if (!conf) + return -1; + + /* use virConfGetValue*(conf, ...) functions to read any settings = into cfg */ + + if (virConfGetValueString(conf, "firewall_backend", &fwBackendStr)= < 0) + return -1; + if (virConfGetValueBool(conf, "enable_trace", &cfg->firewallTracin= g) < 0) + return -1; + if (virConfGetValueBool(conf, "enable_counters", &cfg->ruleCounter= s) < 0) + return -1; + + if (fwBackendStr) { + fwBackends[0] =3D virFirewallBackendTypeFromString(fwBackendSt= r); + nFwBackends =3D 1; + + if (fwBackends[0] < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("unrecognized nwfilter_driver =3D '%1$s' = set in nwfilter driver config file %2$s"), + fwBackendStr, filename); + return -1; + } + VIR_DEBUG("nwfilter_driver setting requested from config file = %s: '%s'", + filename, virFirewallBackendTypeToString(fwBackends[= 0])); + } + } + + for (i =3D 0; i < nFwBackends && !fwBackendSelected; i++) { + switch ((virFirewallBackend)fwBackends[i]) { + case VIR_FIREWALL_BACKEND_NONE: + fwBackendSelected =3D true; + break; + + case VIR_FIREWALL_BACKEND_IPTABLES: { + g_autofree char *iptablesInPath =3D virFindFileInPath(IPTABLES= ); + + if (iptablesInPath) + fwBackendSelected =3D true; + break; + } + + case VIR_FIREWALL_BACKEND_NFTABLES: { + g_autofree char *nftablesInPath =3D virFindFileInPath(NFT); + + if (nftablesInPath) + fwBackendSelected =3D true; + break; + } + + case VIR_FIREWALL_BACKEND_PF: { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("unsupported nwfilter driver PF")); + return -1; + } + + case VIR_FIREWALL_BACKEND_LAST: + virReportEnumRangeError(virFirewallBackend, fwBackends[i]); + return -1; + } + + if (fwBackendSelected) + cfg->firewallBackend =3D fwBackends[i]; + } + + if (fwBackendSelected) { + VIR_INFO("using nwfilter_driver: '%s'", + virFirewallBackendTypeToString(cfg->firewallBackend)); + return 0; + } else if (fwBackendStr) { + /* the explicitly requested driver wasn't found - this is a failur= e */ + virReportError(VIR_ERR_INTERNAL_ERROR, + _("requested nwfilter_driver '%1$s' is not availabl= e"), + fwBackendStr); + return -1; + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("could not find a usable nwfilter driver")); + return -1; + } +} + + +virNWFilterDriverConfig * +virNWFilterDriverConfigNew(bool privileged) +{ + g_autoptr(virNWFilterDriverConfig) cfg =3D NULL; + g_autofree char *configdir =3D NULL; + g_autofree char *configfile =3D NULL; + + if (virNWFilterConfigInitialize() < 0) + return NULL; + + if (!(cfg =3D virObjectNew(virNWFilterDriverConfigClass))) + return NULL; + + if (!privileged) + return g_steal_pointer(&cfg); + + cfg->stateDir =3D g_strdup(RUNSTATEDIR "/libvirt/nwfilter"); + cfg->configDir =3D g_strdup(SYSCONFDIR "/libvirt/nwfilter"); + cfg->bindingDir =3D g_strdup(RUNSTATEDIR "/libvirt/nwfilter-binding"); + configfile =3D g_strdup(SYSCONFDIR "/libvirt/nwfilter.conf"); + + if (virNWFilterLoadDriverConfig(cfg, configfile) < 0) + return NULL; + + if (g_mkdir_with_parents(cfg->stateDir, S_IRWXU) < 0) { + virReportSystemError(errno, _("cannot create state directory '%1$s= '"), + cfg->stateDir); + return NULL; + } + + if (g_mkdir_with_parents(cfg->configDir, S_IRWXU) < 0) { + virReportSystemError(errno, _("cannot create config directory '%1$= s'"), + cfg->configDir); + return NULL; + } + + if (g_mkdir_with_parents(cfg->bindingDir, S_IRWXU) < 0) { + virReportSystemError(errno, _("cannot create config directory '%1$= s'"), + cfg->bindingDir); + return NULL; + } + + return g_steal_pointer(&cfg); +} + + +virNWFilterDriverConfig * +virNWFilterDriverGetConfig(virNWFilterDriverState *driver) +{ + return virObjectRef(driver->config); +} + + +static void +virNWFilterDriverConfigDispose(void *obj) +{ + virNWFilterDriverConfig *cfg =3D obj; + + g_free(cfg->stateDir); + g_free(cfg->configDir); + g_free(cfg->bindingDir); +} diff --git a/src/nwfilter/nwfilter_driver_conf.h b/src/nwfilter/nwfilter_dr= iver_conf.h new file mode 100644 index 0000000000..356b3cb71e --- /dev/null +++ b/src/nwfilter/nwfilter_driver_conf.h @@ -0,0 +1,69 @@ +/* + * nwfilter_driver_conf.h: nwfilter driver state and config objects + * + * Copyright (C) 2006-2013 Red Hat, Inc. + * Copyright (C) 2006 Daniel P. Berrange + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#pragma once + +#include "libvirt_internal.h" +#include "virthread.h" +#include "virnwfilterobj.h" +#include "virfirewall.h" +#include "virinhibitor.h" + +typedef struct _virNWFilterDriverConfig virNWFilterDriverConfig; +struct _virNWFilterDriverConfig { + virObject parent; + + /* Immutable pointers, Immutable objects */ + char *stateDir; + char *configDir; + char *bindingDir; + + virFirewallBackend firewallBackend; + + bool firewallTracing; + bool ruleCounters; +}; + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNWFilterDriverConfig, virObjectUnref); + +/* Main driver state */ +typedef struct _virNWFilterDriverState virNWFilterDriverState; +struct _virNWFilterDriverState { + bool privileged; + + /* pid file FD, ensures two copies of the driver can't use the same ro= ot */ + int lockFD; + + virNWFilterObjList *nwfilters; + + virNWFilterBindingObjList *bindings; + + virNWFilterDriverConfig *config; + + /* Recursive. Hold for filter changes, instantiation or deletion */ + virMutex updateLock; + bool updateLockInitialized; +}; + +virNWFilterDriverConfig * +virNWFilterDriverConfigNew(bool privileged); +virNWFilterDriverConfig * +virNWFilterDriverGetConfig(virNWFilterDriverState *driver); diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfil= ter_ebiptables_driver.c index 6769a2fb42..6b6b3cbd69 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -78,7 +78,7 @@ VIR_LOG_INIT("nwfilter.nwfilter_ebiptables_driver"); #define MATCH_PHYSDEV_OUT_OLD_FW "-m", "physdev", "--physdev-out" =20 static int ebtablesRemoveBasicRules(const char *ifname); -static int ebiptablesDriverInit(bool privileged); +static int ebiptablesDriverInit(bool privileged, virNWFilterDriverConfig *= config G_GNUC_UNUSED); static void ebiptablesDriverShutdown(void); static int ebtablesCleanAll(const char *ifname); static int ebiptablesAllTeardown(const char *ifname); @@ -3400,7 +3400,7 @@ virNWFilterTechDriver ebiptables_driver =3D { }; =20 static int -ebiptablesDriverInit(bool privileged) +ebiptablesDriverInit(bool privileged, virNWFilterDriverConfig *config G_GN= UC_UNUSED) { if (!privileged) return 0; diff --git a/src/nwfilter/nwfilter_ebiptables_driver.h b/src/nwfilter/nwfil= ter_ebiptables_driver.h index cb146f9f97..dfaea5af3d 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.h +++ b/src/nwfilter/nwfilter_ebiptables_driver.h @@ -27,6 +27,6 @@ =20 extern virNWFilterTechDriver ebiptables_driver; =20 -#define EBIPTABLES_DRIVER_ID "ebiptables" +#define EBIPTABLES_DRIVER_ID "iptables" =20 #define IPTABLES_MAX_COMMENT_LENGTH 256 diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter= _gentech_driver.c index 1465734a54..29f80a8677 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -32,6 +32,7 @@ #include "nwfilter_dhcpsnoop.h" #include "nwfilter_ipaddrmap.h" #include "nwfilter_learnipaddr.h" +#include "nwfilter_nftables_driver.h" #include "virnetdev.h" =20 #define VIR_FROM_THIS VIR_FROM_NWFILTER @@ -48,18 +49,23 @@ static int _virNWFilterTeardownFilter(const char *ifnam= e); =20 static virNWFilterTechDriver *filter_tech_drivers[] =3D { &ebiptables_driver, - NULL + &nftables_driver, }; =20 -int virNWFilterTechDriversInit(bool privileged) +int virNWFilterTechDriversInit(bool privileged, virNWFilterDriverConfig *c= onfig) { size_t i =3D 0; - VIR_DEBUG("Initializing NWFilter technology drivers"); - while (filter_tech_drivers[i]) { - if (!(filter_tech_drivers[i]->flags & TECHDRV_FLAG_INITIALIZED)) - filter_tech_drivers[i]->init(privileged); - i++; + VIR_DEBUG("Initializing NWFilter technology drivers, chosen '%s'", + virFirewallBackendTypeToString(config->firewallBackend)); + + for (i =3D 0; i < G_N_ELEMENTS(filter_tech_drivers); i++) { + if (filter_tech_drivers[i]->flags & TECHDRV_FLAG_INITIALIZED) + continue; + if (STREQ(filter_tech_drivers[i]->name, + virFirewallBackendTypeToString(config->firewallBackend))) + filter_tech_drivers[i]->init(privileged, config); } + return 0; } =20 @@ -67,25 +73,20 @@ int virNWFilterTechDriversInit(bool privileged) void virNWFilterTechDriversShutdown(void) { size_t i =3D 0; - while (filter_tech_drivers[i]) { + for (i =3D 0; i < G_N_ELEMENTS(filter_tech_drivers); i++) { if ((filter_tech_drivers[i]->flags & TECHDRV_FLAG_INITIALIZED)) filter_tech_drivers[i]->shutdown(); - i++; } } =20 =20 static virNWFilterTechDriver * -virNWFilterTechDriverForName(const char *name) +virNWFilterInitializedTechDriver(void) { size_t i =3D 0; - while (filter_tech_drivers[i]) { - if (STREQ(filter_tech_drivers[i]->name, name)) { - if ((filter_tech_drivers[i]->flags & TECHDRV_FLAG_INITIALIZED)= =3D=3D 0) - break; + for (i =3D 0; i < G_N_ELEMENTS(filter_tech_drivers); i++) { + if ((filter_tech_drivers[i]->flags & TECHDRV_FLAG_INITIALIZED)) return filter_tech_drivers[i]; - } - i++; } return NULL; } @@ -617,7 +618,6 @@ virNWFilterInstantiateFilterUpdate(virNWFilterDriverSta= te *driver, bool *foundNewFilter) { int rc =3D -1; - const char *drvname =3D EBIPTABLES_DRIVER_ID; virNWFilterTechDriver *techdriver; virNWFilterObj *obj; virNWFilterDef *filter; @@ -625,12 +625,11 @@ virNWFilterInstantiateFilterUpdate(virNWFilterDriverS= tate *driver, char vmmacaddr[VIR_MAC_STRING_BUFLEN] =3D {0}; virNWFilterVarValue *ipaddr; =20 - techdriver =3D virNWFilterTechDriverForName(drvname); + techdriver =3D virNWFilterInitializedTechDriver(); =20 if (!techdriver) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Could not get access to ACL tech driver '%1$s'"), - drvname); + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not get access to ACL tech driver")); return -1; } =20 @@ -768,15 +767,13 @@ virNWFilterUpdateInstantiateFilter(virNWFilterDriverS= tate *driver, static int virNWFilterRollbackUpdateFilter(virNWFilterBindingDef *binding) { - const char *drvname =3D EBIPTABLES_DRIVER_ID; int ifindex; virNWFilterTechDriver *techdriver; =20 - techdriver =3D virNWFilterTechDriverForName(drvname); + techdriver =3D virNWFilterInitializedTechDriver(); if (!techdriver) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Could not get access to ACL tech driver '%1$s'"), - drvname); + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not get access to ACL tech driver")); return -1; } =20 @@ -793,15 +790,13 @@ virNWFilterRollbackUpdateFilter(virNWFilterBindingDef= *binding) static int virNWFilterTearOldFilter(virNWFilterBindingDef *binding) { - const char *drvname =3D EBIPTABLES_DRIVER_ID; int ifindex; virNWFilterTechDriver *techdriver; =20 - techdriver =3D virNWFilterTechDriverForName(drvname); + techdriver =3D virNWFilterInitializedTechDriver(); if (!techdriver) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Could not get access to ACL tech driver '%1$s'"), - drvname); + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not get access to ACL tech driver")); return -1; } =20 @@ -818,14 +813,12 @@ virNWFilterTearOldFilter(virNWFilterBindingDef *bindi= ng) static int _virNWFilterTeardownFilter(const char *ifname) { - const char *drvname =3D EBIPTABLES_DRIVER_ID; virNWFilterTechDriver *techdriver; - techdriver =3D virNWFilterTechDriverForName(drvname); + techdriver =3D virNWFilterInitializedTechDriver(); =20 if (!techdriver) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Could not get access to ACL tech driver '%1$s'"), - drvname); + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not get access to ACL tech driver")); return -1; } =20 diff --git a/src/nwfilter/nwfilter_gentech_driver.h b/src/nwfilter/nwfilter= _gentech_driver.h index 946d5d3d56..0059ca6bdb 100644 --- a/src/nwfilter/nwfilter_gentech_driver.h +++ b/src/nwfilter/nwfilter_gentech_driver.h @@ -24,8 +24,11 @@ =20 #include "virnwfilterobj.h" #include "virnwfilterbindingdef.h" +#include "nwfilter_driver_conf.h" +#include "virfirewall.h" =20 -int virNWFilterTechDriversInit(bool privileged); + +int virNWFilterTechDriversInit(bool privileged, virNWFilterDriverConfig *c= onfig); void virNWFilterTechDriversShutdown(void); =20 enum instCase { diff --git a/src/nwfilter/nwfilter_nftables_driver.c b/src/nwfilter/nwfilte= r_nftables_driver.c index 317170d850..0e80686393 100644 --- a/src/nwfilter/nwfilter_nftables_driver.c +++ b/src/nwfilter/nwfilter_nftables_driver.c @@ -38,16 +38,20 @@ =20 #define VIR_FROM_THIS VIR_FROM_NWFILTER =20 -/* define nftable root table */ +/* define nftable root tables */ #define NF_ETHERNET_TABLE "libvirt_nwfilter_ethernet" #define NF_INET_TABLE "libvirt_nwfilter_inet" + #define NF_COMMENT \ "{ comment \"Managed by libvirt for network filters: " \ "https://libvirt.org/firewall.html#the-network-filter-driver\"; }" + /* nftables counter can be enabled for firewalls transparency */ -#ifndef NF_COUNTER -# define NF_COUNTER 0 -#endif +static bool counters_enabled; + +/* nftables tracing can be enabled for firewall debugging, +* to find out where packets are flowing towards */ +static bool trace_enabled; =20 /* define chains */ #define IN_CHAIN "postrouting" @@ -66,14 +70,7 @@ =20 #define DEFAULT_POLICY "accept" =20 -#ifndef NF_TRACE -# define NF_TRACE 0 -#endif -#if NF_TRACE -# define TRACE_SETTING "meta nftrace set 1;" -#else -# define TRACE_SETTING "" -#endif +#define TRACE_SETTING "meta nftrace set 1;" =20 #define CHAINSETTINGS "{ }" =20 @@ -85,7 +82,7 @@ =20 #define ROOT_CHAINSETTINGS(chain, defaultPolicy) \ "{ type filter hook "chain" priority %d;" \ - " policy "defaultPolicy"; "TRACE_SETTING" }" + " policy "defaultPolicy"; %s }" =20 VIR_LOG_INIT("nwfilter.nwfilter_nftables_driver"); =20 @@ -165,6 +162,7 @@ static void nftablesCreateTable(virFirewall *fw, const char *tableName) { virFirewallCmd *fwrule =3D NULL; + const char *traceSetting =3D trace_enabled ? TRACE_SETTING : ""; int tablePriority =3D STREQ(tableName, NF_ETHERNET_TABLE) ? 0 : 1; =20 /* define table */ @@ -186,12 +184,12 @@ static void nftablesCreateTable(virFirewall *fw, tableName, IN_CHAIN, NULL); virFirewallCmdAddArgFormat(fw, fwrule, ROOT_CHAINSETTINGS(IN_CHAIN, DEFAULT_POLICY= ), - tablePriority); + tablePriority, traceSetting); fwrule =3D virFirewallAddCmd(fw, layer, "add", "chain", "bridge", tableName, OUT_CHAIN, NULL); virFirewallCmdAddArgFormat(fw, fwrule, ROOT_CHAINSETTINGS(OUT_CHAIN, DEFAULT_POLIC= Y), - tablePriority); + tablePriority, traceSetting); =20 /* add the one jump rule based on the vmap */ fwrule =3D virFirewallAddCmd(fw, layer, "add", "rule", "bridge", table= Name, @@ -1717,7 +1715,7 @@ nftablesCreateRuleInstance(virFirewall *fw, goto cleanup; } =20 - if (NF_COUNTER) + if (counters_enabled) virFirewallCmdAddArg(fw, fwrule, "counter"); =20 /* specify the action for this rule */ @@ -2847,11 +2845,14 @@ nftablesDropAllRules(const char *ifname) } =20 static int -nftablesDriverInit(bool privileged) +nftablesDriverInit(bool privileged, virNWFilterDriverConfig *config G_GNUC= _UNUSED) { if (!privileged) return 0; =20 + trace_enabled =3D config->firewallTracing; + counters_enabled =3D config->ruleCounters; + nftables_driver.flags =3D TECHDRV_FLAG_INITIALIZED; =20 return 0; diff --git a/src/nwfilter/nwfilter_tech_driver.h b/src/nwfilter/nwfilter_te= ch_driver.h index c69752da10..41e0613d7d 100644 --- a/src/nwfilter/nwfilter_tech_driver.h +++ b/src/nwfilter/nwfilter_tech_driver.h @@ -24,6 +24,7 @@ #pragma once =20 #include "virnwfilterobj.h" +#include "nwfilter_driver_conf.h" =20 typedef struct _virNWFilterRuleInst virNWFilterRuleInst; struct _virNWFilterRuleInst { @@ -60,7 +61,7 @@ enum virNWFilterProtoIdx { =20 #define virNWFilterUShortMapEntryIdx(IDX, ATT, VAL) [IDX] =3D { .attr =3D = ATT, .val =3D VAL } =20 -typedef int (*virNWFilterTechDrvInit)(bool privileged); +typedef int (*virNWFilterTechDrvInit)(bool privileged, virNWFilterDriverCo= nfig *config); typedef void (*virNWFilterTechDrvShutdown)(void); =20 typedef int (*virNWFilterRuleApplyNewRules)(const char *ifname, diff --git a/src/nwfilter/test_libvirtd_nwfilter.aug.in b/src/nwfilter/test= _libvirtd_nwfilter.aug.in new file mode 100644 index 0000000000..e6e62550e4 --- /dev/null +++ b/src/nwfilter/test_libvirtd_nwfilter.aug.in @@ -0,0 +1,7 @@ +module Test_libvirtd_nwfilter =3D + @CONFIG@ + + test Libvirtd_nwfilter.lns get conf =3D +{ "firewall_backend" =3D "nftables" } +{ "enable_trace" =3D "0" } +{ "enable_counters" =3D "0" } --=20 2.43.0 From nobody Sat May 30 15:29:22 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) client-ip=38.145.34.151; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1779124154; cv=none; d=zohomail.com; s=zohoarc; b=NLf9+Xevy19jSSdwkLazBap1VIm/EruUOo2hR4Jey6a0btfpG6X4bs3oI5JjTiNcACLuspejP7na6fuHxN6jbM+EiV51dIenGXRBy/QVf7fGZuBDG1O3E9kx4TUKGNyI4IKKNHi3GaScQXV0LA+WTEs3O/t7rFGby2LxtYGP+P4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1779124154; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=4yqjT5Df0vwIkgzdAhhNqMNmPJIjsjqQhPY9lU2IWLo=; b=IGFDMlG1ytYnMigmYZAwlUooe+yvIJFcmbLsCoe3IwXpVb6Ja4OsWnUWEcYLsCsMNNQa6rzXyp3mqGYwfEGTRs/J508DL0FW5tapFh7mcbpLRIOBRFXVGP8AWS1iYbAm7Ri0BxR4iHEJlO5Q3Ar4UyrTrbkehE/dwIpLilJ08pk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [38.145.34.151]) by mx.zohomail.com with SMTPS id 1779124154948924.4899052862942; Mon, 18 May 2026 10:09:14 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 0E17D41903; Mon, 18 May 2026 13:09:14 -0400 (EDT) Received: from [172.19.199.5] (unknown [10.16.107.18]) by lists.libvirt.org (Postfix) with ESMTP id 6E1BB41A8F; Mon, 18 May 2026 13:01:02 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 4B83A41977; Mon, 18 May 2026 13:00:45 -0400 (EDT) Received: from mx11.osci.io (polly.osci.io [IPv6:2620:52:6:3141:1::41]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 30052457FA for ; Mon, 18 May 2026 12:03:56 -0400 (EDT) Received: by mx11.osci.io (Postfix, from userid 994) id C3B1268596; Mon, 18 May 2026 08:31:59 -0400 (EDT) Received: from mail-ed1-x52d.google.com (mail-ed1-x52d.google.com [IPv6:2a00:1450:4864:20::52d]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by mx11.osci.io (Postfix) with ESMTPS id 50A0268594 for ; Mon, 18 May 2026 08:31:57 -0400 (EDT) Received: by mail-ed1-x52d.google.com with SMTP id 4fb4d7f45d1cf-676a89de629so3782029a12.1 for ; Mon, 18 May 2026 05:31:57 -0700 (PDT) Received: from thinkiepadje.home (2a02-a470-a384-0-b529-3d3d-353-106e.fixed6.kpn.net. [2a02:a470:a384:0:b529:3d3d:353:106e]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bd4f4e4d54dsm553354066b.47.2026.05.18.05.29.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 May 2026 05:29:54 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779107396; x=1779712196; darn=lists.libvirt.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4yqjT5Df0vwIkgzdAhhNqMNmPJIjsjqQhPY9lU2IWLo=; b=qKGWu/IaDjiFnnL2Am4BI7Olxy2V/DUGICr1vWr5iMI+z+TEHEWF7m5XIxGeUzOMxk Le2FhFNu3hd12kbzOLkKz6wPcXZ2zAka3MxOKrtnj78Qzwi0NQiXZ5A9KIpPF9gwmzvh nwvFc7CsKtsPbmFAMRK7HbAX6XRugYEnlYFFFFNYuxy1o3lj5dd1+nWJxT8yI+zxt82W Hq1xUBqAkIwZ9WNQgGNApJaLFB2QV7A0WRvzKr1FRKzBsxsBCN8n+5SefjWGDnTDYPsS R7ZPanaiK+9sN55UpxVFXH3sytBnoZQiAe2RAmKtGPW44RZ5MUby+VcctI5sa2bPuGqV pmAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779107396; x=1779712196; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=4yqjT5Df0vwIkgzdAhhNqMNmPJIjsjqQhPY9lU2IWLo=; b=L1/9vBqPG1QyVuUn6P46qKVSGfpvgn5U0vFHVcuiNBnL33+HdiEBzXmd0oLu+hW9qx VLDiKBk65siyHOrHQvYnIBbbZFmjHPC4xKwqFV5+jeFmUDGUy2kOS9sl/bJtFVk89lmt 8tpxQTGqab9lHNN1OpT5pAw9s9p0+dWobz248wGpW7Q/l7NgXaHBsJmKk26bFXSkAkKo t9tLeGyZqPO9C9/UItvcih+ioSDmkqLQxG1lJ5bjTEUnYTHSdYBwXpTvrcV5vyY3YrPM 7xHv+kuSCzdy2iiKr6kWy6AEjHktZd0OSClMi87ncaeXYWGxVoUkbma+nfYju6QEznua Srdg== X-Gm-Message-State: AOJu0YzX42deSfNoiKE8AoMp8CiZZcXpGfr4kELkzUQN/Gbe5Xw1jAju Zt/U38wkAb0pxVPxrSijPgrsvjDi5mnNqcD/cX9baWK0QHr8X0TXBYFaAFoO X-Gm-Gg: Acq92OH/8m7wRQA9IWK6ii5Ja9l+/rVwtdhyOxluC7UzHQTPwme36mfHlXRlCqhwZpV jMraoBp5+OddtW0u/73iPPBt+6wg382+EJl0GQpMpmji10X3vtoS7eCzspKnWoZ1s9v95JRPj5G 1N8bBCxI7yDb7YtQI1rqF5nZTb4BBnU4ZKPyydr9lAmS7PRjK7cDKKx365uaZTgUMMKXHyanEsC xOxkBE3B48IwAuujog0jdDU0NPRrlv8hXSjSKHF0i3wqrnj5sU+afbeLRXKP5j+MM8be772Til+ PLO259Y8wUJ8nRrov4dSzBykyTT9Qgy3CLhHulLT8bhC53qJRi5nxs/NTJsiKqarZmFb+jGBP7w IZjoXH3TE/Q9DbWfJfHbqOGu9Qbio71XceLcC09xna7Bu60GFqOPtxGF5NNOXhUFEBa5YoJIRyH u7LADIm6/DzCBT8Cr+onQ5+79QG7PVAYVdgC62Wcr9xISCTtO71QkoxD+Q7i1xZXvvDWg0PTf1I qKU8vULlbwpYPxVYGQEvc0= X-Received: by 2002:a17:906:ef03:b0:bc5:111d:3c96 with SMTP id a640c23a62f3a-bd5177a9ba0mr763709666b.10.1779107395140; Mon, 18 May 2026 05:29:55 -0700 (PDT) From: Dion Bosschieter To: devel@lists.libvirt.org Subject: [PATCH v7 3/4] nwfilter: add unit tests and test data for nwfilter nftables driver Date: Mon, 18 May 2026 14:25:45 +0200 Message-ID: <20260518122547.163157-4-dionbosschieter@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260518122547.163157-1-dionbosschieter@gmail.com> References: <20260518122547.163157-1-dionbosschieter@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: BDJRBQLC6BKQZFTXE3LMGSLBXUJ7OYH3 X-Message-ID-Hash: BDJRBQLC6BKQZFTXE3LMGSLBXUJ7OYH3 X-MailFrom: SRS0=UfGQ=DP=gmail.com=dionbosschieter@osci.io X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: jean-louis@dupond.be, Dion Bosschieter X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1779124156579154100 Content-Type: text/plain; charset="utf-8" Add unit test files nwfilternftablestest.c and nwfilterxml2nftfirewalltest.c, including data files in existing nwfilterxml2firewalldata directory. Tests follow same style and structure like the ebiptables driver for nwfilter. Signed-off-by: Dion Bosschieter --- tests/meson.build | 2 + tests/nwfilternftablestest.c | 426 ++ .../ah-ipv6-linux.nftables.args | 298 ++ .../ah-linux.nftables.args | 292 ++ .../all-ipv6-linux.nftables.args | 280 ++ .../all-linux.nftables.args | 274 ++ .../arp-linux.nftables.args | 285 ++ .../comment-linux.nftables.args | 502 +++ .../conntrack-linux.nftables.args | 190 + .../esp-ipv6-linux.nftables.args | 298 ++ .../esp-linux.nftables.args | 292 ++ .../example-1-linux.nftables.args | 252 ++ .../example-2-linux.nftables.args | 352 ++ .../hex-data-linux.nftables.args | 368 ++ .../icmp-direction-linux.nftables.args | 226 ++ .../icmp-direction2-linux.nftables.args | 226 ++ .../icmp-direction3-linux.nftables.args | 176 + .../icmp-linux.nftables.args | 248 ++ .../icmpv6-linux.nftables.args | 316 ++ .../igmp-linux.nftables.args | 292 ++ .../ip-linux.nftables.args | 199 + .../ipt-no-macspoof-linux.nftables.args | 166 + .../ipv6-linux.nftables.args | 481 +++ .../iter1-linux.nftables.args | 292 ++ .../iter2-linux.nftables.args | 3532 +++++++++++++++++ .../iter3-linux.nftables.args | 410 ++ .../mac-linux.nftables.args | 176 + .../rarp-linux.nftables.args | 207 + .../sctp-ipv6-linux.nftables.args | 316 ++ .../sctp-linux.nftables.args | 316 ++ .../stp-linux.nftables.args | 233 ++ .../target-linux.nftables.args | 454 +++ .../target2-linux.nftables.args | 302 ++ .../tcp-ipv6-linux.nftables.args | 316 ++ .../tcp-linux.nftables.args | 452 +++ .../udp-ipv6-linux.nftables.args | 316 ++ .../udp-linux.nftables.args | 316 ++ .../udplite-ipv6-linux.nftables.args | 298 ++ .../udplite-linux.nftables.args | 292 ++ .../vlan-linux.nftables.args | 257 ++ tests/nwfilterxml2nftfirewalltest.c | 432 ++ 41 files changed, 15358 insertions(+) create mode 100644 tests/nwfilternftablestest.c create mode 100755 tests/nwfilterxml2firewalldata/ah-ipv6-linux.nftables.a= rgs create mode 100755 tests/nwfilterxml2firewalldata/ah-linux.nftables.args create mode 100755 tests/nwfilterxml2firewalldata/all-ipv6-linux.nftables.= args create mode 100755 tests/nwfilterxml2firewalldata/all-linux.nftables.args create mode 100755 tests/nwfilterxml2firewalldata/arp-linux.nftables.args create mode 100755 tests/nwfilterxml2firewalldata/comment-linux.nftables.a= rgs create mode 100755 tests/nwfilterxml2firewalldata/conntrack-linux.nftables= .args create mode 100755 tests/nwfilterxml2firewalldata/esp-ipv6-linux.nftables.= args create mode 100755 tests/nwfilterxml2firewalldata/esp-linux.nftables.args create mode 100755 tests/nwfilterxml2firewalldata/example-1-linux.nftables= .args create mode 100755 tests/nwfilterxml2firewalldata/example-2-linux.nftables= .args create mode 100755 tests/nwfilterxml2firewalldata/hex-data-linux.nftables.= args create mode 100755 tests/nwfilterxml2firewalldata/icmp-direction-linux.nft= ables.args create mode 100755 tests/nwfilterxml2firewalldata/icmp-direction2-linux.nf= tables.args create mode 100755 tests/nwfilterxml2firewalldata/icmp-direction3-linux.nf= tables.args create mode 100755 tests/nwfilterxml2firewalldata/icmp-linux.nftables.args create mode 100755 tests/nwfilterxml2firewalldata/icmpv6-linux.nftables.ar= gs create mode 100755 tests/nwfilterxml2firewalldata/igmp-linux.nftables.args create mode 100755 tests/nwfilterxml2firewalldata/ip-linux.nftables.args create mode 100755 tests/nwfilterxml2firewalldata/ipt-no-macspoof-linux.nf= tables.args create mode 100755 tests/nwfilterxml2firewalldata/ipv6-linux.nftables.args create mode 100755 tests/nwfilterxml2firewalldata/iter1-linux.nftables.args create mode 100755 tests/nwfilterxml2firewalldata/iter2-linux.nftables.args create mode 100755 tests/nwfilterxml2firewalldata/iter3-linux.nftables.args create mode 100755 tests/nwfilterxml2firewalldata/mac-linux.nftables.args create mode 100755 tests/nwfilterxml2firewalldata/rarp-linux.nftables.args create mode 100755 tests/nwfilterxml2firewalldata/sctp-ipv6-linux.nftables= .args create mode 100755 tests/nwfilterxml2firewalldata/sctp-linux.nftables.args create mode 100644 tests/nwfilterxml2firewalldata/stp-linux.nftables.args create mode 100755 tests/nwfilterxml2firewalldata/target-linux.nftables.ar= gs create mode 100755 tests/nwfilterxml2firewalldata/target2-linux.nftables.a= rgs create mode 100755 tests/nwfilterxml2firewalldata/tcp-ipv6-linux.nftables.= args create mode 100755 tests/nwfilterxml2firewalldata/tcp-linux.nftables.args create mode 100755 tests/nwfilterxml2firewalldata/udp-ipv6-linux.nftables.= args create mode 100755 tests/nwfilterxml2firewalldata/udp-linux.nftables.args create mode 100755 tests/nwfilterxml2firewalldata/udplite-ipv6-linux.nftab= les.args create mode 100755 tests/nwfilterxml2firewalldata/udplite-linux.nftables.a= rgs create mode 100755 tests/nwfilterxml2firewalldata/vlan-linux.nftables.args create mode 100644 tests/nwfilterxml2nftfirewalltest.c diff --git a/tests/meson.build b/tests/meson.build index 83aa0104bb..bcc446b5eb 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -444,7 +444,9 @@ endif if conf.has('WITH_NWFILTER') tests +=3D [ { 'name': 'nwfilterebiptablestest', 'link_with': [ nwfilter_driver_imp= l ] }, + { 'name': 'nwfilternftablestest', 'link_with': [ nwfilter_driver_impl = ] }, { 'name': 'nwfilterxml2ebipfirewalltest', 'link_with': [ nwfilter_driv= er_impl ] }, + { 'name': 'nwfilterxml2nftfirewalltest', 'link_with': [ nwfilter_drive= r_impl ] }, ] endif =20 diff --git a/tests/nwfilternftablestest.c b/tests/nwfilternftablestest.c new file mode 100644 index 0000000000..a2480ec971 --- /dev/null +++ b/tests/nwfilternftablestest.c @@ -0,0 +1,426 @@ +/* + * nwfilternftablestest.c: Test nftables rule generation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + */ + +#include + +#include "testutils.h" +#include "nwfilter/nwfilter_nftables_driver.h" +#include "virbuffer.h" + +#define LIBVIRT_VIRCOMMANDPRIV_H_ALLOW +#include "vircommandpriv.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +#define EXISTING_TABLE \ + "table bridge %s { # handle 562\n" \ + " comment \"this table is managed by libvirt\"\n" \ + " map vmap-oif { # handle 1\n" \ + " type iface_index : verdict\n" \ + " elements =3D { \"vnet0\" : jump vnet0-in }\n" \ + " }\n" \ + "\n" \ + " map vmap-iif { # handle 2\n" \ + " type iface_index : verdict\n" \ + " elements =3D { \"vnet0\" : jump vnet0-out }\n" \ + " }\n" \ + "\n" \ + " chain postrouting { # handle 3\n" \ + " type filter hook postrouting priority 1; policy accept;\n" \ + " meta nftrace set 1 # handle 4\n" \ + " oif vmap @vmap-oif # handle 7\n" \ + " }\n" \ + "\n" \ + " chain prerouting { # handle 5\n" \ + " type filter hook prerouting priority 1; policy accept;\n" \ + " meta nftrace set 1 # handle 6\n" \ + " iif vmap @vmap-iif # handle 8\n" \ + " }\n" \ + "\n" \ + " chain n-vnet0-in { # handle 880\n" \ + " ether type ip jump vnet0-ipv4-in # handle 893\n" \ + " ether type ip6 jump vnet0-ipv6-in # handle 897\n" \ + " }\n" \ + "\n" \ + " chain vnet0-in { # handle 880\n" \ + " ether type ip jump vnet0-ipv4-in # handle 893\n" \ + " ether type ip6 jump vnet0-ipv6-in # handle 897\n" \ + " }\n" \ + "\n" \ + " chain vnet0-out { # handle 881\n" \ + " ip6 saddr 2a01:7c8:e100:1::78e2 tcp dport 465-465 ct directio= n original drop comment \"priority=3D100\" # handle 882\n" \ + " ip6 saddr 2a01:7c8:e100:1::78e2 tcp dport 587-587 ct directio= n original drop comment \"priority=3D100\" # handle 883\n" \ + " ip saddr 192.168.1.2 tcp dport 25-25 ct direction original dr= op comment \"priority=3D100\" # handle 884\n" \ + " ip saddr 192.168.1.2 tcp dport 587-587 ct direction original = drop comment \"priority=3D100\" # handle 885\n" \ + " ether type ip tcp dport 25-25 ct direction original drop comm= ent \"priority=3D100\" # handle 886\n" \ + " ether type ip6 tcp dport 25-25 ct direction original drop com= ment \"priority=3D100\" # handle 887\n" \ + " ip6 daddr 2a01:7c8:e100:1::78e2 tcp dport 465-465 ct directio= n original accept comment \"priority=3D100\" # handle 888\n" \ + " ip6 saddr 2a01:7c8:e100:1::78e2 udp dport 587-587 ct directio= n original drop comment \"priority=3D100\" # handle 889\n" \ + " ip saddr 192.168.1.2 udp dport 25-25 ct direction original co= ntinue comment \"priority=3D100\" # handle 890\n" \ + " ether type ip ct direction original continue comment \"priori= ty=3D100\" # handle 891\n" \ + " ether type ip jump vnet0-ipv4-out # handle 895\n" \ + " ether type ip6 jump vnet0-ipv6-out # handle 899\n" \ + " }\n" \ + "\n" \ + " chain vnet0-ipv4-in { # handle 892\n" \ + " ip saddr 192.168.1.1 tcp dport 4444 ct direction reply ct sta= te established,new accept comment \"priority=3D302\" # handle 902\n" \ + " ether type ip meta l4proto tcp ct direction reply drop commen= t \"priority=3D601\" # handle 904\n" \ + " ether type ip meta l4proto udp ct direction reply drop commen= t \"priority=3D603\" # handle 905\n" \ + " }\n" \ + "\n" \ + " chain vnet0-ipv4-out { # handle 894\n" \ + " ip protocol icmp ct count over 42 drop comment \"priority=3D4= 00\" # handle 903\n" \ + " }\n" \ + "\n" \ + " chain vnet0-ipv6-in { # handle 896\n" \ + " ip6 daddr fe80::5054:ff:fe60:baae udp sport 547 udp dport 546= ct direction reply accept comment \"priority=3D111\" # handle 901\n" \ + " }\n" \ + "\n" \ + " chain vnet0-ipv6-out { # handle 898\n" \ + " ip6 saddr fe80::5054:ff:fe60:baae ip6 daddr ff02::1:2 udp spo= rt 546 udp dport 547 ct direction original accept comment \"priority=3D110\= " # handle 900\n" \ + " }\n" \ + "}\n" + +#define OLD_REMOVES \ + "nft -a list table bridge libvirt_nwfilter_ethernet\n" \ + "nft -a list table bridge libvirt_nwfilter_inet\n" \ + "nft delete element bridge libvirt_nwfilter_ethernet vmap-oif '{' '\"v= net0\"' '}'\n" \ + "nft delete element bridge libvirt_nwfilter_ethernet vmap-iif '{' '\"v= net0\"' '}'\n" \ + "nft delete chain bridge libvirt_nwfilter_ethernet vnet0-in\n" \ + "nft delete chain bridge libvirt_nwfilter_ethernet vnet0-out\n" \ + "nft delete chain bridge libvirt_nwfilter_ethernet vnet0-ipv4-in\n" \ + "nft delete chain bridge libvirt_nwfilter_ethernet vnet0-ipv4-out\n" \ + "nft delete chain bridge libvirt_nwfilter_ethernet vnet0-ipv6-in\n" \ + "nft delete chain bridge libvirt_nwfilter_ethernet vnet0-ipv6-out\n" \ + "nft delete element bridge libvirt_nwfilter_inet vmap-oif '{' '\"vnet0= \"' '}'\n" \ + "nft delete element bridge libvirt_nwfilter_inet vmap-iif '{' '\"vnet0= \"' '}'\n" \ + "nft delete chain bridge libvirt_nwfilter_inet vnet0-in\n" \ + "nft delete chain bridge libvirt_nwfilter_inet vnet0-out\n" \ + "nft delete chain bridge libvirt_nwfilter_inet vnet0-ipv4-in\n" \ + "nft delete chain bridge libvirt_nwfilter_inet vnet0-ipv4-out\n" \ + "nft delete chain bridge libvirt_nwfilter_inet vnet0-ipv6-in\n" \ + "nft delete chain bridge libvirt_nwfilter_inet vnet0-ipv6-out\n" + +static void +testCommandDryRunCallback(const char *const*args, + const char *const*env G_GNUC_UNUSED, + const char *input G_GNUC_UNUSED, + char **output, + char **error G_GNUC_UNUSED, + int *status, + void *opaque G_GNUC_UNUSED) +{ + size_t argc =3D 0; + const char *table; + + while (args[argc] !=3D NULL) + argc++; + + if (STRNEQ(args[0], "nft")) { + *status =3D EXIT_FAILURE; + return; + } + + /* simulate an empty existing set rules */ + if (argc =3D=3D 6 && STREQ(args[1], "-a") && STREQ(args[2], "list")) { + table =3D args[argc-1]; + *output =3D g_strdup_printf(EXISTING_TABLE, table); + *status =3D EXIT_SUCCESS; + } +} + + +static int +testNWFilterNFTablesAllTeardown(const void *opaque G_GNUC_UNUSED) +{ + g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; + const char *expected =3D OLD_REMOVES; + g_autofree char *actual =3D NULL; + g_autoptr(virCommandDryRunToken) dryRunToken =3D virCommandDryRunToken= New(); + + virCommandSetDryRun(dryRunToken, &buf, false, true, testCommandDryRunC= allback, NULL); + + if (nftables_driver.allTeardown("vnet0") < 0) + return -1; + + actual =3D virBufferContentAndReset(&buf); + + if (virTestCompareToString(expected, actual) < 0) { + return -1; + } + + return 0; +} + + +static int +testNWFilterNFTablesTearOldRules(const void *opaque G_GNUC_UNUSED) +{ + g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; + const char *expected =3D + "nft -a list table bridge libvirt_nwfilter_ethernet\n" + "nft -a list table bridge libvirt_nwfilter_inet\n" + OLD_REMOVES + "nft rename chain bridge libvirt_nwfilter_ethernet n-vnet0-in vnet= 0-in\n" + "nft rename chain bridge libvirt_nwfilter_inet n-vnet0-in vnet0-in= \n"; + g_autofree char *actual =3D NULL; + g_autoptr(virCommandDryRunToken) dryRunToken =3D virCommandDryRunToken= New(); + + virCommandSetDryRun(dryRunToken, &buf, false, true, testCommandDryRunC= allback, NULL); + + if (nftables_driver.tearOldRules("vnet0") < 0) + return -1; + + actual =3D virBufferContentAndReset(&buf); + + if (virTestCompareToString(expected, actual) < 0) { + return -1; + } + + return 0; +} + + +static int +testNWFilterNFTablesRemoveBasicRules(const void *opaque G_GNUC_UNUSED) +{ + g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; + const char *expected =3D OLD_REMOVES; + g_autofree char *actual =3D NULL; + g_autoptr(virCommandDryRunToken) dryRunToken =3D virCommandDryRunToken= New(); + + virCommandSetDryRun(dryRunToken, &buf, false, true, testCommandDryRunC= allback, NULL); + + if (nftables_driver.removeBasicRules("vnet0") < 0) + return -1; + + actual =3D virBufferContentAndReset(&buf); + + if (virTestCompareToString(expected, actual) < 0) { + return -1; + } + + return 0; +} + + +static int +testNWFilterNFTablesTearNewRules(const void *opaque G_GNUC_UNUSED) +{ + g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; + const char *expected =3D + "nft -a list table bridge libvirt_nwfilter_ethernet\n" + "nft -a list table bridge libvirt_nwfilter_inet\n"\ + "nft delete chain bridge libvirt_nwfilter_ethernet n-vnet0-in\n" + "nft delete chain bridge libvirt_nwfilter_inet n-vnet0-in\n"; + g_autofree char *actual =3D NULL; + g_autoptr(virCommandDryRunToken) dryRunToken =3D virCommandDryRunToken= New(); + + virCommandSetDryRun(dryRunToken, &buf, false, true, testCommandDryRunC= allback, NULL); + + if (nftables_driver.tearNewRules("vnet0") < 0) + return -1; + + actual =3D virBufferContentAndReset(&buf); + + if (virTestCompareToString(expected, actual) < 0) { + return -1; + } + + return 0; +} + + +static int +testNWFilterNFTablesApplyBasicRules(const void *opaque G_GNUC_UNUSED) +{ + g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; + const char *expected =3D + "nft list tables\n" + OLD_REMOVES + "nft add chain bridge libvirt_nwfilter_ethernet vnet0-in '{ }'\n" + "nft add chain bridge libvirt_nwfilter_inet vnet0-in '{ }'\n" + "nft add chain bridge libvirt_nwfilter_ethernet vnet0-out '{ }'\n" + "nft add chain bridge libvirt_nwfilter_inet vnet0-out '{ }'\n" + "nft add rule bridge libvirt_nwfilter_ethernet vnet0-out ether sad= dr '!=3D' 10:20:30:40:50:60 drop\n" + "nft add rule bridge libvirt_nwfilter_ethernet vnet0-out ether typ= e ip accept\n" + "nft add rule bridge libvirt_nwfilter_ethernet vnet0-out ether typ= e arp accept\n" + "nft add rule bridge libvirt_nwfilter_ethernet vnet0-out accept\n" + "nft delete element bridge libvirt_nwfilter_inet vmap-oif '{' vnet= 0 '}'\n" + "nft add element bridge libvirt_nwfilter_inet vmap-oif '{' vnet0 := jump vnet0-in '}'\n" + "nft delete element bridge libvirt_nwfilter_ethernet vmap-oif '{' = vnet0 '}'\n" + "nft add element bridge libvirt_nwfilter_ethernet vmap-oif '{' vne= t0 : jump vnet0-in '}'\n" + "nft delete element bridge libvirt_nwfilter_inet vmap-iif '{' vnet= 0 '}'\n" + "nft add element bridge libvirt_nwfilter_inet vmap-iif '{' vnet0 := jump vnet0-out '}'\n" + "nft delete element bridge libvirt_nwfilter_ethernet vmap-iif '{' = vnet0 '}'\n" + "nft add element bridge libvirt_nwfilter_ethernet vmap-iif '{' vne= t0 : jump vnet0-out '}'\n"; + g_autofree char *actual =3D NULL; + virMacAddr mac =3D { .addr =3D { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 } = }; + g_autoptr(virCommandDryRunToken) dryRunToken =3D virCommandDryRunToken= New(); + + virCommandSetDryRun(dryRunToken, &buf, false, true, testCommandDryRunC= allback, NULL); + + if (nftables_driver.applyBasicRules("vnet0", &mac) < 0) + return -1; + + actual =3D virBufferContentAndReset(&buf); + + if (virTestCompareToString(expected, actual) < 0) { + return -1; + } + + return 0; +} + + +static int +testNWFilterNFTablesApplyDHCPOnlyRules(const void *opaque G_GNUC_UNUSED) +{ + g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; + const char *expected =3D + "nft list tables\n" + OLD_REMOVES + "nft add chain bridge libvirt_nwfilter_ethernet vnet0-in '{ }'\n" + "nft add chain bridge libvirt_nwfilter_inet vnet0-in '{ }'\n" + "nft add chain bridge libvirt_nwfilter_ethernet vnet0-out '{ }'\n" + "nft add chain bridge libvirt_nwfilter_inet vnet0-out '{ }'\n" + "nft add rule bridge libvirt_nwfilter_ethernet vnet0-out ether sad= dr 10:20:30:40:50:60 ether type ip udp sport 68 udp dport 67 accept\n" + "nft add rule bridge libvirt_nwfilter_ethernet vnet0-out drop\n" + "nft add rule bridge libvirt_nwfilter_ethernet vnet0-in ether dadd= r 10:20:30:40:50:60 ether type ip ip saddr 192.168.122.1 udp sport 67 udp d= port 68 accept\n" + "nft add rule bridge libvirt_nwfilter_ethernet vnet0-in ether dadd= r ff:ff:ff:ff:ff:ff ether type ip ip saddr 192.168.122.1 udp sport 67 udp d= port 68 accept\n" + "nft add rule bridge libvirt_nwfilter_ethernet vnet0-in ether dadd= r 10:20:30:40:50:60 ether type ip ip saddr 10.0.0.1 udp sport 67 udp dport = 68 accept\n" + "nft add rule bridge libvirt_nwfilter_ethernet vnet0-in ether dadd= r ff:ff:ff:ff:ff:ff ether type ip ip saddr 10.0.0.1 udp sport 67 udp dport = 68 accept\n" + "nft add rule bridge libvirt_nwfilter_ethernet vnet0-in ether dadd= r 10:20:30:40:50:60 ether type ip ip saddr 10.0.0.2 udp sport 67 udp dport = 68 accept\n" + "nft add rule bridge libvirt_nwfilter_ethernet vnet0-in ether dadd= r ff:ff:ff:ff:ff:ff ether type ip ip saddr 10.0.0.2 udp sport 67 udp dport = 68 accept\n" + "nft add rule bridge libvirt_nwfilter_ethernet vnet0-in drop\n" + "nft delete element bridge libvirt_nwfilter_inet vmap-oif '{' vnet= 0 '}'\n" + "nft add element bridge libvirt_nwfilter_inet vmap-oif '{' vnet0 := jump vnet0-in '}'\n" + "nft delete element bridge libvirt_nwfilter_ethernet vmap-oif '{' = vnet0 '}'\n" + "nft add element bridge libvirt_nwfilter_ethernet vmap-oif '{' vne= t0 : jump vnet0-in '}'\n" + "nft delete element bridge libvirt_nwfilter_inet vmap-iif '{' vnet= 0 '}'\n" + "nft add element bridge libvirt_nwfilter_inet vmap-iif '{' vnet0 := jump vnet0-out '}'\n" + "nft delete element bridge libvirt_nwfilter_ethernet vmap-iif '{' = vnet0 '}'\n" + "nft add element bridge libvirt_nwfilter_ethernet vmap-iif '{' vne= t0 : jump vnet0-out '}'\n"; + g_autofree char *actual =3D NULL; + virMacAddr mac =3D { .addr =3D { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 } = }; + const char *servers[] =3D { "192.168.122.1", "10.0.0.1", "10.0.0.2" }; + virNWFilterVarValue val =3D { + .valType =3D NWFILTER_VALUE_TYPE_ARRAY, + .u =3D { + .array =3D { + .values =3D (char **)servers, + .nValues =3D 3, + } + } + }; + g_autoptr(virCommandDryRunToken) dryRunToken =3D virCommandDryRunToken= New(); + + virCommandSetDryRun(dryRunToken, &buf, false, true, testCommandDryRunC= allback, NULL); + + if (nftables_driver.applyDHCPOnlyRules("vnet0", &mac, &val, false) < 0) + return -1; + + actual =3D virBufferContentAndReset(&buf); + + if (virTestCompareToString(expected, actual) < 0) { + return -1; + } + + return 0; +} + + + +static int +testNWFilterNFTablesApplyDropAllRules(const void *opaque G_GNUC_UNUSED) +{ + g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; + const char *expected =3D + "nft list tables\n" + OLD_REMOVES + "nft add chain bridge libvirt_nwfilter_ethernet vnet0-in '{ }'\n" + "nft add chain bridge libvirt_nwfilter_inet vnet0-in '{ }'\n" + "nft add chain bridge libvirt_nwfilter_ethernet vnet0-out '{ }'\n" + "nft add chain bridge libvirt_nwfilter_inet vnet0-out '{ }'\n" + "nft add rule bridge libvirt_nwfilter_ethernet vnet0-out drop\n" + "nft add rule bridge libvirt_nwfilter_ethernet vnet0-in drop\n" + "nft add rule bridge libvirt_nwfilter_ethernet postrouting oifname= vnet0 jump vnet0-in\n" + "nft add rule bridge libvirt_nwfilter_ethernet prerouting iifname = vnet0 jump vnet0-out\n"; + g_autofree char *actual =3D NULL; + g_autoptr(virCommandDryRunToken) dryRunToken =3D virCommandDryRunToken= New(); + + virCommandSetDryRun(dryRunToken, &buf, false, true, testCommandDryRunC= allback, NULL); + + if (nftables_driver.applyDropAllRules("vnet0") < 0) + return -1; + + actual =3D virBufferContentAndReset(&buf); + + if (virTestCompareToString(expected, actual) < 0) { + return -1; + } + + return 0; +} + + +static int +mymain(void) +{ + int ret =3D 0; + + if (virTestRun("nftablesAllTeardown", + testNWFilterNFTablesAllTeardown, + NULL) < 0) + ret =3D -1; + + if (virTestRun("nftablesTearOldRules", + testNWFilterNFTablesTearOldRules, + NULL) < 0) + ret =3D -1; + + if (virTestRun("nftablesRemoveBasicRules", + testNWFilterNFTablesRemoveBasicRules, + NULL) < 0) + ret =3D -1; + + if (virTestRun("nftablesTearNewRules", + testNWFilterNFTablesTearNewRules, + NULL) < 0) + ret =3D -1; + + if (virTestRun("nftablesApplyBasicRules", + testNWFilterNFTablesApplyBasicRules, + NULL) < 0) + ret =3D -1; + + if (virTestRun("nftablesApplyDHCPOnlyRules", + testNWFilterNFTablesApplyDHCPOnlyRules, + NULL) < 0) + ret =3D -1; + + if (virTestRun("nftablesApplyDropAllRules", + testNWFilterNFTablesApplyDropAllRules, + NULL) < 0) + ret =3D -1; + + return ret =3D=3D 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIR_TEST_MAIN_PRELOAD(mymain, VIR_TEST_MOCK("virfirewall")) diff --git a/tests/nwfilterxml2firewalldata/ah-ipv6-linux.nftables.args b/t= ests/nwfilterxml2firewalldata/ah-ipv6-linux.nftables.args new file mode 100755 index 0000000000..702614bac9 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/ah-ipv6-linux.nftables.args @@ -0,0 +1,298 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +ah \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +f:e:d::c:b:a/127 \ +ip6 \ +daddr \ +a:b:c::d:e:f/128 \ +ip6 \ +dscp \ +2 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +ah \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +f:e:d::c:b:a/127 \ +ip6 \ +saddr \ +a:b:c::d:e:f/128 \ +ip6 \ +dscp \ +2 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +ah \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +ah \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +ah \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +::ffff:10.1.2.3/128 \ +ip6 \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +ah \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +::ffff:10.1.2.3/128 \ +ip6 \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/ah-linux.nftables.args b/tests/= nwfilterxml2firewalldata/ah-linux.nftables.args new file mode 100755 index 0000000000..2e123974b7 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/ah-linux.nftables.args @@ -0,0 +1,292 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +ah \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +ah \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +ah \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +ah \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +ah \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +ah \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/all-ipv6-linux.nftables.args b/= tests/nwfilterxml2firewalldata/all-ipv6-linux.nftables.args new file mode 100755 index 0000000000..f0fd014554 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/all-ipv6-linux.nftables.args @@ -0,0 +1,280 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +f:e:d::c:b:a/127 \ +ip6 \ +daddr \ +a:b:c::d:e:f/128 \ +ip6 \ +dscp \ +2 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +f:e:d::c:b:a/127 \ +ip6 \ +saddr \ +a:b:c::d:e:f/128 \ +ip6 \ +dscp \ +2 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +::ffff:10.1.2.3/128 \ +ip6 \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +::ffff:10.1.2.3/128 \ +ip6 \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/all-linux.nftables.args b/tests= /nwfilterxml2firewalldata/all-linux.nftables.args new file mode 100755 index 0000000000..b4e98c21de --- /dev/null +++ b/tests/nwfilterxml2firewalldata/all-linux.nftables.args @@ -0,0 +1,274 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/arp-linux.nftables.args b/tests= /nwfilterxml2firewalldata/arp-linux.nftables.args new file mode 100755 index 0000000000..9bad9955ac --- /dev/null +++ b/tests/nwfilterxml2firewalldata/arp-linux.nftables.args @@ -0,0 +1,285 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +0x806 \ +arp \ +htype \ +12 \ +arp \ +ptype \ +0x22 \ +arp \ +operation \ +1 \ +arp \ +saddr \ +ether \ +01:02:03:04:05:06 \ +arp \ +daddr \ +ether \ +0a:0b:0c:0d:0e:0f \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +type \ +0x806 \ +arp \ +htype \ +255 \ +arp \ +ptype \ +0xff \ +arp \ +operation \ +1 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +type \ +0x806 \ +arp \ +htype \ +256 \ +arp \ +ptype \ +0x100 \ +arp \ +operation \ +11 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +type \ +0x806 \ +arp \ +htype \ +65535 \ +arp \ +ptype \ +0xffff \ +arp \ +operation \ +65535 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +type \ +0x806 \ +arp \ +saddr \ +ip \ +'&' \ +255.0.0.0 \ +. \ +arp \ +daddr \ +ip \ +'&' \ +255.0.0.0 \ +=3D=3D \ +@same-ip-set \ +arp \ +saddr \ +ip \ +'&' \ +0.255.0.0 \ +. \ +arp \ +daddr \ +ip \ +'&' \ +0.255.0.0 \ +=3D=3D \ +@same-ip-set \ +arp \ +saddr \ +ip \ +'&' \ +0.0.255.0 \ +. \ +arp \ +daddr \ +ip \ +'&' \ +0.0.255.0 \ +=3D=3D \ +@same-ip-set \ +arp \ +saddr \ +ip \ +'&' \ +0.0.0.255 \ +. \ +arp \ +daddr \ +ip \ +'&' \ +0.0.0.255 \ +=3D=3D \ +@same-ip-set \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/comment-linux.nftables.args b/t= ests/nwfilterxml2firewalldata/comment-linux.nftables.args new file mode 100755 index 0000000000..f19f865fd8 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/comment-linux.nftables.args @@ -0,0 +1,502 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +type \ +0x1234 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +protocol \ +17 \ +th \ +sport \ +291-564 \ +th \ +dport \ +13398-17767 \ +ip \ +dscp \ +0x32 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:fe =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:80 =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +ip6 \ +ip6 \ +saddr \ +::ffff:10.1.2.3/22 \ +ip6 \ +daddr \ +::ffff:10.1.2.3/113 \ +ip6 \ +nexthdr \ +6 \ +th \ +sport \ +273-400 \ +th \ +dport \ +13107-65535 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +0x806 \ +arp \ +htype \ +18 \ +arp \ +ptype \ +0x56 \ +arp \ +operation \ +1 \ +arp \ +saddr \ +ether \ +01:02:03:04:05:06 \ +arp \ +daddr \ +ether \ +0a:0b:0c:0d:0e:0f \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +34 \ +udp \ +dport \ +564-1092 \ +udp \ +sport \ +291-400 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept \ +comment \ +'"usercomment=3Dudp rule"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +34 \ +udp \ +sport \ +564-1092 \ +udp \ +dport \ +291-400 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept \ +comment \ +'"usercomment=3Dudp rule"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +tcp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +57 \ +tcp \ +dport \ +256-4369 \ +tcp \ +sport \ +32-33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept \ +comment \ +'"usercomment=3Dtcp/ipv6 rule"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +tcp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +57 \ +tcp \ +sport \ +256-4369 \ +tcp \ +dport \ +32-33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept \ +comment \ +'"usercomment=3Dtcp/ipv6 rule"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +udp \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept \ +comment \ +'"usercomment=3D`ls`;${COLUMNS};$(ls);'\''test'\'';&'\''3 spaces'\''"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +udp \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept \ +comment \ +'"usercomment=3D`ls`;${COLUMNS};$(ls);'\''test'\'';&'\''3 spaces'\''"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +sctp \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept \ +comment \ +'"usercomment=3Dcomment with lone '\'', `, '\'', `, \, $x, and two spaces= "' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +sctp \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept \ +comment \ +'"usercomment=3Dcomment with lone '\'', `, '\'', `, \, $x, and two spaces= "' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +ah \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept \ +comment \ +'"usercomment=3Dtmp=3D`mktemp`; echo ${RANDOM} > ${tmp} ; cat < ${tmp}; rm= -f ${tmp}"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +ah \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept \ +comment \ +'"usercomment=3Dtmp=3D`mktemp`; echo ${RANDOM} > ${tmp} ; cat < ${tmp}; rm= -f ${tmp}"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/conntrack-linux.nftables.args b= /tests/nwfilterxml2firewalldata/conntrack-linux.nftables.args new file mode 100755 index 0000000000..46a3ec7f25 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/conntrack-linux.nftables.args @@ -0,0 +1,190 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +ct \ +count \ +over \ +1 \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ct \ +count \ +over \ +2 \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/esp-ipv6-linux.nftables.args b/= tests/nwfilterxml2firewalldata/esp-ipv6-linux.nftables.args new file mode 100755 index 0000000000..184d0d2ae5 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/esp-ipv6-linux.nftables.args @@ -0,0 +1,298 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +esp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +f:e:d::c:b:a/127 \ +ip6 \ +daddr \ +a:b:c::d:e:f/128 \ +ip6 \ +dscp \ +2 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +esp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +f:e:d::c:b:a/127 \ +ip6 \ +saddr \ +a:b:c::d:e:f/128 \ +ip6 \ +dscp \ +2 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +esp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +esp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +esp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +::ffff:10.1.2.3/128 \ +ip6 \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +esp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +::ffff:10.1.2.3/128 \ +ip6 \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/esp-linux.nftables.args b/tests= /nwfilterxml2firewalldata/esp-linux.nftables.args new file mode 100755 index 0000000000..fc1df1f3bb --- /dev/null +++ b/tests/nwfilterxml2firewalldata/esp-linux.nftables.args @@ -0,0 +1,292 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +esp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +esp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +esp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +esp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +esp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +esp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/example-1-linux.nftables.args b= /tests/nwfilterxml2firewalldata/example-1-linux.nftables.args new file mode 100755 index 0000000000..a501a4fa50 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/example-1-linux.nftables.args @@ -0,0 +1,252 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +dport \ +22 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +sport \ +22 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/example-2-linux.nftables.args b= /tests/nwfilterxml2firewalldata/example-2-linux.nftables.args new file mode 100755 index 0000000000..e8a082dc74 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/example-2-linux.nftables.args @@ -0,0 +1,352 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ct \ +direction \ +original \ +ct \ +state \ +established,related \ +accept \ +comment \ +'"usercomment=3Dout: existing and related (ftp) connections"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ct \ +direction \ +reply \ +ct \ +state \ +established,related \ +accept \ +comment \ +'"usercomment=3Dout: existing and related (ftp) connections"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ct \ +direction \ +original \ +ct \ +state \ +established \ +accept \ +comment \ +'"usercomment=3Din: existing connections"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept \ +comment \ +'"usercomment=3Din: existing connections"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +dport \ +21-22 \ +ct \ +direction \ +original \ +ct \ +state \ +new \ +accept \ +comment \ +'"usercomment=3Din: ftp and ssh"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +sport \ +21-22 \ +ct \ +direction \ +reply \ +ct \ +state \ +new \ +accept \ +comment \ +'"usercomment=3Din: ftp and ssh"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +ct \ +state \ +new \ +accept \ +comment \ +'"usercomment=3Din: icmp"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +ct \ +state \ +new \ +accept \ +comment \ +'"usercomment=3Din: icmp"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +udp \ +dport \ +53 \ +ct \ +direction \ +original \ +ct \ +state \ +new \ +accept \ +comment \ +'"usercomment=3Dout: DNS lookups"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +udp \ +sport \ +53 \ +ct \ +direction \ +reply \ +ct \ +state \ +new \ +accept \ +comment \ +'"usercomment=3Dout: DNS lookups"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +drop \ +comment \ +'"usercomment=3Dinout: drop all non-accepted traffic"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +drop \ +comment \ +'"usercomment=3Dinout: drop all non-accepted traffic"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/hex-data-linux.nftables.args b/= tests/nwfilterxml2firewalldata/hex-data-linux.nftables.args new file mode 100755 index 0000000000..b41d7811bb --- /dev/null +++ b/tests/nwfilterxml2firewalldata/hex-data-linux.nftables.args @@ -0,0 +1,368 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +type \ +0x1234 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +protocol \ +17 \ +th \ +sport \ +291-564 \ +th \ +dport \ +13398-17767 \ +ip \ +dscp \ +0x32 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:fe =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:80 =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +ip6 \ +ip6 \ +saddr \ +::ffff:10.1.2.3/22 \ +ip6 \ +daddr \ +::ffff:10.1.2.3/113 \ +ip6 \ +nexthdr \ +6 \ +th \ +sport \ +273-400 \ +th \ +dport \ +13107-65535 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +0x806 \ +arp \ +htype \ +18 \ +arp \ +ptype \ +0x56 \ +arp \ +operation \ +1 \ +arp \ +saddr \ +ether \ +01:02:03:04:05:06 \ +arp \ +daddr \ +ether \ +0a:0b:0c:0d:0e:0f \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +34 \ +udp \ +dport \ +564-1092 \ +udp \ +sport \ +291-400 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +34 \ +udp \ +sport \ +564-1092 \ +udp \ +dport \ +291-400 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +tcp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +57 \ +tcp \ +dport \ +256-4369 \ +tcp \ +sport \ +32-33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +tcp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +57 \ +tcp \ +sport \ +256-4369 \ +tcp \ +dport \ +32-33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/icmp-direction-linux.nftables.a= rgs b/tests/nwfilterxml2firewalldata/icmp-direction-linux.nftables.args new file mode 100755 index 0000000000..4202de5e0f --- /dev/null +++ b/tests/nwfilterxml2firewalldata/icmp-direction-linux.nftables.args @@ -0,0 +1,226 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +icmp \ +type \ +0 \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +icmp \ +type \ +0 \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +icmp \ +type \ +8 \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +icmp \ +type \ +8 \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/icmp-direction2-linux.nftables.= args b/tests/nwfilterxml2firewalldata/icmp-direction2-linux.nftables.args new file mode 100755 index 0000000000..50ba9b7ebf --- /dev/null +++ b/tests/nwfilterxml2firewalldata/icmp-direction2-linux.nftables.args @@ -0,0 +1,226 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +icmp \ +type \ +8 \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +icmp \ +type \ +8 \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +icmp \ +type \ +0 \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +icmp \ +type \ +0 \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/icmp-direction3-linux.nftables.= args b/tests/nwfilterxml2firewalldata/icmp-direction3-linux.nftables.args new file mode 100755 index 0000000000..5483994207 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/icmp-direction3-linux.nftables.args @@ -0,0 +1,176 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/icmp-linux.nftables.args b/test= s/nwfilterxml2firewalldata/icmp-linux.nftables.args new file mode 100755 index 0000000000..e436fc0acf --- /dev/null +++ b/tests/nwfilterxml2firewalldata/icmp-linux.nftables.args @@ -0,0 +1,248 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +icmp \ +type \ +12 \ +icmp \ +code \ +11 \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +icmp \ +type \ +12 \ +icmp \ +code \ +11 \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +icmp \ +type \ +255 \ +icmp \ +code \ +255 \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ip \ +protocol \ +icmp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +icmp \ +type \ +255 \ +icmp \ +code \ +255 \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/icmpv6-linux.nftables.args b/te= sts/nwfilterxml2firewalldata/icmpv6-linux.nftables.args new file mode 100755 index 0000000000..aeae3dd3e7 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/icmpv6-linux.nftables.args @@ -0,0 +1,316 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +ip6 \ +nexthdr \ +icmpv6 \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +f:e:d::c:b:a/127 \ +ip6 \ +daddr \ +a:b:c::d:e:f/128 \ +ip6 \ +dscp \ +2 \ +icmpv6 \ +type \ +12 \ +icmpv6 \ +code \ +11 \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +ip6 \ +nexthdr \ +icmpv6 \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +f:e:d::c:b:a/127 \ +ip6 \ +saddr \ +a:b:c::d:e:f/128 \ +ip6 \ +dscp \ +2 \ +icmpv6 \ +type \ +12 \ +icmpv6 \ +code \ +11 \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +ip6 \ +nexthdr \ +icmpv6 \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +33 \ +icmpv6 \ +type \ +255 \ +icmpv6 \ +code \ +255 \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +ip6 \ +nexthdr \ +icmpv6 \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +33 \ +icmpv6 \ +type \ +255 \ +icmpv6 \ +code \ +255 \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +ip6 \ +nexthdr \ +icmpv6 \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +::ffff:10.1.2.3/128 \ +ip6 \ +dscp \ +33 \ +icmpv6 \ +type \ +255 \ +icmpv6 \ +code \ +255 \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +ip6 \ +nexthdr \ +icmpv6 \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +::ffff:10.1.2.3/128 \ +ip6 \ +dscp \ +33 \ +icmpv6 \ +type \ +255 \ +icmpv6 \ +code \ +255 \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/igmp-linux.nftables.args b/test= s/nwfilterxml2firewalldata/igmp-linux.nftables.args new file mode 100755 index 0000000000..f148504685 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/igmp-linux.nftables.args @@ -0,0 +1,292 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +igmp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +igmp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +igmp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +igmp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +igmp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +igmp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/ip-linux.nftables.args b/tests/= nwfilterxml2firewalldata/ip-linux.nftables.args new file mode 100755 index 0000000000..eee7a4b4af --- /dev/null +++ b/tests/nwfilterxml2firewalldata/ip-linux.nftables.args @@ -0,0 +1,199 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +protocol \ +17 \ +th \ +sport \ +20-22 \ +th \ +dport \ +100-101 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ip \ +saddr \ +10.1.2.3/17 \ +ip \ +daddr \ +10.1.2.3/24 \ +ip \ +protocol \ +17 \ +ip \ +dscp \ +0x3f \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ip \ +saddr \ +10.1.2.3/31 \ +ip \ +daddr \ +10.1.2.3/25 \ +ip \ +protocol \ +255 \ +ip \ +dscp \ +0x3f \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/ipt-no-macspoof-linux.nftables.= args b/tests/nwfilterxml2firewalldata/ipt-no-macspoof-linux.nftables.args new file mode 100755 index 0000000000..0611160fc8 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/ipt-no-macspoof-linux.nftables.args @@ -0,0 +1,166 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ether \ +saddr \ +'!=3D' \ +12:34:56:78:9a:bc \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ether \ +saddr \ +'!=3D' \ +12:34:56:78:9a:bc \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ether \ +saddr \ +'!=3D' \ +aa:aa:aa:aa:aa:aa \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/ipv6-linux.nftables.args b/test= s/nwfilterxml2firewalldata/ipv6-linux.nftables.args new file mode 100755 index 0000000000..1f933bdc57 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/ipv6-linux.nftables.args @@ -0,0 +1,481 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:fe =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:80 =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +ip6 \ +ip6 \ +saddr \ +::ffff:10.1.2.3/22 \ +ip6 \ +daddr \ +::ffff:10.1.2.3/113 \ +ip6 \ +nexthdr \ +17 \ +th \ +sport \ +20-22 \ +th \ +dport \ +100-101 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +ip6 \ +saddr \ +1::2/128 \ +ip6 \ +daddr \ +a:b:c::/65 \ +ip6 \ +nexthdr \ +6 \ +th \ +sport \ +20-22 \ +th \ +dport \ +100-101 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +ip6 \ +daddr \ +1::2/128 \ +ip6 \ +saddr \ +a:b:c::/65 \ +ip6 \ +nexthdr \ +6 \ +th \ +dport \ +20-22 \ +th \ +sport \ +100-101 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +ip6 \ +saddr \ +1::2/128 \ +ip6 \ +daddr \ +a:b:c::/65 \ +ip6 \ +nexthdr \ +6 \ +th \ +sport \ +255-256 \ +th \ +dport \ +65535-65535 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +ip6 \ +daddr \ +1::2/128 \ +ip6 \ +saddr \ +a:b:c::/65 \ +ip6 \ +nexthdr \ +6 \ +th \ +dport \ +255-256 \ +th \ +sport \ +65535-65535 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +ip6 \ +saddr \ +1::2/128 \ +ip6 \ +daddr \ +a:b:c::/65 \ +ip6 \ +nexthdr \ +18 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +ip6 \ +daddr \ +1::2/128 \ +ip6 \ +saddr \ +a:b:c::/65 \ +ip6 \ +nexthdr \ +18 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +ip6 \ +saddr \ +1::2/128 \ +ip6 \ +daddr \ +a:b:c::/65 \ +ip6 \ +nexthdr \ +58 \ +icmpv6 \ +type \ +1 \ +icmpv6 \ +code \ +10 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +ip6 \ +daddr \ +1::2/128 \ +ip6 \ +saddr \ +a:b:c::/65 \ +ip6 \ +nexthdr \ +58 \ +icmpv6 \ +type \ +1 \ +icmpv6 \ +code \ +10 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +ip6 \ +saddr \ +1::2/128 \ +ip6 \ +daddr \ +a:b:c::/65 \ +ip6 \ +nexthdr \ +58 \ +icmpv6 \ +type \ +1 \ +icmpv6 \ +code \ +10 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +ip6 \ +daddr \ +1::2/128 \ +ip6 \ +saddr \ +a:b:c::/65 \ +ip6 \ +nexthdr \ +58 \ +icmpv6 \ +type \ +1 \ +icmpv6 \ +code \ +10 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +ip6 \ +saddr \ +1::2/128 \ +ip6 \ +daddr \ +a:b:c::/65 \ +ip6 \ +nexthdr \ +58 \ +icmpv6 \ +code \ +10 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +ip6 \ +daddr \ +1::2/128 \ +ip6 \ +saddr \ +a:b:c::/65 \ +ip6 \ +nexthdr \ +58 \ +icmpv6 \ +code \ +10 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +ip6 \ +saddr \ +1::2/128 \ +ip6 \ +daddr \ +a:b:c::/65 \ +ip6 \ +nexthdr \ +58 \ +icmpv6 \ +type \ +1 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +ip6 \ +daddr \ +1::2/128 \ +ip6 \ +saddr \ +a:b:c::/65 \ +ip6 \ +nexthdr \ +58 \ +icmpv6 \ +type \ +1 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/iter1-linux.nftables.args b/tes= ts/nwfilterxml2firewalldata/iter1-linux.nftables.args new file mode 100755 index 0000000000..8c62640e95 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/iter1-linux.nftables.args @@ -0,0 +1,292 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +2 \ +tcp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +2 \ +tcp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +2 \ +tcp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +2 \ +tcp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +2 \ +tcp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +2 \ +tcp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/iter2-linux.nftables.args b/tes= ts/nwfilterxml2firewalldata/iter2-linux.nftables.args new file mode 100755 index 0000000000..aa81c7a357 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/iter2-linux.nftables.args @@ -0,0 +1,3532 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +1 \ +tcp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +1 \ +tcp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +1 \ +tcp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +1 \ +tcp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +1 \ +tcp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +1 \ +tcp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +2 \ +udp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +2 \ +udp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +2 \ +udp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +2 \ +udp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +2 \ +udp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +2 \ +udp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +2 \ +udp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +2 \ +udp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +2 \ +udp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +2 \ +udp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +2 \ +udp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +2 \ +udp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +3 \ +sctp \ +dport \ +1080 \ +sctp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +3 \ +sctp \ +sport \ +1080 \ +sctp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +3 \ +sctp \ +dport \ +1080 \ +sctp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +3 \ +sctp \ +sport \ +1080 \ +sctp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +3 \ +sctp \ +dport \ +1080 \ +sctp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +3 \ +sctp \ +sport \ +1080 \ +sctp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +3 \ +sctp \ +dport \ +1090 \ +sctp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +3 \ +sctp \ +sport \ +1090 \ +sctp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +3 \ +sctp \ +dport \ +1090 \ +sctp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +3 \ +sctp \ +sport \ +1090 \ +sctp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +3 \ +sctp \ +dport \ +1090 \ +sctp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +3 \ +sctp \ +sport \ +1090 \ +sctp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +3 \ +sctp \ +dport \ +1100 \ +sctp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +3 \ +sctp \ +sport \ +1100 \ +sctp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +3 \ +sctp \ +dport \ +1100 \ +sctp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +3 \ +sctp \ +sport \ +1100 \ +sctp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +3 \ +sctp \ +dport \ +1100 \ +sctp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +3 \ +sctp \ +sport \ +1100 \ +sctp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +3 \ +sctp \ +dport \ +1110 \ +sctp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +3 \ +sctp \ +sport \ +1110 \ +sctp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +3 \ +sctp \ +dport \ +1110 \ +sctp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +3 \ +sctp \ +sport \ +1110 \ +sctp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +3 \ +sctp \ +dport \ +1110 \ +sctp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +3 \ +sctp \ +sport \ +1110 \ +sctp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1080 \ +tcp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1080 \ +tcp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1080 \ +tcp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1080 \ +tcp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1080 \ +tcp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1080 \ +tcp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1080 \ +tcp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1080 \ +tcp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1080 \ +tcp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1080 \ +tcp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1080 \ +tcp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1080 \ +tcp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1090 \ +tcp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1090 \ +tcp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1090 \ +tcp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1090 \ +tcp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1090 \ +tcp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1090 \ +tcp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1090 \ +tcp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1090 \ +tcp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1090 \ +tcp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1090 \ +tcp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1090 \ +tcp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1090 \ +tcp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1100 \ +tcp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1100 \ +tcp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1100 \ +tcp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1100 \ +tcp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1100 \ +tcp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1100 \ +tcp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1100 \ +tcp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1100 \ +tcp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1100 \ +tcp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1100 \ +tcp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1100 \ +tcp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1100 \ +tcp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1110 \ +tcp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1110 \ +tcp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1110 \ +tcp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1110 \ +tcp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1110 \ +tcp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1110 \ +tcp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1110 \ +tcp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1110 \ +tcp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1110 \ +tcp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1110 \ +tcp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +4 \ +tcp \ +dport \ +1110 \ +tcp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +4 \ +tcp \ +sport \ +1110 \ +tcp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +5 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +6 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +6 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +6 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +6 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +dscp \ +6 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +daddr \ +3.3.3.3 \ +ip \ +saddr \ +3.3.3.3 \ +ip \ +dscp \ +6 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/iter3-linux.nftables.args b/tes= ts/nwfilterxml2firewalldata/iter3-linux.nftables.args new file mode 100755 index 0000000000..6c5b4cfd7d --- /dev/null +++ b/tests/nwfilterxml2firewalldata/iter3-linux.nftables.args @@ -0,0 +1,410 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +1 \ +tcp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +1 \ +tcp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +saddr \ +1.1.1.1 \ +ip \ +dscp \ +1 \ +tcp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ip \ +daddr \ +1.1.1.1 \ +ip \ +dscp \ +1 \ +tcp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +2 \ +udp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +2 \ +udp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +2 \ +udp \ +sport \ +90 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +2 \ +udp \ +dport \ +90 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +saddr \ +2.2.2.2 \ +ip \ +dscp \ +3 \ +sctp \ +dport \ +1100 \ +sctp \ +sport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ip \ +daddr \ +2.2.2.2 \ +ip \ +dscp \ +3 \ +sctp \ +sport \ +1100 \ +sctp \ +dport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/mac-linux.nftables.args b/tests= /nwfilterxml2firewalldata/mac-linux.nftables.args new file mode 100755 index 0000000000..81eac763af --- /dev/null +++ b/tests/nwfilterxml2firewalldata/mac-linux.nftables.args @@ -0,0 +1,176 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +type \ +0x806 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +0x800 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +0x600 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +0xffff \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/rarp-linux.nftables.args b/test= s/nwfilterxml2firewalldata/rarp-linux.nftables.args new file mode 100755 index 0000000000..015c1d6c74 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/rarp-linux.nftables.args @@ -0,0 +1,207 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +0x8035 \ +@nh,0,16 \ +0xc \ +@nh,40,16 \ +0x22 \ +@nh,48,16 \ +0x1 \ +@nh,64,48 \ +0x010203040506 \ +@nh,144,48 \ +0x0a0b0c0d0e0f \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +type \ +0x8035 \ +@nh,0,16 \ +0xff \ +@nh,40,16 \ +0xff \ +@nh,48,16 \ +0x1 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +type \ +0x8035 \ +@nh,0,16 \ +0x100 \ +@nh,40,16 \ +0x100 \ +@nh,48,16 \ +0xb \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +type \ +0x8035 \ +@nh,0,16 \ +0xffff \ +@nh,40,16 \ +0xffff \ +@nh,48,16 \ +0xffff \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/sctp-ipv6-linux.nftables.args b= /tests/nwfilterxml2firewalldata/sctp-ipv6-linux.nftables.args new file mode 100755 index 0000000000..6be5973e7e --- /dev/null +++ b/tests/nwfilterxml2firewalldata/sctp-ipv6-linux.nftables.args @@ -0,0 +1,316 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +sctp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +a:b:c::d:e:f/128 \ +ip6 \ +dscp \ +2 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +sctp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +a:b:c::d:e:f/128 \ +ip6 \ +dscp \ +2 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +sctp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +33 \ +sctp \ +dport \ +100-1111 \ +sctp \ +sport \ +20-21 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +sctp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +33 \ +sctp \ +sport \ +100-1111 \ +sctp \ +dport \ +20-21 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +sctp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +::ffff:10.1.2.3/128 \ +ip6 \ +dscp \ +63 \ +sctp \ +dport \ +65535-65535 \ +sctp \ +sport \ +255-256 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +sctp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +::ffff:10.1.2.3/128 \ +ip6 \ +dscp \ +63 \ +sctp \ +sport \ +65535-65535 \ +sctp \ +dport \ +255-256 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/sctp-linux.nftables.args b/test= s/nwfilterxml2firewalldata/sctp-linux.nftables.args new file mode 100755 index 0000000000..b414d05022 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/sctp-linux.nftables.args @@ -0,0 +1,316 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +33 \ +sctp \ +dport \ +100-1111 \ +sctp \ +sport \ +20-21 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +33 \ +sctp \ +sport \ +100-1111 \ +sctp \ +dport \ +20-21 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +63 \ +sctp \ +dport \ +65535-65535 \ +sctp \ +sport \ +255-256 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +sctp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +63 \ +sctp \ +sport \ +65535-65535 \ +sctp \ +dport \ +255-256 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/stp-linux.nftables.args b/tests= /nwfilterxml2firewalldata/stp-linux.nftables.args new file mode 100644 index 0000000000..4dabd3cbc2 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/stp-linux.nftables.args @@ -0,0 +1,233 @@ +nft \ +add \ +chain \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-stp-xyz-in \ +'{ }' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +daddr \ +01:80:c2:00:00:00 \ +jump \ +n-vnet0-stp-xyz-in +nft \ +add \ +chain \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-stp-xyz-out \ +'{ }' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +daddr \ +01:80:c2:00:00:00 \ +jump \ +n-vnet0-stp-xyz-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-stp-xyz-in \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +01:80:c2:00:00:00 \ +@nh,48,8 \ +0x12 \ +@nh,56,8 \ +0x44 \ +continue +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-stp-xyz-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +01:80:c2:00:00:00 \ +@nh,64,16 \ +'!=3D' \ +0x1234-0x2345 \ +@nh,80,48 \ +'&' \ +0x060504030201 \ +0x060504030201 \ +@nh,128,32 \ +'!=3D' \ +0x11223344-0x22334455 \ +return +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-stp-xyz-in \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +01:80:c2:00:00:00 \ +@nh,160,16 \ +'!=3D' \ +0x1234 \ +@nh,176,48 \ +0x060504030201 \ +@nh,224,16 \ +'!=3D' \ +0x7b-0xea \ +@nh,240,16 \ +'!=3D' \ +0x15a8-0x15b3 \ +@nh,256,16 \ +'!=3D' \ +0x1e61-0x22b8 \ +@nh,272,16 \ +'!=3D' \ +0x3039-0x303a \ +@nh,288,16 \ +'!=3D' \ +0xd431-0xff98 \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/target-linux.nftables.args b/te= sts/nwfilterxml2firewalldata/target-linux.nftables.args new file mode 100755 index 0000000000..fa323e8b58 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/target-linux.nftables.args @@ -0,0 +1,454 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept \ +comment \ +'"usercomment=3Daccept rule -- dir out"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept \ +comment \ +'"usercomment=3Daccept rule -- dir out"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +drop \ +comment \ +'"usercomment=3Ddrop rule -- dir out"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +drop \ +comment \ +'"usercomment=3Dreject rule -- dir out"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept \ +comment \ +'"usercomment=3Daccept rule -- dir in"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept \ +comment \ +'"usercomment=3Daccept rule -- dir in"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +drop \ +comment \ +'"usercomment=3Ddrop rule -- dir in"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +drop \ +comment \ +'"usercomment=3Dreject rule -- dir in"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept \ +comment \ +'"usercomment=3Daccept rule -- dir inout"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept \ +comment \ +'"usercomment=3Daccept rule -- dir inout"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +drop \ +comment \ +'"usercomment=3Ddrop rule -- dir inout"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +drop \ +comment \ +'"usercomment=3Dreject rule -- dir inout"' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +type \ +0x806 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +type \ +0x806 \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +type \ +0x806 \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +0x800 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +0x800 \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +0x800 \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/target2-linux.nftables.args b/t= ests/nwfilterxml2firewalldata/target2-linux.nftables.args new file mode 100755 index 0000000000..04cc52c06f --- /dev/null +++ b/tests/nwfilterxml2firewalldata/target2-linux.nftables.args @@ -0,0 +1,302 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +dport \ +22 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +sport \ +22 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +sport \ +22 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +dport \ +22 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +dport \ +80 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +sport \ +80 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/tcp-ipv6-linux.nftables.args b/= tests/nwfilterxml2firewalldata/tcp-ipv6-linux.nftables.args new file mode 100755 index 0000000000..1d7c8e844a --- /dev/null +++ b/tests/nwfilterxml2firewalldata/tcp-ipv6-linux.nftables.args @@ -0,0 +1,316 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +tcp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +a:b:c::d:e:f/128 \ +ip6 \ +dscp \ +2 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +tcp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +a:b:c::d:e:f/128 \ +ip6 \ +dscp \ +2 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +tcp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +33 \ +tcp \ +dport \ +100-1111 \ +tcp \ +sport \ +20-21 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +tcp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +33 \ +tcp \ +sport \ +100-1111 \ +tcp \ +dport \ +20-21 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +tcp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +::ffff:10.1.2.3/128 \ +ip6 \ +dscp \ +63 \ +tcp \ +dport \ +65535-65535 \ +tcp \ +sport \ +255-256 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +tcp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +::ffff:10.1.2.3/128 \ +ip6 \ +dscp \ +63 \ +tcp \ +sport \ +65535-65535 \ +tcp \ +dport \ +255-256 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/tcp-linux.nftables.args b/tests= /nwfilterxml2firewalldata/tcp-linux.nftables.args new file mode 100755 index 0000000000..770fc7bb0c --- /dev/null +++ b/tests/nwfilterxml2firewalldata/tcp-linux.nftables.args @@ -0,0 +1,452 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +33 \ +tcp \ +dport \ +100-1111 \ +tcp \ +sport \ +20-21 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +63 \ +tcp \ +dport \ +65535-65535 \ +tcp \ +sport \ +255-256 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +flags \ +'&' \ +syn \ +=3D=3D \ +'{' \ +'*' \ +'}' \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +flags \ +'&' \ +syn \ +=3D=3D \ +'{' \ +'*' \ +'}' \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +flags \ +'&' \ +syn \ +=3D=3D \ +'{' \ +syn,ack \ +'}' \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +flags \ +'&' \ +syn \ +=3D=3D \ +'{' \ +syn,ack \ +'}' \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +flags \ +'&' \ +rst \ +=3D=3D \ +'{' \ +0 \ +'}' \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +flags \ +'&' \ +rst \ +=3D=3D \ +'{' \ +0 \ +'}' \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +flags \ +'&' \ +psh \ +=3D=3D \ +'{' \ +0 \ +'}' \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +tcp \ +tcp \ +flags \ +'&' \ +psh \ +=3D=3D \ +'{' \ +0 \ +'}' \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/udp-ipv6-linux.nftables.args b/= tests/nwfilterxml2firewalldata/udp-ipv6-linux.nftables.args new file mode 100755 index 0000000000..476e38c4f2 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/udp-ipv6-linux.nftables.args @@ -0,0 +1,316 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +udp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +a:b:c::d:e:f/128 \ +ip6 \ +dscp \ +2 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +udp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +a:b:c::d:e:f/128 \ +ip6 \ +dscp \ +2 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +udp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +::a:b:c/128 \ +ip6 \ +dscp \ +33 \ +udp \ +dport \ +100-1111 \ +udp \ +sport \ +20-21 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +udp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +::a:b:c/128 \ +ip6 \ +dscp \ +33 \ +udp \ +sport \ +100-1111 \ +udp \ +dport \ +20-21 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +udp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +::ffff:10.1.2.3/128 \ +ip6 \ +dscp \ +63 \ +udp \ +dport \ +65535-65535 \ +udp \ +sport \ +255-256 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +udp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +::ffff:10.1.2.3/128 \ +ip6 \ +dscp \ +63 \ +udp \ +sport \ +65535-65535 \ +udp \ +dport \ +255-256 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/udp-linux.nftables.args b/tests= /nwfilterxml2firewalldata/udp-linux.nftables.args new file mode 100755 index 0000000000..641a60df0c --- /dev/null +++ b/tests/nwfilterxml2firewalldata/udp-linux.nftables.args @@ -0,0 +1,316 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +33 \ +udp \ +dport \ +100-1111 \ +udp \ +sport \ +20-21 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +33 \ +udp \ +sport \ +100-1111 \ +udp \ +dport \ +20-21 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +63 \ +udp \ +dport \ +65535-65535 \ +udp \ +sport \ +255-256 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udp \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +63 \ +udp \ +sport \ +65535-65535 \ +udp \ +dport \ +255-256 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/udplite-ipv6-linux.nftables.arg= s b/tests/nwfilterxml2firewalldata/udplite-ipv6-linux.nftables.args new file mode 100755 index 0000000000..6051b1bdf9 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/udplite-ipv6-linux.nftables.args @@ -0,0 +1,298 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +udplite \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +f:e:d::c:b:a/127 \ +ip6 \ +daddr \ +a:b:c::d:e:f/128 \ +ip6 \ +dscp \ +2 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +udplite \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +f:e:d::c:b:a/127 \ +ip6 \ +saddr \ +a:b:c::d:e:f/128 \ +ip6 \ +dscp \ +2 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +udplite \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +udplite \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +a:b:c::/128 \ +ip6 \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +udplite \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +saddr \ +::ffff:10.1.2.3/128 \ +ip6 \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip6 \ +meta \ +l4proto \ +udplite \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip6 \ +daddr \ +::ffff:10.1.2.3/128 \ +ip6 \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/udplite-linux.nftables.args b/t= ests/nwfilterxml2firewalldata/udplite-linux.nftables.args new file mode 100755 index 0000000000..d770a56268 --- /dev/null +++ b/tests/nwfilterxml2firewalldata/udplite-linux.nftables.args @@ -0,0 +1,292 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udplite \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udplite \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/32 \ +ip \ +dscp \ +2 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udplite \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udplite \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-in \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udplite \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +saddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +original \ +ct \ +state \ +new,established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +n-vnet0-out \ +ether \ +type \ +ip \ +meta \ +l4proto \ +udplite \ +ether \ +saddr \ +01:02:03:04:05:06 \ +ip \ +daddr \ +10.1.2.3/22 \ +ip \ +dscp \ +33 \ +ct \ +direction \ +reply \ +ct \ +state \ +established \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2firewalldata/vlan-linux.nftables.args b/test= s/nwfilterxml2firewalldata/vlan-linux.nftables.args new file mode 100755 index 0000000000..fabdc5f9da --- /dev/null +++ b/tests/nwfilterxml2firewalldata/vlan-linux.nftables.args @@ -0,0 +1,257 @@ +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +0x8100 \ +vlan \ +id \ +291 \ +continue +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +0x8100 \ +vlan \ +id \ +291 \ +continue +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +0x8100 \ +vlan \ +id \ +1234 \ +return +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +0x8100 \ +vlan \ +id \ +1234 \ +return +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-in \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +0x8100 \ +vlan \ +id \ +291 \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +0x8100 \ +vlan \ +type \ +2054 \ +drop +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +n-vnet0-out \ +ether \ +saddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D 01:02:03:04:05:06' \ +ether \ +daddr \ +'& ff:ff:ff:ff:ff:ff =3D=3D aa:bb:cc:dd:ee:ff' \ +ether \ +type \ +0x8100 \ +vlan \ +type \ +4660 \ +accept +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +postrouting \ +oif \ +vnet0 \ +jump \ +n-vnet0-in +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-oif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-in \ +'}' +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_inet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +add \ +rule \ +bridge \ +libvirt_nwfilter_ethernet \ +prerouting \ +iif \ +vnet0 \ +jump \ +n-vnet0-out +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_inet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' +nft \ +delete \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +'}' +nft \ +add \ +element \ +bridge \ +libvirt_nwfilter_ethernet \ +vmap-iif \ +'{' \ +vnet0 \ +: \ +jump \ +n-vnet0-out \ +'}' diff --git a/tests/nwfilterxml2nftfirewalltest.c b/tests/nwfilterxml2nftfir= ewalltest.c new file mode 100644 index 0000000000..d96297b8fc --- /dev/null +++ b/tests/nwfilterxml2nftfirewalltest.c @@ -0,0 +1,432 @@ +/* + * nwfilterxml2nftfirewalltest.c: Test iptables rule generation + * + * Copyright (C) 2014 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + */ + +#include + +#if defined (__linux__) + +# include "testutils.h" +# include "nwfilter/nwfilter_nftables_driver.h" +# include "virbuffer.h" + +# define LIBVIRT_VIRCOMMANDPRIV_H_ALLOW +# include "vircommandpriv.h" + +# define VIR_FROM_THIS VIR_FROM_NONE + +# ifdef __linux__ +# define RULESTYPE "linux" +# else +# error "test case not ported to this platform" +# endif + +typedef struct _virNWFilterInst virNWFilterInst; +struct _virNWFilterInst { + virNWFilterDef **filters; + size_t nfilters; + virNWFilterRuleInst **rules; + size_t nrules; +}; + +/* + * Some sets of rules that will be common to all test files, + * so we don't bother including them in the test data files + * as that would just bloat them + */ +static const char *commonRules[] =3D { + "nft \\\nlist \\\ntables\n" + "nft \\\nlist \\\nchains\n" + "nft \\\nadd \\\ntable \\\nbridge \\\nlibvirt_nwfilter_ethernet \\\n'{= comment \"Managed by libvirt for network filters: https://libvirt.org/fire= wall.html#the-network-filter-driver\"; }'\n" + "nft \\\nadd \\\nset \\\nbridge \\\nlibvirt_nwfilter_ethernet \\\nsame= -ip-set \\\n'{ type ipv4_addr . ipv4_addr; }'\n" + "nft \\\nadd \\\nelement \\\nbridge \\\nlibvirt_nwfilter_ethernet \\\n= same-ip-set \\\n'{' \\\n0.0.0.0 \\\n. \\\n0.0.0.0 \\\n, \\\n1.0.0.0 \\\n. \= \\n1.0.0.0 \\\n, \\\n2.0.0.0 \\\n. \\\n2.0.0.0 \\\n, \\\n3.0.0.0 \\\n. \\\n= 3.0.0.0 \\\n, \\\n4.0.0.0 \\\n. \\\n4.0.0.0 \\\n, \\\n5.0.0.0 \\\n. \\\n5.0= .0.0 \\\n, \\\n6.0.0.0 \\\n. \\\n6.0.0.0 \\\n, \\\n7.0.0.0 \\\n. \\\n7.0.0.= 0 \\\n, \\\n8.0.0.0 \\\n. \\\n8.0.0.0 \\\n, \\\n9.0.0.0 \\\n. \\\n9.0.0.0 \= \\n, \\\n10.0.0.0 \\\n. \\\n10.0.0.0 \\\n, \\\n11.0.0.0 \\\n. \\\n11.0.0.0 = \\\n, \\\n12.0.0.0 \\\n. \\\n12.0.0.0 \\\n, \\\n13.0.0.0 \\\n. \\\n13.0.0.0= \\\n, \\\n14.0.0.0 \\\n. \\\n14.0.0.0 \\\n, \\\n15.0.0.0 \\\n. \\\n15.0.0.= 0 \\\n, \\\n16.0.0.0 \\\n. \\\n16.0.0.0 \\\n, \\\n17.0.0.0 \\\n. \\\n17.0.0= .0 \\\n, \\\n18.0.0.0 \\\n. \\\n18.0.0.0 \\\n, \\\n19.0.0.0 \\\n. \\\n19.0.= 0.0 \\\n, \\\n20.0.0.0 \\\n. \\\n20.0.0.0 \\\n, \\\n21.0.0.0 \\\n. \\\n21.0= .0.0 \\\n, \\\n22.0.0.0 \\\n. \\\n22.0.0.0 \\\n, \\\n23.0.0.0 \\\n. \\\n23.= 0.0.0 \\\n, \\\n24.0.0.0 \\\n. \\\n24.0.0.0 \\\n, \\\n25.0.0.0 \\\n. \\\n25= .0.0.0 \\\n, \\\n26.0.0.0 \\\n. \\\n26.0.0.0 \\\n, \\\n27.0.0.0 \\\n. \\\n2= 7.0.0.0 \\\n, \\\n28.0.0.0 \\\n. \\\n28.0.0.0 \\\n, \\\n29.0.0.0 \\\n. \\\n= 29.0.0.0 \\\n, \\\n30.0.0.0 \\\n. \\\n30.0.0.0 \\\n, \\\n31.0.0.0 \\\n. \\\= n31.0.0.0 \\\n, \\\n32.0.0.0 \\\n. \\\n32.0.0.0 \\\n, \\\n33.0.0.0 \\\n. \\= \n33.0.0.0 \\\n, \\\n34.0.0.0 \\\n. \\\n34.0.0.0 \\\n, \\\n35.0.0.0 \\\n. \= \\n35.0.0.0 \\\n, \\\n36.0.0.0 \\\n. \\\n36.0.0.0 \\\n, \\\n37.0.0.0 \\\n. = \\\n37.0.0.0 \\\n, \\\n38.0.0.0 \\\n. \\\n38.0.0.0 \\\n, \\\n39.0.0.0 \\\n.= \\\n39.0.0.0 \\\n, \\\n40.0.0.0 \\\n. \\\n40.0.0.0 \\\n, \\\n41.0.0.0 \\\n= . \\\n41.0.0.0 \\\n, \\\n42.0.0.0 \\\n. \\\n42.0.0.0 \\\n, \\\n43.0.0.0 \\\= n. \\\n43.0.0.0 \\\n, \\\n44.0.0.0 \\\n. \\\n44.0.0.0 \\\n, \\\n45.0.0.0 \\= \n. \\\n45.0.0.0 \\\n, \\\n46.0.0.0 \\\n. \\\n46.0.0.0 \\\n, \\\n47.0.0.0 \= \\n. \\\n47.0.0.0 \\\n, \\\n48.0.0.0 \\\n. \\\n48.0.0.0 \\\n, \\\n49.0.0.0 = \\\n. \\\n49.0.0.0 \\\n, \\\n50.0.0.0 \\\n. \\\n50.0.0.0 \\\n, \\\n51.0.0.0= \\\n. \\\n51.0.0.0 \\\n, \\\n52.0.0.0 \\\n. \\\n52.0.0.0 \\\n, \\\n53.0.0.= 0 \\\n. \\\n53.0.0.0 \\\n, \\\n54.0.0.0 \\\n. \\\n54.0.0.0 \\\n, \\\n55.0.0= .0 \\\n. \\\n55.0.0.0 \\\n, \\\n56.0.0.0 \\\n. \\\n56.0.0.0 \\\n, \\\n57.0.= 0.0 \\\n. \\\n57.0.0.0 \\\n, \\\n58.0.0.0 \\\n. \\\n58.0.0.0 \\\n, \\\n59.0= .0.0 \\\n. \\\n59.0.0.0 \\\n, \\\n60.0.0.0 \\\n. \\\n60.0.0.0 \\\n, \\\n61.= 0.0.0 \\\n. \\\n61.0.0.0 \\\n, \\\n62.0.0.0 \\\n. \\\n62.0.0.0 \\\n, \\\n63= .0.0.0 \\\n. \\\n63.0.0.0 \\\n, \\\n64.0.0.0 \\\n. \\\n64.0.0.0 \\\n, \\\n6= 5.0.0.0 \\\n. \\\n65.0.0.0 \\\n, \\\n66.0.0.0 \\\n. \\\n66.0.0.0 \\\n, \\\n= 67.0.0.0 \\\n. \\\n67.0.0.0 \\\n, \\\n68.0.0.0 \\\n. \\\n68.0.0.0 \\\n, \\\= n69.0.0.0 \\\n. \\\n69.0.0.0 \\\n, \\\n70.0.0.0 \\\n. \\\n70.0.0.0 \\\n, \\= \n71.0.0.0 \\\n. \\\n71.0.0.0 \\\n, \\\n72.0.0.0 \\\n. \\\n72.0.0.0 \\\n, \= \\n73.0.0.0 \\\n. \\\n73.0.0.0 \\\n, \\\n74.0.0.0 \\\n. \\\n74.0.0.0 \\\n, = \\\n75.0.0.0 \\\n. \\\n75.0.0.0 \\\n, \\\n76.0.0.0 \\\n. \\\n76.0.0.0 \\\n,= \\\n77.0.0.0 \\\n. \\\n77.0.0.0 \\\n, \\\n78.0.0.0 \\\n. \\\n78.0.0.0 \\\n= , \\\n79.0.0.0 \\\n. \\\n79.0.0.0 \\\n, \\\n80.0.0.0 \\\n. \\\n80.0.0.0 \\\= n, \\\n81.0.0.0 \\\n. \\\n81.0.0.0 \\\n, \\\n82.0.0.0 \\\n. \\\n82.0.0.0 \\= \n, \\\n83.0.0.0 \\\n. \\\n83.0.0.0 \\\n, \\\n84.0.0.0 \\\n. \\\n84.0.0.0 \= \\n, \\\n85.0.0.0 \\\n. \\\n85.0.0.0 \\\n, \\\n86.0.0.0 \\\n. \\\n86.0.0.0 = \\\n, \\\n87.0.0.0 \\\n. \\\n87.0.0.0 \\\n, \\\n88.0.0.0 \\\n. \\\n88.0.0.0= \\\n, \\\n89.0.0.0 \\\n. \\\n89.0.0.0 \\\n, \\\n90.0.0.0 \\\n. \\\n90.0.0.= 0 \\\n, \\\n91.0.0.0 \\\n. \\\n91.0.0.0 \\\n, \\\n92.0.0.0 \\\n. \\\n92.0.0= .0 \\\n, \\\n93.0.0.0 \\\n. \\\n93.0.0.0 \\\n, \\\n94.0.0.0 \\\n. \\\n94.0.= 0.0 \\\n, \\\n95.0.0.0 \\\n. \\\n95.0.0.0 \\\n, \\\n96.0.0.0 \\\n. \\\n96.0= .0.0 \\\n, \\\n97.0.0.0 \\\n. \\\n97.0.0.0 \\\n, \\\n98.0.0.0 \\\n. \\\n98.= 0.0.0 \\\n, \\\n99.0.0.0 \\\n. \\\n99.0.0.0 \\\n, \\\n100.0.0.0 \\\n. \\\n1= 00.0.0.0 \\\n, \\\n101.0.0.0 \\\n. \\\n101.0.0.0 \\\n, \\\n102.0.0.0 \\\n. = \\\n102.0.0.0 \\\n, \\\n103.0.0.0 \\\n. \\\n103.0.0.0 \\\n, \\\n104.0.0.0 \= \\n. \\\n104.0.0.0 \\\n, \\\n105.0.0.0 \\\n. \\\n105.0.0.0 \\\n, \\\n106.0.= 0.0 \\\n. \\\n106.0.0.0 \\\n, \\\n107.0.0.0 \\\n. \\\n107.0.0.0 \\\n, \\\n1= 08.0.0.0 \\\n. \\\n108.0.0.0 \\\n, \\\n109.0.0.0 \\\n. \\\n109.0.0.0 \\\n, = \\\n110.0.0.0 \\\n. \\\n110.0.0.0 \\\n, \\\n111.0.0.0 \\\n. \\\n111.0.0.0 \= \\n, \\\n112.0.0.0 \\\n. \\\n112.0.0.0 \\\n, \\\n113.0.0.0 \\\n. \\\n113.0.= 0.0 \\\n, \\\n114.0.0.0 \\\n. \\\n114.0.0.0 \\\n, \\\n115.0.0.0 \\\n. \\\n1= 15.0.0.0 \\\n, \\\n116.0.0.0 \\\n. \\\n116.0.0.0 \\\n, \\\n117.0.0.0 \\\n. = \\\n117.0.0.0 \\\n, \\\n118.0.0.0 \\\n. \\\n118.0.0.0 \\\n, \\\n119.0.0.0 \= \\n. \\\n119.0.0.0 \\\n, \\\n120.0.0.0 \\\n. \\\n120.0.0.0 \\\n, \\\n121.0.= 0.0 \\\n. \\\n121.0.0.0 \\\n, \\\n122.0.0.0 \\\n. \\\n122.0.0.0 \\\n, \\\n1= 23.0.0.0 \\\n. \\\n123.0.0.0 \\\n, \\\n124.0.0.0 \\\n. \\\n124.0.0.0 \\\n, = \\\n125.0.0.0 \\\n. \\\n125.0.0.0 \\\n, \\\n126.0.0.0 \\\n. \\\n126.0.0.0 \= \\n, \\\n127.0.0.0 \\\n. \\\n127.0.0.0 \\\n, \\\n128.0.0.0 \\\n. \\\n128.0.= 0.0 \\\n, \\\n129.0.0.0 \\\n. \\\n129.0.0.0 \\\n, \\\n130.0.0.0 \\\n. \\\n1= 30.0.0.0 \\\n, \\\n131.0.0.0 \\\n. \\\n131.0.0.0 \\\n, \\\n132.0.0.0 \\\n. = \\\n132.0.0.0 \\\n, \\\n133.0.0.0 \\\n. \\\n133.0.0.0 \\\n, \\\n134.0.0.0 \= \\n. \\\n134.0.0.0 \\\n, \\\n135.0.0.0 \\\n. \\\n135.0.0.0 \\\n, \\\n136.0.= 0.0 \\\n. \\\n136.0.0.0 \\\n, \\\n137.0.0.0 \\\n. \\\n137.0.0.0 \\\n, \\\n1= 38.0.0.0 \\\n. \\\n138.0.0.0 \\\n, \\\n139.0.0.0 \\\n. \\\n139.0.0.0 \\\n, = \\\n140.0.0.0 \\\n. \\\n140.0.0.0 \\\n, \\\n141.0.0.0 \\\n. \\\n141.0.0.0 \= \\n, \\\n142.0.0.0 \\\n. \\\n142.0.0.0 \\\n, \\\n143.0.0.0 \\\n. \\\n143.0.= 0.0 \\\n, \\\n144.0.0.0 \\\n. \\\n144.0.0.0 \\\n, \\\n145.0.0.0 \\\n. \\\n1= 45.0.0.0 \\\n, \\\n146.0.0.0 \\\n. \\\n146.0.0.0 \\\n, \\\n147.0.0.0 \\\n. = \\\n147.0.0.0 \\\n, \\\n148.0.0.0 \\\n. \\\n148.0.0.0 \\\n, \\\n149.0.0.0 \= \\n. \\\n149.0.0.0 \\\n, \\\n150.0.0.0 \\\n. \\\n150.0.0.0 \\\n, \\\n151.0.= 0.0 \\\n. \\\n151.0.0.0 \\\n, \\\n152.0.0.0 \\\n. \\\n152.0.0.0 \\\n, \\\n1= 53.0.0.0 \\\n. \\\n153.0.0.0 \\\n, \\\n154.0.0.0 \\\n. \\\n154.0.0.0 \\\n, = \\\n155.0.0.0 \\\n. \\\n155.0.0.0 \\\n, \\\n156.0.0.0 \\\n. \\\n156.0.0.0 \= \\n, \\\n157.0.0.0 \\\n. \\\n157.0.0.0 \\\n, \\\n158.0.0.0 \\\n. \\\n158.0.= 0.0 \\\n, \\\n159.0.0.0 \\\n. \\\n159.0.0.0 \\\n, \\\n160.0.0.0 \\\n. \\\n1= 60.0.0.0 \\\n, \\\n161.0.0.0 \\\n. \\\n161.0.0.0 \\\n, \\\n162.0.0.0 \\\n. = \\\n162.0.0.0 \\\n, \\\n163.0.0.0 \\\n. \\\n163.0.0.0 \\\n, \\\n164.0.0.0 \= \\n. \\\n164.0.0.0 \\\n, \\\n165.0.0.0 \\\n. \\\n165.0.0.0 \\\n, \\\n166.0.= 0.0 \\\n. \\\n166.0.0.0 \\\n, \\\n167.0.0.0 \\\n. \\\n167.0.0.0 \\\n, \\\n1= 68.0.0.0 \\\n. \\\n168.0.0.0 \\\n, \\\n169.0.0.0 \\\n. \\\n169.0.0.0 \\\n, = \\\n170.0.0.0 \\\n. \\\n170.0.0.0 \\\n, \\\n171.0.0.0 \\\n. \\\n171.0.0.0 \= \\n, \\\n172.0.0.0 \\\n. \\\n172.0.0.0 \\\n, \\\n173.0.0.0 \\\n. \\\n173.0.= 0.0 \\\n, \\\n174.0.0.0 \\\n. \\\n174.0.0.0 \\\n, \\\n175.0.0.0 \\\n. \\\n1= 75.0.0.0 \\\n, \\\n176.0.0.0 \\\n. \\\n176.0.0.0 \\\n, \\\n177.0.0.0 \\\n. = \\\n177.0.0.0 \\\n, \\\n178.0.0.0 \\\n. \\\n178.0.0.0 \\\n, \\\n179.0.0.0 \= \\n. \\\n179.0.0.0 \\\n, \\\n180.0.0.0 \\\n. \\\n180.0.0.0 \\\n, \\\n181.0.= 0.0 \\\n. \\\n181.0.0.0 \\\n, \\\n182.0.0.0 \\\n. \\\n182.0.0.0 \\\n, \\\n1= 83.0.0.0 \\\n. \\\n183.0.0.0 \\\n, \\\n184.0.0.0 \\\n. \\\n184.0.0.0 \\\n, = \\\n185.0.0.0 \\\n. \\\n185.0.0.0 \\\n, \\\n186.0.0.0 \\\n. \\\n186.0.0.0 \= \\n, \\\n187.0.0.0 \\\n. \\\n187.0.0.0 \\\n, \\\n188.0.0.0 \\\n. \\\n188.0.= 0.0 \\\n, \\\n189.0.0.0 \\\n. \\\n189.0.0.0 \\\n, \\\n190.0.0.0 \\\n. \\\n1= 90.0.0.0 \\\n, \\\n191.0.0.0 \\\n. \\\n191.0.0.0 \\\n, \\\n192.0.0.0 \\\n. = \\\n192.0.0.0 \\\n, \\\n193.0.0.0 \\\n. \\\n193.0.0.0 \\\n, \\\n194.0.0.0 \= \\n. \\\n194.0.0.0 \\\n, \\\n195.0.0.0 \\\n. \\\n195.0.0.0 \\\n, \\\n196.0.= 0.0 \\\n. \\\n196.0.0.0 \\\n, \\\n197.0.0.0 \\\n. \\\n197.0.0.0 \\\n, \\\n1= 98.0.0.0 \\\n. \\\n198.0.0.0 \\\n, \\\n199.0.0.0 \\\n. \\\n199.0.0.0 \\\n, = \\\n200.0.0.0 \\\n. \\\n200.0.0.0 \\\n, \\\n201.0.0.0 \\\n. \\\n201.0.0.0 \= \\n, \\\n202.0.0.0 \\\n. \\\n202.0.0.0 \\\n, \\\n203.0.0.0 \\\n. \\\n203.0.= 0.0 \\\n, \\\n204.0.0.0 \\\n. \\\n204.0.0.0 \\\n, \\\n205.0.0.0 \\\n. \\\n2= 05.0.0.0 \\\n, \\\n206.0.0.0 \\\n. \\\n206.0.0.0 \\\n, \\\n207.0.0.0 \\\n. = \\\n207.0.0.0 \\\n, \\\n208.0.0.0 \\\n. \\\n208.0.0.0 \\\n, \\\n209.0.0.0 \= \\n. \\\n209.0.0.0 \\\n, \\\n210.0.0.0 \\\n. \\\n210.0.0.0 \\\n, \\\n211.0.= 0.0 \\\n. \\\n211.0.0.0 \\\n, \\\n212.0.0.0 \\\n. \\\n212.0.0.0 \\\n, \\\n2= 13.0.0.0 \\\n. \\\n213.0.0.0 \\\n, \\\n214.0.0.0 \\\n. \\\n214.0.0.0 \\\n, = \\\n215.0.0.0 \\\n. \\\n215.0.0.0 \\\n, \\\n216.0.0.0 \\\n. \\\n216.0.0.0 \= \\n, \\\n217.0.0.0 \\\n. \\\n217.0.0.0 \\\n, \\\n218.0.0.0 \\\n. \\\n218.0.= 0.0 \\\n, \\\n219.0.0.0 \\\n. \\\n219.0.0.0 \\\n, \\\n220.0.0.0 \\\n. \\\n2= 20.0.0.0 \\\n, \\\n221.0.0.0 \\\n. \\\n221.0.0.0 \\\n, \\\n222.0.0.0 \\\n. = \\\n222.0.0.0 \\\n, \\\n223.0.0.0 \\\n. \\\n223.0.0.0 \\\n, \\\n224.0.0.0 \= \\n. \\\n224.0.0.0 \\\n, \\\n225.0.0.0 \\\n. \\\n225.0.0.0 \\\n, \\\n226.0.= 0.0 \\\n. \\\n226.0.0.0 \\\n, \\\n227.0.0.0 \\\n. \\\n227.0.0.0 \\\n, \\\n2= 28.0.0.0 \\\n. \\\n228.0.0.0 \\\n, \\\n229.0.0.0 \\\n. \\\n229.0.0.0 \\\n, = \\\n230.0.0.0 \\\n. \\\n230.0.0.0 \\\n, \\\n231.0.0.0 \\\n. \\\n231.0.0.0 \= \\n, \\\n232.0.0.0 \\\n. \\\n232.0.0.0 \\\n, \\\n233.0.0.0 \\\n. \\\n233.0.= 0.0 \\\n, \\\n234.0.0.0 \\\n. \\\n234.0.0.0 \\\n, \\\n235.0.0.0 \\\n. \\\n2= 35.0.0.0 \\\n, \\\n236.0.0.0 \\\n. \\\n236.0.0.0 \\\n, \\\n237.0.0.0 \\\n. = \\\n237.0.0.0 \\\n, \\\n238.0.0.0 \\\n. \\\n238.0.0.0 \\\n, \\\n239.0.0.0 \= \\n. \\\n239.0.0.0 \\\n, \\\n240.0.0.0 \\\n. \\\n240.0.0.0 \\\n, \\\n241.0.= 0.0 \\\n. \\\n241.0.0.0 \\\n, \\\n242.0.0.0 \\\n. \\\n242.0.0.0 \\\n, \\\n2= 43.0.0.0 \\\n. \\\n243.0.0.0 \\\n, \\\n244.0.0.0 \\\n. \\\n244.0.0.0 \\\n, = \\\n245.0.0.0 \\\n. \\\n245.0.0.0 \\\n, \\\n246.0.0.0 \\\n. \\\n246.0.0.0 \= \\n, \\\n247.0.0.0 \\\n. \\\n247.0.0.0 \\\n, \\\n248.0.0.0 \\\n. \\\n248.0.= 0.0 \\\n, \\\n249.0.0.0 \\\n. \\\n249.0.0.0 \\\n, \\\n250.0.0.0 \\\n. \\\n2= 50.0.0.0 \\\n, \\\n251.0.0.0 \\\n. \\\n251.0.0.0 \\\n, \\\n252.0.0.0 \\\n. = \\\n252.0.0.0 \\\n, \\\n253.0.0.0 \\\n. \\\n253.0.0.0 \\\n, \\\n254.0.0.0 \= \\n. \\\n254.0.0.0 \\\n, \\\n255.0.0.0 \\\n. \\\n255.0.0.0 \\\n, \\\n0.0.0.= 0 \\\n. \\\n0.0.0.0 \\\n, \\\n0.1.0.0 \\\n. \\\n0.1.0.0 \\\n, \\\n0.2.0.0 \= \\n. \\\n0.2.0.0 \\\n, \\\n0.3.0.0 \\\n. \\\n0.3.0.0 \\\n, \\\n0.4.0.0 \\\n= . \\\n0.4.0.0 \\\n, \\\n0.5.0.0 \\\n. \\\n0.5.0.0 \\\n, \\\n0.6.0.0 \\\n. \= \\n0.6.0.0 \\\n, \\\n0.7.0.0 \\\n. \\\n0.7.0.0 \\\n, \\\n0.8.0.0 \\\n. \\\n= 0.8.0.0 \\\n, \\\n0.9.0.0 \\\n. \\\n0.9.0.0 \\\n, \\\n0.10.0.0 \\\n. \\\n0.= 10.0.0 \\\n, \\\n0.11.0.0 \\\n. \\\n0.11.0.0 \\\n, \\\n0.12.0.0 \\\n. \\\n0= .12.0.0 \\\n, \\\n0.13.0.0 \\\n. \\\n0.13.0.0 \\\n, \\\n0.14.0.0 \\\n. \\\n= 0.14.0.0 \\\n, \\\n0.15.0.0 \\\n. \\\n0.15.0.0 \\\n, \\\n0.16.0.0 \\\n. \\\= n0.16.0.0 \\\n, \\\n0.17.0.0 \\\n. \\\n0.17.0.0 \\\n, \\\n0.18.0.0 \\\n. \\= \n0.18.0.0 \\\n, \\\n0.19.0.0 \\\n. \\\n0.19.0.0 \\\n, \\\n0.20.0.0 \\\n. \= \\n0.20.0.0 \\\n, \\\n0.21.0.0 \\\n. \\\n0.21.0.0 \\\n, \\\n0.22.0.0 \\\n. = \\\n0.22.0.0 \\\n, \\\n0.23.0.0 \\\n. \\\n0.23.0.0 \\\n, \\\n0.24.0.0 \\\n.= \\\n0.24.0.0 \\\n, \\\n0.25.0.0 \\\n. \\\n0.25.0.0 \\\n, \\\n0.26.0.0 \\\n= . \\\n0.26.0.0 \\\n, \\\n0.27.0.0 \\\n. \\\n0.27.0.0 \\\n, \\\n0.28.0.0 \\\= n. \\\n0.28.0.0 \\\n, \\\n0.29.0.0 \\\n. \\\n0.29.0.0 \\\n, \\\n0.30.0.0 \\= \n. \\\n0.30.0.0 \\\n, \\\n0.31.0.0 \\\n. \\\n0.31.0.0 \\\n, \\\n0.32.0.0 \= \\n. \\\n0.32.0.0 \\\n, \\\n0.33.0.0 \\\n. \\\n0.33.0.0 \\\n, \\\n0.34.0.0 = \\\n. \\\n0.34.0.0 \\\n, \\\n0.35.0.0 \\\n. \\\n0.35.0.0 \\\n, \\\n0.36.0.0= \\\n. \\\n0.36.0.0 \\\n, \\\n0.37.0.0 \\\n. \\\n0.37.0.0 \\\n, \\\n0.38.0.= 0 \\\n. \\\n0.38.0.0 \\\n, \\\n0.39.0.0 \\\n. \\\n0.39.0.0 \\\n, \\\n0.40.0= .0 \\\n. \\\n0.40.0.0 \\\n, \\\n0.41.0.0 \\\n. \\\n0.41.0.0 \\\n, \\\n0.42.= 0.0 \\\n. \\\n0.42.0.0 \\\n, \\\n0.43.0.0 \\\n. \\\n0.43.0.0 \\\n, \\\n0.44= .0.0 \\\n. \\\n0.44.0.0 \\\n, \\\n0.45.0.0 \\\n. \\\n0.45.0.0 \\\n, \\\n0.4= 6.0.0 \\\n. \\\n0.46.0.0 \\\n, \\\n0.47.0.0 \\\n. \\\n0.47.0.0 \\\n, \\\n0.= 48.0.0 \\\n. \\\n0.48.0.0 \\\n, \\\n0.49.0.0 \\\n. \\\n0.49.0.0 \\\n, \\\n0= .50.0.0 \\\n. \\\n0.50.0.0 \\\n, \\\n0.51.0.0 \\\n. \\\n0.51.0.0 \\\n, \\\n= 0.52.0.0 \\\n. \\\n0.52.0.0 \\\n, \\\n0.53.0.0 \\\n. \\\n0.53.0.0 \\\n, \\\= n0.54.0.0 \\\n. \\\n0.54.0.0 \\\n, \\\n0.55.0.0 \\\n. \\\n0.55.0.0 \\\n, \\= \n0.56.0.0 \\\n. \\\n0.56.0.0 \\\n, \\\n0.57.0.0 \\\n. \\\n0.57.0.0 \\\n, \= \\n0.58.0.0 \\\n. \\\n0.58.0.0 \\\n, \\\n0.59.0.0 \\\n. \\\n0.59.0.0 \\\n, = \\\n0.60.0.0 \\\n. \\\n0.60.0.0 \\\n, \\\n0.61.0.0 \\\n. \\\n0.61.0.0 \\\n,= \\\n0.62.0.0 \\\n. \\\n0.62.0.0 \\\n, \\\n0.63.0.0 \\\n. \\\n0.63.0.0 \\\n= , \\\n0.64.0.0 \\\n. \\\n0.64.0.0 \\\n, \\\n0.65.0.0 \\\n. \\\n0.65.0.0 \\\= n, \\\n0.66.0.0 \\\n. \\\n0.66.0.0 \\\n, \\\n0.67.0.0 \\\n. \\\n0.67.0.0 \\= \n, \\\n0.68.0.0 \\\n. \\\n0.68.0.0 \\\n, \\\n0.69.0.0 \\\n. \\\n0.69.0.0 \= \\n, \\\n0.70.0.0 \\\n. \\\n0.70.0.0 \\\n, \\\n0.71.0.0 \\\n. \\\n0.71.0.0 = \\\n, \\\n0.72.0.0 \\\n. \\\n0.72.0.0 \\\n, \\\n0.73.0.0 \\\n. \\\n0.73.0.0= \\\n, \\\n0.74.0.0 \\\n. \\\n0.74.0.0 \\\n, \\\n0.75.0.0 \\\n. \\\n0.75.0.= 0 \\\n, \\\n0.76.0.0 \\\n. \\\n0.76.0.0 \\\n, \\\n0.77.0.0 \\\n. \\\n0.77.0= .0 \\\n, \\\n0.78.0.0 \\\n. \\\n0.78.0.0 \\\n, \\\n0.79.0.0 \\\n. \\\n0.79.= 0.0 \\\n, \\\n0.80.0.0 \\\n. \\\n0.80.0.0 \\\n, \\\n0.81.0.0 \\\n. \\\n0.81= .0.0 \\\n, \\\n0.82.0.0 \\\n. \\\n0.82.0.0 \\\n, \\\n0.83.0.0 \\\n. \\\n0.8= 3.0.0 \\\n, \\\n0.84.0.0 \\\n. \\\n0.84.0.0 \\\n, \\\n0.85.0.0 \\\n. \\\n0.= 85.0.0 \\\n, \\\n0.86.0.0 \\\n. \\\n0.86.0.0 \\\n, \\\n0.87.0.0 \\\n. \\\n0= .87.0.0 \\\n, \\\n0.88.0.0 \\\n. \\\n0.88.0.0 \\\n, \\\n0.89.0.0 \\\n. \\\n= 0.89.0.0 \\\n, \\\n0.90.0.0 \\\n. \\\n0.90.0.0 \\\n, \\\n0.91.0.0 \\\n. \\\= n0.91.0.0 \\\n, \\\n0.92.0.0 \\\n. \\\n0.92.0.0 \\\n, \\\n0.93.0.0 \\\n. \\= \n0.93.0.0 \\\n, \\\n0.94.0.0 \\\n. \\\n0.94.0.0 \\\n, \\\n0.95.0.0 \\\n. \= \\n0.95.0.0 \\\n, \\\n0.96.0.0 \\\n. \\\n0.96.0.0 \\\n, \\\n0.97.0.0 \\\n. = \\\n0.97.0.0 \\\n, \\\n0.98.0.0 \\\n. \\\n0.98.0.0 \\\n, \\\n0.99.0.0 \\\n.= \\\n0.99.0.0 \\\n, \\\n0.100.0.0 \\\n. \\\n0.100.0.0 \\\n, \\\n0.101.0.0 \= \\n. \\\n0.101.0.0 \\\n, \\\n0.102.0.0 \\\n. \\\n0.102.0.0 \\\n, \\\n0.103.= 0.0 \\\n. \\\n0.103.0.0 \\\n, \\\n0.104.0.0 \\\n. \\\n0.104.0.0 \\\n, \\\n0= .105.0.0 \\\n. \\\n0.105.0.0 \\\n, \\\n0.106.0.0 \\\n. \\\n0.106.0.0 \\\n, = \\\n0.107.0.0 \\\n. \\\n0.107.0.0 \\\n, \\\n0.108.0.0 \\\n. \\\n0.108.0.0 \= \\n, \\\n0.109.0.0 \\\n. \\\n0.109.0.0 \\\n, \\\n0.110.0.0 \\\n. \\\n0.110.= 0.0 \\\n, \\\n0.111.0.0 \\\n. \\\n0.111.0.0 \\\n, \\\n0.112.0.0 \\\n. \\\n0= .112.0.0 \\\n, \\\n0.113.0.0 \\\n. \\\n0.113.0.0 \\\n, \\\n0.114.0.0 \\\n. = \\\n0.114.0.0 \\\n, \\\n0.115.0.0 \\\n. \\\n0.115.0.0 \\\n, \\\n0.116.0.0 \= \\n. \\\n0.116.0.0 \\\n, \\\n0.117.0.0 \\\n. \\\n0.117.0.0 \\\n, \\\n0.118.= 0.0 \\\n. \\\n0.118.0.0 \\\n, \\\n0.119.0.0 \\\n. \\\n0.119.0.0 \\\n, \\\n0= .120.0.0 \\\n. \\\n0.120.0.0 \\\n, \\\n0.121.0.0 \\\n. \\\n0.121.0.0 \\\n, = \\\n0.122.0.0 \\\n. \\\n0.122.0.0 \\\n, \\\n0.123.0.0 \\\n. \\\n0.123.0.0 \= \\n, \\\n0.124.0.0 \\\n. \\\n0.124.0.0 \\\n, \\\n0.125.0.0 \\\n. \\\n0.125.= 0.0 \\\n, \\\n0.126.0.0 \\\n. \\\n0.126.0.0 \\\n, \\\n0.127.0.0 \\\n. \\\n0= .127.0.0 \\\n, \\\n0.128.0.0 \\\n. \\\n0.128.0.0 \\\n, \\\n0.129.0.0 \\\n. = \\\n0.129.0.0 \\\n, \\\n0.130.0.0 \\\n. \\\n0.130.0.0 \\\n, \\\n0.131.0.0 \= \\n. \\\n0.131.0.0 \\\n, \\\n0.132.0.0 \\\n. \\\n0.132.0.0 \\\n, \\\n0.133.= 0.0 \\\n. \\\n0.133.0.0 \\\n, \\\n0.134.0.0 \\\n. \\\n0.134.0.0 \\\n, \\\n0= .135.0.0 \\\n. \\\n0.135.0.0 \\\n, \\\n0.136.0.0 \\\n. \\\n0.136.0.0 \\\n, = \\\n0.137.0.0 \\\n. \\\n0.137.0.0 \\\n, \\\n0.138.0.0 \\\n. \\\n0.138.0.0 \= \\n, \\\n0.139.0.0 \\\n. \\\n0.139.0.0 \\\n, \\\n0.140.0.0 \\\n. \\\n0.140.= 0.0 \\\n, \\\n0.141.0.0 \\\n. \\\n0.141.0.0 \\\n, \\\n0.142.0.0 \\\n. \\\n0= .142.0.0 \\\n, \\\n0.143.0.0 \\\n. \\\n0.143.0.0 \\\n, \\\n0.144.0.0 \\\n. = \\\n0.144.0.0 \\\n, \\\n0.145.0.0 \\\n. \\\n0.145.0.0 \\\n, \\\n0.146.0.0 \= \\n. \\\n0.146.0.0 \\\n, \\\n0.147.0.0 \\\n. \\\n0.147.0.0 \\\n, \\\n0.148.= 0.0 \\\n. \\\n0.148.0.0 \\\n, \\\n0.149.0.0 \\\n. \\\n0.149.0.0 \\\n, \\\n0= .150.0.0 \\\n. \\\n0.150.0.0 \\\n, \\\n0.151.0.0 \\\n. \\\n0.151.0.0 \\\n, = \\\n0.152.0.0 \\\n. \\\n0.152.0.0 \\\n, \\\n0.153.0.0 \\\n. \\\n0.153.0.0 \= \\n, \\\n0.154.0.0 \\\n. \\\n0.154.0.0 \\\n, \\\n0.155.0.0 \\\n. \\\n0.155.= 0.0 \\\n, \\\n0.156.0.0 \\\n. \\\n0.156.0.0 \\\n, \\\n0.157.0.0 \\\n. \\\n0= .157.0.0 \\\n, \\\n0.158.0.0 \\\n. \\\n0.158.0.0 \\\n, \\\n0.159.0.0 \\\n. = \\\n0.159.0.0 \\\n, \\\n0.160.0.0 \\\n. \\\n0.160.0.0 \\\n, \\\n0.161.0.0 \= \\n. \\\n0.161.0.0 \\\n, \\\n0.162.0.0 \\\n. \\\n0.162.0.0 \\\n, \\\n0.163.= 0.0 \\\n. \\\n0.163.0.0 \\\n, \\\n0.164.0.0 \\\n. \\\n0.164.0.0 \\\n, \\\n0= .165.0.0 \\\n. \\\n0.165.0.0 \\\n, \\\n0.166.0.0 \\\n. \\\n0.166.0.0 \\\n, = \\\n0.167.0.0 \\\n. \\\n0.167.0.0 \\\n, \\\n0.168.0.0 \\\n. \\\n0.168.0.0 \= \\n, \\\n0.169.0.0 \\\n. \\\n0.169.0.0 \\\n, \\\n0.170.0.0 \\\n. \\\n0.170.= 0.0 \\\n, \\\n0.171.0.0 \\\n. \\\n0.171.0.0 \\\n, \\\n0.172.0.0 \\\n. \\\n0= .172.0.0 \\\n, \\\n0.173.0.0 \\\n. \\\n0.173.0.0 \\\n, \\\n0.174.0.0 \\\n. = \\\n0.174.0.0 \\\n, \\\n0.175.0.0 \\\n. \\\n0.175.0.0 \\\n, \\\n0.176.0.0 \= \\n. \\\n0.176.0.0 \\\n, \\\n0.177.0.0 \\\n. \\\n0.177.0.0 \\\n, \\\n0.178.= 0.0 \\\n. \\\n0.178.0.0 \\\n, \\\n0.179.0.0 \\\n. \\\n0.179.0.0 \\\n, \\\n0= .180.0.0 \\\n. \\\n0.180.0.0 \\\n, \\\n0.181.0.0 \\\n. \\\n0.181.0.0 \\\n, = \\\n0.182.0.0 \\\n. \\\n0.182.0.0 \\\n, \\\n0.183.0.0 \\\n. \\\n0.183.0.0 \= \\n, \\\n0.184.0.0 \\\n. \\\n0.184.0.0 \\\n, \\\n0.185.0.0 \\\n. \\\n0.185.= 0.0 \\\n, \\\n0.186.0.0 \\\n. \\\n0.186.0.0 \\\n, \\\n0.187.0.0 \\\n. \\\n0= .187.0.0 \\\n, \\\n0.188.0.0 \\\n. \\\n0.188.0.0 \\\n, \\\n0.189.0.0 \\\n. = \\\n0.189.0.0 \\\n, \\\n0.190.0.0 \\\n. \\\n0.190.0.0 \\\n, \\\n0.191.0.0 \= \\n. \\\n0.191.0.0 \\\n, \\\n0.192.0.0 \\\n. \\\n0.192.0.0 \\\n, \\\n0.193.= 0.0 \\\n. \\\n0.193.0.0 \\\n, \\\n0.194.0.0 \\\n. \\\n0.194.0.0 \\\n, \\\n0= .195.0.0 \\\n. \\\n0.195.0.0 \\\n, \\\n0.196.0.0 \\\n. \\\n0.196.0.0 \\\n, = \\\n0.197.0.0 \\\n. \\\n0.197.0.0 \\\n, \\\n0.198.0.0 \\\n. \\\n0.198.0.0 \= \\n, \\\n0.199.0.0 \\\n. \\\n0.199.0.0 \\\n, \\\n0.200.0.0 \\\n. \\\n0.200.= 0.0 \\\n, \\\n0.201.0.0 \\\n. \\\n0.201.0.0 \\\n, \\\n0.202.0.0 \\\n. \\\n0= .202.0.0 \\\n, \\\n0.203.0.0 \\\n. \\\n0.203.0.0 \\\n, \\\n0.204.0.0 \\\n. = \\\n0.204.0.0 \\\n, \\\n0.205.0.0 \\\n. \\\n0.205.0.0 \\\n, \\\n0.206.0.0 \= \\n. \\\n0.206.0.0 \\\n, \\\n0.207.0.0 \\\n. \\\n0.207.0.0 \\\n, \\\n0.208.= 0.0 \\\n. \\\n0.208.0.0 \\\n, \\\n0.209.0.0 \\\n. \\\n0.209.0.0 \\\n, \\\n0= .210.0.0 \\\n. \\\n0.210.0.0 \\\n, \\\n0.211.0.0 \\\n. \\\n0.211.0.0 \\\n, = \\\n0.212.0.0 \\\n. \\\n0.212.0.0 \\\n, \\\n0.213.0.0 \\\n. \\\n0.213.0.0 \= \\n, \\\n0.214.0.0 \\\n. \\\n0.214.0.0 \\\n, \\\n0.215.0.0 \\\n. \\\n0.215.= 0.0 \\\n, \\\n0.216.0.0 \\\n. \\\n0.216.0.0 \\\n, \\\n0.217.0.0 \\\n. \\\n0= .217.0.0 \\\n, \\\n0.218.0.0 \\\n. \\\n0.218.0.0 \\\n, \\\n0.219.0.0 \\\n. = \\\n0.219.0.0 \\\n, \\\n0.220.0.0 \\\n. \\\n0.220.0.0 \\\n, \\\n0.221.0.0 \= \\n. \\\n0.221.0.0 \\\n, \\\n0.222.0.0 \\\n. \\\n0.222.0.0 \\\n, \\\n0.223.= 0.0 \\\n. \\\n0.223.0.0 \\\n, \\\n0.224.0.0 \\\n. \\\n0.224.0.0 \\\n, \\\n0= .225.0.0 \\\n. \\\n0.225.0.0 \\\n, \\\n0.226.0.0 \\\n. \\\n0.226.0.0 \\\n, = \\\n0.227.0.0 \\\n. \\\n0.227.0.0 \\\n, \\\n0.228.0.0 \\\n. \\\n0.228.0.0 \= \\n, \\\n0.229.0.0 \\\n. \\\n0.229.0.0 \\\n, \\\n0.230.0.0 \\\n. \\\n0.230.= 0.0 \\\n, \\\n0.231.0.0 \\\n. \\\n0.231.0.0 \\\n, \\\n0.232.0.0 \\\n. \\\n0= .232.0.0 \\\n, \\\n0.233.0.0 \\\n. \\\n0.233.0.0 \\\n, \\\n0.234.0.0 \\\n. = \\\n0.234.0.0 \\\n, \\\n0.235.0.0 \\\n. \\\n0.235.0.0 \\\n, \\\n0.236.0.0 \= \\n. \\\n0.236.0.0 \\\n, \\\n0.237.0.0 \\\n. \\\n0.237.0.0 \\\n, \\\n0.238.= 0.0 \\\n. \\\n0.238.0.0 \\\n, \\\n0.239.0.0 \\\n. \\\n0.239.0.0 \\\n, \\\n0= .240.0.0 \\\n. \\\n0.240.0.0 \\\n, \\\n0.241.0.0 \\\n. \\\n0.241.0.0 \\\n, = \\\n0.242.0.0 \\\n. \\\n0.242.0.0 \\\n, \\\n0.243.0.0 \\\n. \\\n0.243.0.0 \= \\n, \\\n0.244.0.0 \\\n. \\\n0.244.0.0 \\\n, \\\n0.245.0.0 \\\n. \\\n0.245.= 0.0 \\\n, \\\n0.246.0.0 \\\n. \\\n0.246.0.0 \\\n, \\\n0.247.0.0 \\\n. \\\n0= .247.0.0 \\\n, \\\n0.248.0.0 \\\n. \\\n0.248.0.0 \\\n, \\\n0.249.0.0 \\\n. = \\\n0.249.0.0 \\\n, \\\n0.250.0.0 \\\n. \\\n0.250.0.0 \\\n, \\\n0.251.0.0 \= \\n. \\\n0.251.0.0 \\\n, \\\n0.252.0.0 \\\n. \\\n0.252.0.0 \\\n, \\\n0.253.= 0.0 \\\n. \\\n0.253.0.0 \\\n, \\\n0.254.0.0 \\\n. \\\n0.254.0.0 \\\n, \\\n0= .255.0.0 \\\n. \\\n0.255.0.0 \\\n, \\\n0.0.0.0 \\\n. \\\n0.0.0.0 \\\n, \\\n= 0.0.1.0 \\\n. \\\n0.0.1.0 \\\n, \\\n0.0.2.0 \\\n. \\\n0.0.2.0 \\\n, \\\n0.0= .3.0 \\\n. \\\n0.0.3.0 \\\n, \\\n0.0.4.0 \\\n. \\\n0.0.4.0 \\\n, \\\n0.0.5.= 0 \\\n. \\\n0.0.5.0 \\\n, \\\n0.0.6.0 \\\n. \\\n0.0.6.0 \\\n, \\\n0.0.7.0 \= \\n. \\\n0.0.7.0 \\\n, \\\n0.0.8.0 \\\n. \\\n0.0.8.0 \\\n, \\\n0.0.9.0 \\\n= . \\\n0.0.9.0 \\\n, \\\n0.0.10.0 \\\n. \\\n0.0.10.0 \\\n, \\\n0.0.11.0 \\\n= . \\\n0.0.11.0 \\\n, \\\n0.0.12.0 \\\n. \\\n0.0.12.0 \\\n, \\\n0.0.13.0 \\\= n. \\\n0.0.13.0 \\\n, \\\n0.0.14.0 \\\n. \\\n0.0.14.0 \\\n, \\\n0.0.15.0 \\= \n. \\\n0.0.15.0 \\\n, \\\n0.0.16.0 \\\n. \\\n0.0.16.0 \\\n, \\\n0.0.17.0 \= \\n. \\\n0.0.17.0 \\\n, \\\n0.0.18.0 \\\n. \\\n0.0.18.0 \\\n, \\\n0.0.19.0 = \\\n. \\\n0.0.19.0 \\\n, \\\n0.0.20.0 \\\n. \\\n0.0.20.0 \\\n, \\\n0.0.21.0= \\\n. \\\n0.0.21.0 \\\n, \\\n0.0.22.0 \\\n. \\\n0.0.22.0 \\\n, \\\n0.0.23.= 0 \\\n. \\\n0.0.23.0 \\\n, \\\n0.0.24.0 \\\n. \\\n0.0.24.0 \\\n, \\\n0.0.25= .0 \\\n. \\\n0.0.25.0 \\\n, \\\n0.0.26.0 \\\n. \\\n0.0.26.0 \\\n, \\\n0.0.2= 7.0 \\\n. \\\n0.0.27.0 \\\n, \\\n0.0.28.0 \\\n. \\\n0.0.28.0 \\\n, \\\n0.0.= 29.0 \\\n. \\\n0.0.29.0 \\\n, \\\n0.0.30.0 \\\n. \\\n0.0.30.0 \\\n, \\\n0.0= .31.0 \\\n. \\\n0.0.31.0 \\\n, \\\n0.0.32.0 \\\n. \\\n0.0.32.0 \\\n, \\\n0.= 0.33.0 \\\n. \\\n0.0.33.0 \\\n, \\\n0.0.34.0 \\\n. \\\n0.0.34.0 \\\n, \\\n0= .0.35.0 \\\n. \\\n0.0.35.0 \\\n, \\\n0.0.36.0 \\\n. \\\n0.0.36.0 \\\n, \\\n= 0.0.37.0 \\\n. \\\n0.0.37.0 \\\n, \\\n0.0.38.0 \\\n. \\\n0.0.38.0 \\\n, \\\= n0.0.39.0 \\\n. \\\n0.0.39.0 \\\n, \\\n0.0.40.0 \\\n. \\\n0.0.40.0 \\\n, \\= \n0.0.41.0 \\\n. \\\n0.0.41.0 \\\n, \\\n0.0.42.0 \\\n. \\\n0.0.42.0 \\\n, \= \\n0.0.43.0 \\\n. \\\n0.0.43.0 \\\n, \\\n0.0.44.0 \\\n. \\\n0.0.44.0 \\\n, = \\\n0.0.45.0 \\\n. \\\n0.0.45.0 \\\n, \\\n0.0.46.0 \\\n. \\\n0.0.46.0 \\\n,= \\\n0.0.47.0 \\\n. \\\n0.0.47.0 \\\n, \\\n0.0.48.0 \\\n. \\\n0.0.48.0 \\\n= , \\\n0.0.49.0 \\\n. \\\n0.0.49.0 \\\n, \\\n0.0.50.0 \\\n. \\\n0.0.50.0 \\\= n, \\\n0.0.51.0 \\\n. \\\n0.0.51.0 \\\n, \\\n0.0.52.0 \\\n. \\\n0.0.52.0 \\= \n, \\\n0.0.53.0 \\\n. \\\n0.0.53.0 \\\n, \\\n0.0.54.0 \\\n. \\\n0.0.54.0 \= \\n, \\\n0.0.55.0 \\\n. \\\n0.0.55.0 \\\n, \\\n0.0.56.0 \\\n. \\\n0.0.56.0 = \\\n, \\\n0.0.57.0 \\\n. \\\n0.0.57.0 \\\n, \\\n0.0.58.0 \\\n. \\\n0.0.58.0= \\\n, \\\n0.0.59.0 \\\n. \\\n0.0.59.0 \\\n, \\\n0.0.60.0 \\\n. \\\n0.0.60.= 0 \\\n, \\\n0.0.61.0 \\\n. \\\n0.0.61.0 \\\n, \\\n0.0.62.0 \\\n. \\\n0.0.62= .0 \\\n, \\\n0.0.63.0 \\\n. \\\n0.0.63.0 \\\n, \\\n0.0.64.0 \\\n. \\\n0.0.6= 4.0 \\\n, \\\n0.0.65.0 \\\n. \\\n0.0.65.0 \\\n, \\\n0.0.66.0 \\\n. \\\n0.0.= 66.0 \\\n, \\\n0.0.67.0 \\\n. \\\n0.0.67.0 \\\n, \\\n0.0.68.0 \\\n. \\\n0.0= .68.0 \\\n, \\\n0.0.69.0 \\\n. \\\n0.0.69.0 \\\n, \\\n0.0.70.0 \\\n. \\\n0.= 0.70.0 \\\n, \\\n0.0.71.0 \\\n. \\\n0.0.71.0 \\\n, \\\n0.0.72.0 \\\n. \\\n0= .0.72.0 \\\n, \\\n0.0.73.0 \\\n. \\\n0.0.73.0 \\\n, \\\n0.0.74.0 \\\n. \\\n= 0.0.74.0 \\\n, \\\n0.0.75.0 \\\n. \\\n0.0.75.0 \\\n, \\\n0.0.76.0 \\\n. \\\= n0.0.76.0 \\\n, \\\n0.0.77.0 \\\n. \\\n0.0.77.0 \\\n, \\\n0.0.78.0 \\\n. \\= \n0.0.78.0 \\\n, \\\n0.0.79.0 \\\n. \\\n0.0.79.0 \\\n, \\\n0.0.80.0 \\\n. \= \\n0.0.80.0 \\\n, \\\n0.0.81.0 \\\n. \\\n0.0.81.0 \\\n, \\\n0.0.82.0 \\\n. = \\\n0.0.82.0 \\\n, \\\n0.0.83.0 \\\n. \\\n0.0.83.0 \\\n, \\\n0.0.84.0 \\\n.= \\\n0.0.84.0 \\\n, \\\n0.0.85.0 \\\n. \\\n0.0.85.0 \\\n, \\\n0.0.86.0 \\\n= . \\\n0.0.86.0 \\\n, \\\n0.0.87.0 \\\n. \\\n0.0.87.0 \\\n, \\\n0.0.88.0 \\\= n. \\\n0.0.88.0 \\\n, \\\n0.0.89.0 \\\n. \\\n0.0.89.0 \\\n, \\\n0.0.90.0 \\= \n. \\\n0.0.90.0 \\\n, \\\n0.0.91.0 \\\n. \\\n0.0.91.0 \\\n, \\\n0.0.92.0 \= \\n. \\\n0.0.92.0 \\\n, \\\n0.0.93.0 \\\n. \\\n0.0.93.0 \\\n, \\\n0.0.94.0 = \\\n. \\\n0.0.94.0 \\\n, \\\n0.0.95.0 \\\n. \\\n0.0.95.0 \\\n, \\\n0.0.96.0= \\\n. \\\n0.0.96.0 \\\n, \\\n0.0.97.0 \\\n. \\\n0.0.97.0 \\\n, \\\n0.0.98.= 0 \\\n. \\\n0.0.98.0 \\\n, \\\n0.0.99.0 \\\n. \\\n0.0.99.0 \\\n, \\\n0.0.10= 0.0 \\\n. \\\n0.0.100.0 \\\n, \\\n0.0.101.0 \\\n. \\\n0.0.101.0 \\\n, \\\n0= .0.102.0 \\\n. \\\n0.0.102.0 \\\n, \\\n0.0.103.0 \\\n. \\\n0.0.103.0 \\\n, = \\\n0.0.104.0 \\\n. \\\n0.0.104.0 \\\n, \\\n0.0.105.0 \\\n. \\\n0.0.105.0 \= \\n, \\\n0.0.106.0 \\\n. \\\n0.0.106.0 \\\n, \\\n0.0.107.0 \\\n. \\\n0.0.10= 7.0 \\\n, \\\n0.0.108.0 \\\n. \\\n0.0.108.0 \\\n, \\\n0.0.109.0 \\\n. \\\n0= .0.109.0 \\\n, \\\n0.0.110.0 \\\n. \\\n0.0.110.0 \\\n, \\\n0.0.111.0 \\\n. = \\\n0.0.111.0 \\\n, \\\n0.0.112.0 \\\n. \\\n0.0.112.0 \\\n, \\\n0.0.113.0 \= \\n. \\\n0.0.113.0 \\\n, \\\n0.0.114.0 \\\n. \\\n0.0.114.0 \\\n, \\\n0.0.11= 5.0 \\\n. \\\n0.0.115.0 \\\n, \\\n0.0.116.0 \\\n. \\\n0.0.116.0 \\\n, \\\n0= .0.117.0 \\\n. \\\n0.0.117.0 \\\n, \\\n0.0.118.0 \\\n. \\\n0.0.118.0 \\\n, = \\\n0.0.119.0 \\\n. \\\n0.0.119.0 \\\n, \\\n0.0.120.0 \\\n. \\\n0.0.120.0 \= \\n, \\\n0.0.121.0 \\\n. \\\n0.0.121.0 \\\n, \\\n0.0.122.0 \\\n. \\\n0.0.12= 2.0 \\\n, \\\n0.0.123.0 \\\n. \\\n0.0.123.0 \\\n, \\\n0.0.124.0 \\\n. \\\n0= .0.124.0 \\\n, \\\n0.0.125.0 \\\n. \\\n0.0.125.0 \\\n, \\\n0.0.126.0 \\\n. = \\\n0.0.126.0 \\\n, \\\n0.0.127.0 \\\n. \\\n0.0.127.0 \\\n, \\\n0.0.128.0 \= \\n. \\\n0.0.128.0 \\\n, \\\n0.0.129.0 \\\n. \\\n0.0.129.0 \\\n, \\\n0.0.13= 0.0 \\\n. \\\n0.0.130.0 \\\n, \\\n0.0.131.0 \\\n. \\\n0.0.131.0 \\\n, \\\n0= .0.132.0 \\\n. \\\n0.0.132.0 \\\n, \\\n0.0.133.0 \\\n. \\\n0.0.133.0 \\\n, = \\\n0.0.134.0 \\\n. \\\n0.0.134.0 \\\n, \\\n0.0.135.0 \\\n. \\\n0.0.135.0 \= \\n, \\\n0.0.136.0 \\\n. \\\n0.0.136.0 \\\n, \\\n0.0.137.0 \\\n. \\\n0.0.13= 7.0 \\\n, \\\n0.0.138.0 \\\n. \\\n0.0.138.0 \\\n, \\\n0.0.139.0 \\\n. \\\n0= .0.139.0 \\\n, \\\n0.0.140.0 \\\n. \\\n0.0.140.0 \\\n, \\\n0.0.141.0 \\\n. = \\\n0.0.141.0 \\\n, \\\n0.0.142.0 \\\n. \\\n0.0.142.0 \\\n, \\\n0.0.143.0 \= \\n. \\\n0.0.143.0 \\\n, \\\n0.0.144.0 \\\n. \\\n0.0.144.0 \\\n, \\\n0.0.14= 5.0 \\\n. \\\n0.0.145.0 \\\n, \\\n0.0.146.0 \\\n. \\\n0.0.146.0 \\\n, \\\n0= .0.147.0 \\\n. \\\n0.0.147.0 \\\n, \\\n0.0.148.0 \\\n. \\\n0.0.148.0 \\\n, = \\\n0.0.149.0 \\\n. \\\n0.0.149.0 \\\n, \\\n0.0.150.0 \\\n. \\\n0.0.150.0 \= \\n, \\\n0.0.151.0 \\\n. \\\n0.0.151.0 \\\n, \\\n0.0.152.0 \\\n. \\\n0.0.15= 2.0 \\\n, \\\n0.0.153.0 \\\n. \\\n0.0.153.0 \\\n, \\\n0.0.154.0 \\\n. \\\n0= .0.154.0 \\\n, \\\n0.0.155.0 \\\n. \\\n0.0.155.0 \\\n, \\\n0.0.156.0 \\\n. = \\\n0.0.156.0 \\\n, \\\n0.0.157.0 \\\n. \\\n0.0.157.0 \\\n, \\\n0.0.158.0 \= \\n. \\\n0.0.158.0 \\\n, \\\n0.0.159.0 \\\n. \\\n0.0.159.0 \\\n, \\\n0.0.16= 0.0 \\\n. \\\n0.0.160.0 \\\n, \\\n0.0.161.0 \\\n. \\\n0.0.161.0 \\\n, \\\n0= .0.162.0 \\\n. \\\n0.0.162.0 \\\n, \\\n0.0.163.0 \\\n. \\\n0.0.163.0 \\\n, = \\\n0.0.164.0 \\\n. \\\n0.0.164.0 \\\n, \\\n0.0.165.0 \\\n. \\\n0.0.165.0 \= \\n, \\\n0.0.166.0 \\\n. \\\n0.0.166.0 \\\n, \\\n0.0.167.0 \\\n. \\\n0.0.16= 7.0 \\\n, \\\n0.0.168.0 \\\n. \\\n0.0.168.0 \\\n, \\\n0.0.169.0 \\\n. \\\n0= .0.169.0 \\\n, \\\n0.0.170.0 \\\n. \\\n0.0.170.0 \\\n, \\\n0.0.171.0 \\\n. = \\\n0.0.171.0 \\\n, \\\n0.0.172.0 \\\n. \\\n0.0.172.0 \\\n, \\\n0.0.173.0 \= \\n. \\\n0.0.173.0 \\\n, \\\n0.0.174.0 \\\n. \\\n0.0.174.0 \\\n, \\\n0.0.17= 5.0 \\\n. \\\n0.0.175.0 \\\n, \\\n0.0.176.0 \\\n. \\\n0.0.176.0 \\\n, \\\n0= .0.177.0 \\\n. \\\n0.0.177.0 \\\n, \\\n0.0.178.0 \\\n. \\\n0.0.178.0 \\\n, = \\\n0.0.179.0 \\\n. \\\n0.0.179.0 \\\n, \\\n0.0.180.0 \\\n. \\\n0.0.180.0 \= \\n, \\\n0.0.181.0 \\\n. \\\n0.0.181.0 \\\n, \\\n0.0.182.0 \\\n. \\\n0.0.18= 2.0 \\\n, \\\n0.0.183.0 \\\n. \\\n0.0.183.0 \\\n, \\\n0.0.184.0 \\\n. \\\n0= .0.184.0 \\\n, \\\n0.0.185.0 \\\n. \\\n0.0.185.0 \\\n, \\\n0.0.186.0 \\\n. = \\\n0.0.186.0 \\\n, \\\n0.0.187.0 \\\n. \\\n0.0.187.0 \\\n, \\\n0.0.188.0 \= \\n. \\\n0.0.188.0 \\\n, \\\n0.0.189.0 \\\n. \\\n0.0.189.0 \\\n, \\\n0.0.19= 0.0 \\\n. \\\n0.0.190.0 \\\n, \\\n0.0.191.0 \\\n. \\\n0.0.191.0 \\\n, \\\n0= .0.192.0 \\\n. \\\n0.0.192.0 \\\n, \\\n0.0.193.0 \\\n. \\\n0.0.193.0 \\\n, = \\\n0.0.194.0 \\\n. \\\n0.0.194.0 \\\n, \\\n0.0.195.0 \\\n. \\\n0.0.195.0 \= \\n, \\\n0.0.196.0 \\\n. \\\n0.0.196.0 \\\n, \\\n0.0.197.0 \\\n. \\\n0.0.19= 7.0 \\\n, \\\n0.0.198.0 \\\n. \\\n0.0.198.0 \\\n, \\\n0.0.199.0 \\\n. \\\n0= .0.199.0 \\\n, \\\n0.0.200.0 \\\n. \\\n0.0.200.0 \\\n, \\\n0.0.201.0 \\\n. = \\\n0.0.201.0 \\\n, \\\n0.0.202.0 \\\n. \\\n0.0.202.0 \\\n, \\\n0.0.203.0 \= \\n. \\\n0.0.203.0 \\\n, \\\n0.0.204.0 \\\n. \\\n0.0.204.0 \\\n, \\\n0.0.20= 5.0 \\\n. \\\n0.0.205.0 \\\n, \\\n0.0.206.0 \\\n. \\\n0.0.206.0 \\\n, \\\n0= .0.207.0 \\\n. \\\n0.0.207.0 \\\n, \\\n0.0.208.0 \\\n. \\\n0.0.208.0 \\\n, = \\\n0.0.209.0 \\\n. \\\n0.0.209.0 \\\n, \\\n0.0.210.0 \\\n. \\\n0.0.210.0 \= \\n, \\\n0.0.211.0 \\\n. \\\n0.0.211.0 \\\n, \\\n0.0.212.0 \\\n. \\\n0.0.21= 2.0 \\\n, \\\n0.0.213.0 \\\n. \\\n0.0.213.0 \\\n, \\\n0.0.214.0 \\\n. \\\n0= .0.214.0 \\\n, \\\n0.0.215.0 \\\n. \\\n0.0.215.0 \\\n, \\\n0.0.216.0 \\\n. = \\\n0.0.216.0 \\\n, \\\n0.0.217.0 \\\n. \\\n0.0.217.0 \\\n, \\\n0.0.218.0 \= \\n. \\\n0.0.218.0 \\\n, \\\n0.0.219.0 \\\n. \\\n0.0.219.0 \\\n, \\\n0.0.22= 0.0 \\\n. \\\n0.0.220.0 \\\n, \\\n0.0.221.0 \\\n. \\\n0.0.221.0 \\\n, \\\n0= .0.222.0 \\\n. \\\n0.0.222.0 \\\n, \\\n0.0.223.0 \\\n. \\\n0.0.223.0 \\\n, = \\\n0.0.224.0 \\\n. \\\n0.0.224.0 \\\n, \\\n0.0.225.0 \\\n. \\\n0.0.225.0 \= \\n, \\\n0.0.226.0 \\\n. \\\n0.0.226.0 \\\n, \\\n0.0.227.0 \\\n. \\\n0.0.22= 7.0 \\\n, \\\n0.0.228.0 \\\n. \\\n0.0.228.0 \\\n, \\\n0.0.229.0 \\\n. \\\n0= .0.229.0 \\\n, \\\n0.0.230.0 \\\n. \\\n0.0.230.0 \\\n, \\\n0.0.231.0 \\\n. = \\\n0.0.231.0 \\\n, \\\n0.0.232.0 \\\n. \\\n0.0.232.0 \\\n, \\\n0.0.233.0 \= \\n. \\\n0.0.233.0 \\\n, \\\n0.0.234.0 \\\n. \\\n0.0.234.0 \\\n, \\\n0.0.23= 5.0 \\\n. \\\n0.0.235.0 \\\n, \\\n0.0.236.0 \\\n. \\\n0.0.236.0 \\\n, \\\n0= .0.237.0 \\\n. \\\n0.0.237.0 \\\n, \\\n0.0.238.0 \\\n. \\\n0.0.238.0 \\\n, = \\\n0.0.239.0 \\\n. \\\n0.0.239.0 \\\n, \\\n0.0.240.0 \\\n. \\\n0.0.240.0 \= \\n, \\\n0.0.241.0 \\\n. \\\n0.0.241.0 \\\n, \\\n0.0.242.0 \\\n. \\\n0.0.24= 2.0 \\\n, \\\n0.0.243.0 \\\n. \\\n0.0.243.0 \\\n, \\\n0.0.244.0 \\\n. \\\n0= .0.244.0 \\\n, \\\n0.0.245.0 \\\n. \\\n0.0.245.0 \\\n, \\\n0.0.246.0 \\\n. = \\\n0.0.246.0 \\\n, \\\n0.0.247.0 \\\n. \\\n0.0.247.0 \\\n, \\\n0.0.248.0 \= \\n. \\\n0.0.248.0 \\\n, \\\n0.0.249.0 \\\n. \\\n0.0.249.0 \\\n, \\\n0.0.25= 0.0 \\\n. \\\n0.0.250.0 \\\n, \\\n0.0.251.0 \\\n. \\\n0.0.251.0 \\\n, \\\n0= .0.252.0 \\\n. \\\n0.0.252.0 \\\n, \\\n0.0.253.0 \\\n. \\\n0.0.253.0 \\\n, = \\\n0.0.254.0 \\\n. \\\n0.0.254.0 \\\n, \\\n0.0.255.0 \\\n. \\\n0.0.255.0 \= \\n, \\\n0.0.0.0 \\\n. \\\n0.0.0.0 \\\n, \\\n0.0.0.1 \\\n. \\\n0.0.0.1 \\\n= , \\\n0.0.0.2 \\\n. \\\n0.0.0.2 \\\n, \\\n0.0.0.3 \\\n. \\\n0.0.0.3 \\\n, \= \\n0.0.0.4 \\\n. \\\n0.0.0.4 \\\n, \\\n0.0.0.5 \\\n. \\\n0.0.0.5 \\\n, \\\n= 0.0.0.6 \\\n. \\\n0.0.0.6 \\\n, \\\n0.0.0.7 \\\n. \\\n0.0.0.7 \\\n, \\\n0.0= .0.8 \\\n. \\\n0.0.0.8 \\\n, \\\n0.0.0.9 \\\n. \\\n0.0.0.9 \\\n, \\\n0.0.0.= 10 \\\n. \\\n0.0.0.10 \\\n, \\\n0.0.0.11 \\\n. \\\n0.0.0.11 \\\n, \\\n0.0.0= .12 \\\n. \\\n0.0.0.12 \\\n, \\\n0.0.0.13 \\\n. \\\n0.0.0.13 \\\n, \\\n0.0.= 0.14 \\\n. \\\n0.0.0.14 \\\n, \\\n0.0.0.15 \\\n. \\\n0.0.0.15 \\\n, \\\n0.0= .0.16 \\\n. \\\n0.0.0.16 \\\n, \\\n0.0.0.17 \\\n. \\\n0.0.0.17 \\\n, \\\n0.= 0.0.18 \\\n. \\\n0.0.0.18 \\\n, \\\n0.0.0.19 \\\n. \\\n0.0.0.19 \\\n, \\\n0= .0.0.20 \\\n. \\\n0.0.0.20 \\\n, \\\n0.0.0.21 \\\n. \\\n0.0.0.21 \\\n, \\\n= 0.0.0.22 \\\n. \\\n0.0.0.22 \\\n, \\\n0.0.0.23 \\\n. \\\n0.0.0.23 \\\n, \\\= n0.0.0.24 \\\n. \\\n0.0.0.24 \\\n, \\\n0.0.0.25 \\\n. \\\n0.0.0.25 \\\n, \\= \n0.0.0.26 \\\n. \\\n0.0.0.26 \\\n, \\\n0.0.0.27 \\\n. \\\n0.0.0.27 \\\n, \= \\n0.0.0.28 \\\n. \\\n0.0.0.28 \\\n, \\\n0.0.0.29 \\\n. \\\n0.0.0.29 \\\n, = \\\n0.0.0.30 \\\n. \\\n0.0.0.30 \\\n, \\\n0.0.0.31 \\\n. \\\n0.0.0.31 \\\n,= \\\n0.0.0.32 \\\n. \\\n0.0.0.32 \\\n, \\\n0.0.0.33 \\\n. \\\n0.0.0.33 \\\n= , \\\n0.0.0.34 \\\n. \\\n0.0.0.34 \\\n, \\\n0.0.0.35 \\\n. \\\n0.0.0.35 \\\= n, \\\n0.0.0.36 \\\n. \\\n0.0.0.36 \\\n, \\\n0.0.0.37 \\\n. \\\n0.0.0.37 \\= \n, \\\n0.0.0.38 \\\n. \\\n0.0.0.38 \\\n, \\\n0.0.0.39 \\\n. \\\n0.0.0.39 \= \\n, \\\n0.0.0.40 \\\n. \\\n0.0.0.40 \\\n, \\\n0.0.0.41 \\\n. \\\n0.0.0.41 = \\\n, \\\n0.0.0.42 \\\n. \\\n0.0.0.42 \\\n, \\\n0.0.0.43 \\\n. \\\n0.0.0.43= \\\n, \\\n0.0.0.44 \\\n. \\\n0.0.0.44 \\\n, \\\n0.0.0.45 \\\n. \\\n0.0.0.4= 5 \\\n, \\\n0.0.0.46 \\\n. \\\n0.0.0.46 \\\n, \\\n0.0.0.47 \\\n. \\\n0.0.0.= 47 \\\n, \\\n0.0.0.48 \\\n. \\\n0.0.0.48 \\\n, \\\n0.0.0.49 \\\n. \\\n0.0.0= .49 \\\n, \\\n0.0.0.50 \\\n. \\\n0.0.0.50 \\\n, \\\n0.0.0.51 \\\n. \\\n0.0.= 0.51 \\\n, \\\n0.0.0.52 \\\n. \\\n0.0.0.52 \\\n, \\\n0.0.0.53 \\\n. \\\n0.0= .0.53 \\\n, \\\n0.0.0.54 \\\n. \\\n0.0.0.54 \\\n, \\\n0.0.0.55 \\\n. \\\n0.= 0.0.55 \\\n, \\\n0.0.0.56 \\\n. \\\n0.0.0.56 \\\n, \\\n0.0.0.57 \\\n. \\\n0= .0.0.57 \\\n, \\\n0.0.0.58 \\\n. \\\n0.0.0.58 \\\n, \\\n0.0.0.59 \\\n. \\\n= 0.0.0.59 \\\n, \\\n0.0.0.60 \\\n. \\\n0.0.0.60 \\\n, \\\n0.0.0.61 \\\n. \\\= n0.0.0.61 \\\n, \\\n0.0.0.62 \\\n. \\\n0.0.0.62 \\\n, \\\n0.0.0.63 \\\n. \\= \n0.0.0.63 \\\n, \\\n0.0.0.64 \\\n. \\\n0.0.0.64 \\\n, \\\n0.0.0.65 \\\n. \= \\n0.0.0.65 \\\n, \\\n0.0.0.66 \\\n. \\\n0.0.0.66 \\\n, \\\n0.0.0.67 \\\n. = \\\n0.0.0.67 \\\n, \\\n0.0.0.68 \\\n. \\\n0.0.0.68 \\\n, \\\n0.0.0.69 \\\n.= \\\n0.0.0.69 \\\n, \\\n0.0.0.70 \\\n. \\\n0.0.0.70 \\\n, \\\n0.0.0.71 \\\n= . \\\n0.0.0.71 \\\n, \\\n0.0.0.72 \\\n. \\\n0.0.0.72 \\\n, \\\n0.0.0.73 \\\= n. \\\n0.0.0.73 \\\n, \\\n0.0.0.74 \\\n. \\\n0.0.0.74 \\\n, \\\n0.0.0.75 \\= \n. \\\n0.0.0.75 \\\n, \\\n0.0.0.76 \\\n. \\\n0.0.0.76 \\\n, \\\n0.0.0.77 \= \\n. \\\n0.0.0.77 \\\n, \\\n0.0.0.78 \\\n. \\\n0.0.0.78 \\\n, \\\n0.0.0.79 = \\\n. \\\n0.0.0.79 \\\n, \\\n0.0.0.80 \\\n. \\\n0.0.0.80 \\\n, \\\n0.0.0.81= \\\n. \\\n0.0.0.81 \\\n, \\\n0.0.0.82 \\\n. \\\n0.0.0.82 \\\n, \\\n0.0.0.8= 3 \\\n. \\\n0.0.0.83 \\\n, \\\n0.0.0.84 \\\n. \\\n0.0.0.84 \\\n, \\\n0.0.0.= 85 \\\n. \\\n0.0.0.85 \\\n, \\\n0.0.0.86 \\\n. \\\n0.0.0.86 \\\n, \\\n0.0.0= .87 \\\n. \\\n0.0.0.87 \\\n, \\\n0.0.0.88 \\\n. \\\n0.0.0.88 \\\n, \\\n0.0.= 0.89 \\\n. \\\n0.0.0.89 \\\n, \\\n0.0.0.90 \\\n. \\\n0.0.0.90 \\\n, \\\n0.0= .0.91 \\\n. \\\n0.0.0.91 \\\n, \\\n0.0.0.92 \\\n. \\\n0.0.0.92 \\\n, \\\n0.= 0.0.93 \\\n. \\\n0.0.0.93 \\\n, \\\n0.0.0.94 \\\n. \\\n0.0.0.94 \\\n, \\\n0= .0.0.95 \\\n. \\\n0.0.0.95 \\\n, \\\n0.0.0.96 \\\n. \\\n0.0.0.96 \\\n, \\\n= 0.0.0.97 \\\n. \\\n0.0.0.97 \\\n, \\\n0.0.0.98 \\\n. \\\n0.0.0.98 \\\n, \\\= n0.0.0.99 \\\n. \\\n0.0.0.99 \\\n, \\\n0.0.0.100 \\\n. \\\n0.0.0.100 \\\n, = \\\n0.0.0.101 \\\n. \\\n0.0.0.101 \\\n, \\\n0.0.0.102 \\\n. \\\n0.0.0.102 \= \\n, \\\n0.0.0.103 \\\n. \\\n0.0.0.103 \\\n, \\\n0.0.0.104 \\\n. \\\n0.0.0.= 104 \\\n, \\\n0.0.0.105 \\\n. \\\n0.0.0.105 \\\n, \\\n0.0.0.106 \\\n. \\\n0= .0.0.106 \\\n, \\\n0.0.0.107 \\\n. \\\n0.0.0.107 \\\n, \\\n0.0.0.108 \\\n. = \\\n0.0.0.108 \\\n, \\\n0.0.0.109 \\\n. \\\n0.0.0.109 \\\n, \\\n0.0.0.110 \= \\n. \\\n0.0.0.110 \\\n, \\\n0.0.0.111 \\\n. \\\n0.0.0.111 \\\n, \\\n0.0.0.= 112 \\\n. \\\n0.0.0.112 \\\n, \\\n0.0.0.113 \\\n. \\\n0.0.0.113 \\\n, \\\n0= .0.0.114 \\\n. \\\n0.0.0.114 \\\n, \\\n0.0.0.115 \\\n. \\\n0.0.0.115 \\\n, = \\\n0.0.0.116 \\\n. \\\n0.0.0.116 \\\n, \\\n0.0.0.117 \\\n. \\\n0.0.0.117 \= \\n, \\\n0.0.0.118 \\\n. \\\n0.0.0.118 \\\n, \\\n0.0.0.119 \\\n. \\\n0.0.0.= 119 \\\n, \\\n0.0.0.120 \\\n. \\\n0.0.0.120 \\\n, \\\n0.0.0.121 \\\n. \\\n0= .0.0.121 \\\n, \\\n0.0.0.122 \\\n. \\\n0.0.0.122 \\\n, \\\n0.0.0.123 \\\n. = \\\n0.0.0.123 \\\n, \\\n0.0.0.124 \\\n. \\\n0.0.0.124 \\\n, \\\n0.0.0.125 \= \\n. \\\n0.0.0.125 \\\n, \\\n0.0.0.126 \\\n. \\\n0.0.0.126 \\\n, \\\n0.0.0.= 127 \\\n. \\\n0.0.0.127 \\\n, \\\n0.0.0.128 \\\n. \\\n0.0.0.128 \\\n, \\\n0= .0.0.129 \\\n. \\\n0.0.0.129 \\\n, \\\n0.0.0.130 \\\n. \\\n0.0.0.130 \\\n, = \\\n0.0.0.131 \\\n. \\\n0.0.0.131 \\\n, \\\n0.0.0.132 \\\n. \\\n0.0.0.132 \= \\n, \\\n0.0.0.133 \\\n. \\\n0.0.0.133 \\\n, \\\n0.0.0.134 \\\n. \\\n0.0.0.= 134 \\\n, \\\n0.0.0.135 \\\n. \\\n0.0.0.135 \\\n, \\\n0.0.0.136 \\\n. \\\n0= .0.0.136 \\\n, \\\n0.0.0.137 \\\n. \\\n0.0.0.137 \\\n, \\\n0.0.0.138 \\\n. = \\\n0.0.0.138 \\\n, \\\n0.0.0.139 \\\n. \\\n0.0.0.139 \\\n, \\\n0.0.0.140 \= \\n. \\\n0.0.0.140 \\\n, \\\n0.0.0.141 \\\n. \\\n0.0.0.141 \\\n, \\\n0.0.0.= 142 \\\n. \\\n0.0.0.142 \\\n, \\\n0.0.0.143 \\\n. \\\n0.0.0.143 \\\n, \\\n0= .0.0.144 \\\n. \\\n0.0.0.144 \\\n, \\\n0.0.0.145 \\\n. \\\n0.0.0.145 \\\n, = \\\n0.0.0.146 \\\n. \\\n0.0.0.146 \\\n, \\\n0.0.0.147 \\\n. \\\n0.0.0.147 \= \\n, \\\n0.0.0.148 \\\n. \\\n0.0.0.148 \\\n, \\\n0.0.0.149 \\\n. \\\n0.0.0.= 149 \\\n, \\\n0.0.0.150 \\\n. \\\n0.0.0.150 \\\n, \\\n0.0.0.151 \\\n. \\\n0= .0.0.151 \\\n, \\\n0.0.0.152 \\\n. \\\n0.0.0.152 \\\n, \\\n0.0.0.153 \\\n. = \\\n0.0.0.153 \\\n, \\\n0.0.0.154 \\\n. \\\n0.0.0.154 \\\n, \\\n0.0.0.155 \= \\n. \\\n0.0.0.155 \\\n, \\\n0.0.0.156 \\\n. \\\n0.0.0.156 \\\n, \\\n0.0.0.= 157 \\\n. \\\n0.0.0.157 \\\n, \\\n0.0.0.158 \\\n. \\\n0.0.0.158 \\\n, \\\n0= .0.0.159 \\\n. \\\n0.0.0.159 \\\n, \\\n0.0.0.160 \\\n. \\\n0.0.0.160 \\\n, = \\\n0.0.0.161 \\\n. \\\n0.0.0.161 \\\n, \\\n0.0.0.162 \\\n. \\\n0.0.0.162 \= \\n, \\\n0.0.0.163 \\\n. \\\n0.0.0.163 \\\n, \\\n0.0.0.164 \\\n. \\\n0.0.0.= 164 \\\n, \\\n0.0.0.165 \\\n. \\\n0.0.0.165 \\\n, \\\n0.0.0.166 \\\n. \\\n0= .0.0.166 \\\n, \\\n0.0.0.167 \\\n. \\\n0.0.0.167 \\\n, \\\n0.0.0.168 \\\n. = \\\n0.0.0.168 \\\n, \\\n0.0.0.169 \\\n. \\\n0.0.0.169 \\\n, \\\n0.0.0.170 \= \\n. \\\n0.0.0.170 \\\n, \\\n0.0.0.171 \\\n. \\\n0.0.0.171 \\\n, \\\n0.0.0.= 172 \\\n. \\\n0.0.0.172 \\\n, \\\n0.0.0.173 \\\n. \\\n0.0.0.173 \\\n, \\\n0= .0.0.174 \\\n. \\\n0.0.0.174 \\\n, \\\n0.0.0.175 \\\n. \\\n0.0.0.175 \\\n, = \\\n0.0.0.176 \\\n. \\\n0.0.0.176 \\\n, \\\n0.0.0.177 \\\n. \\\n0.0.0.177 \= \\n, \\\n0.0.0.178 \\\n. \\\n0.0.0.178 \\\n, \\\n0.0.0.179 \\\n. \\\n0.0.0.= 179 \\\n, \\\n0.0.0.180 \\\n. \\\n0.0.0.180 \\\n, \\\n0.0.0.181 \\\n. \\\n0= .0.0.181 \\\n, \\\n0.0.0.182 \\\n. \\\n0.0.0.182 \\\n, \\\n0.0.0.183 \\\n. = \\\n0.0.0.183 \\\n, \\\n0.0.0.184 \\\n. \\\n0.0.0.184 \\\n, \\\n0.0.0.185 \= \\n. \\\n0.0.0.185 \\\n, \\\n0.0.0.186 \\\n. \\\n0.0.0.186 \\\n, \\\n0.0.0.= 187 \\\n. \\\n0.0.0.187 \\\n, \\\n0.0.0.188 \\\n. \\\n0.0.0.188 \\\n, \\\n0= .0.0.189 \\\n. \\\n0.0.0.189 \\\n, \\\n0.0.0.190 \\\n. \\\n0.0.0.190 \\\n, = \\\n0.0.0.191 \\\n. \\\n0.0.0.191 \\\n, \\\n0.0.0.192 \\\n. \\\n0.0.0.192 \= \\n, \\\n0.0.0.193 \\\n. \\\n0.0.0.193 \\\n, \\\n0.0.0.194 \\\n. \\\n0.0.0.= 194 \\\n, \\\n0.0.0.195 \\\n. \\\n0.0.0.195 \\\n, \\\n0.0.0.196 \\\n. \\\n0= .0.0.196 \\\n, \\\n0.0.0.197 \\\n. \\\n0.0.0.197 \\\n, \\\n0.0.0.198 \\\n. = \\\n0.0.0.198 \\\n, \\\n0.0.0.199 \\\n. \\\n0.0.0.199 \\\n, \\\n0.0.0.200 \= \\n. \\\n0.0.0.200 \\\n, \\\n0.0.0.201 \\\n. \\\n0.0.0.201 \\\n, \\\n0.0.0.= 202 \\\n. \\\n0.0.0.202 \\\n, \\\n0.0.0.203 \\\n. \\\n0.0.0.203 \\\n, \\\n0= .0.0.204 \\\n. \\\n0.0.0.204 \\\n, \\\n0.0.0.205 \\\n. \\\n0.0.0.205 \\\n, = \\\n0.0.0.206 \\\n. \\\n0.0.0.206 \\\n, \\\n0.0.0.207 \\\n. \\\n0.0.0.207 \= \\n, \\\n0.0.0.208 \\\n. \\\n0.0.0.208 \\\n, \\\n0.0.0.209 \\\n. \\\n0.0.0.= 209 \\\n, \\\n0.0.0.210 \\\n. \\\n0.0.0.210 \\\n, \\\n0.0.0.211 \\\n. \\\n0= .0.0.211 \\\n, \\\n0.0.0.212 \\\n. \\\n0.0.0.212 \\\n, \\\n0.0.0.213 \\\n. = \\\n0.0.0.213 \\\n, \\\n0.0.0.214 \\\n. \\\n0.0.0.214 \\\n, \\\n0.0.0.215 \= \\n. \\\n0.0.0.215 \\\n, \\\n0.0.0.216 \\\n. \\\n0.0.0.216 \\\n, \\\n0.0.0.= 217 \\\n. \\\n0.0.0.217 \\\n, \\\n0.0.0.218 \\\n. \\\n0.0.0.218 \\\n, \\\n0= .0.0.219 \\\n. \\\n0.0.0.219 \\\n, \\\n0.0.0.220 \\\n. \\\n0.0.0.220 \\\n, = \\\n0.0.0.221 \\\n. \\\n0.0.0.221 \\\n, \\\n0.0.0.222 \\\n. \\\n0.0.0.222 \= \\n, \\\n0.0.0.223 \\\n. \\\n0.0.0.223 \\\n, \\\n0.0.0.224 \\\n. \\\n0.0.0.= 224 \\\n, \\\n0.0.0.225 \\\n. \\\n0.0.0.225 \\\n, \\\n0.0.0.226 \\\n. \\\n0= .0.0.226 \\\n, \\\n0.0.0.227 \\\n. \\\n0.0.0.227 \\\n, \\\n0.0.0.228 \\\n. = \\\n0.0.0.228 \\\n, \\\n0.0.0.229 \\\n. \\\n0.0.0.229 \\\n, \\\n0.0.0.230 \= \\n. \\\n0.0.0.230 \\\n, \\\n0.0.0.231 \\\n. \\\n0.0.0.231 \\\n, \\\n0.0.0.= 232 \\\n. \\\n0.0.0.232 \\\n, \\\n0.0.0.233 \\\n. \\\n0.0.0.233 \\\n, \\\n0= .0.0.234 \\\n. \\\n0.0.0.234 \\\n, \\\n0.0.0.235 \\\n. \\\n0.0.0.235 \\\n, = \\\n0.0.0.236 \\\n. \\\n0.0.0.236 \\\n, \\\n0.0.0.237 \\\n. \\\n0.0.0.237 \= \\n, \\\n0.0.0.238 \\\n. \\\n0.0.0.238 \\\n, \\\n0.0.0.239 \\\n. \\\n0.0.0.= 239 \\\n, \\\n0.0.0.240 \\\n. \\\n0.0.0.240 \\\n, \\\n0.0.0.241 \\\n. \\\n0= .0.0.241 \\\n, \\\n0.0.0.242 \\\n. \\\n0.0.0.242 \\\n, \\\n0.0.0.243 \\\n. = \\\n0.0.0.243 \\\n, \\\n0.0.0.244 \\\n. \\\n0.0.0.244 \\\n, \\\n0.0.0.245 \= \\n. \\\n0.0.0.245 \\\n, \\\n0.0.0.246 \\\n. \\\n0.0.0.246 \\\n, \\\n0.0.0.= 247 \\\n. \\\n0.0.0.247 \\\n, \\\n0.0.0.248 \\\n. \\\n0.0.0.248 \\\n, \\\n0= .0.0.249 \\\n. \\\n0.0.0.249 \\\n, \\\n0.0.0.250 \\\n. \\\n0.0.0.250 \\\n, = \\\n0.0.0.251 \\\n. \\\n0.0.0.251 \\\n, \\\n0.0.0.252 \\\n. \\\n0.0.0.252 \= \\n, \\\n0.0.0.253 \\\n. \\\n0.0.0.253 \\\n, \\\n0.0.0.254 \\\n. \\\n0.0.0.= 254 \\\n, \\\n0.0.0.255 \\\n. \\\n0.0.0.255 \\\n, \\\n'}'\n" + "nft \\\nadd \\\nmap \\\nbridge \\\nlibvirt_nwfilter_ethernet \\\nvmap= -oif \\\n'{ type iface_index: verdict; }'\n" + "nft \\\nadd \\\nmap \\\nbridge \\\nlibvirt_nwfilter_ethernet \\\nvmap= -iif \\\n'{ type iface_index: verdict; }'\n" + "nft \\\nadd \\\nchain \\\nbridge \\\nlibvirt_nwfilter_ethernet \\\npo= strouting \\\n'{ type filter hook postrouting priority 0; policy accept; }= '\n" + "nft \\\nadd \\\nchain \\\nbridge \\\nlibvirt_nwfilter_ethernet \\\npr= erouting \\\n'{ type filter hook prerouting priority 0; policy accept; }'\= n" + "nft \\\nadd \\\nrule \\\nbridge \\\nlibvirt_nwfilter_ethernet \\\npos= trouting \\\noif \\\nvmap \\\n@vmap-oif\n" + "nft \\\nadd \\\nrule \\\nbridge \\\nlibvirt_nwfilter_ethernet \\\npre= routing \\\niif \\\nvmap \\\n@vmap-iif\n" + "nft \\\nadd \\\ntable \\\nbridge \\\nlibvirt_nwfilter_inet \\\n'{ com= ment \"Managed by libvirt for network filters: https://libvirt.org/firewall= .html#the-network-filter-driver\"; }'\n" + "nft \\\nadd \\\nmap \\\nbridge \\\nlibvirt_nwfilter_inet \\\nvmap-oif= \\\n'{ type iface_index: verdict; }'\n", + "nft \\\nadd \\\nmap \\\nbridge \\\nlibvirt_nwfilter_inet \\\nvmap-iif= \\\n'{ type iface_index: verdict; }'\n" + "nft \\\nadd \\\nchain \\\nbridge \\\nlibvirt_nwfilter_inet \\\npostro= uting \\\n'{ type filter hook postrouting priority 1; policy accept; }'\n" + "nft \\\nadd \\\nchain \\\nbridge \\\nlibvirt_nwfilter_inet \\\nprerou= ting \\\n'{ type filter hook prerouting priority 1; policy accept; }'\n" + "nft \\\nadd \\\nrule \\\nbridge \\\nlibvirt_nwfilter_inet \\\npostrou= ting \\\noif \\\nvmap \\\n@vmap-oif\n" + "nft \\\nadd \\\nrule \\\nbridge \\\nlibvirt_nwfilter_inet \\\nprerout= ing \\\niif \\\nvmap \\\n@vmap-iif\n" + "nft \\\nadd \\\nchain \\\nbridge \\\nlibvirt_nwfilter_ethernet \\\nn-= vnet0-in \\\n'{ }'\n" + "nft \\\nadd \\\nchain \\\nbridge \\\nlibvirt_nwfilter_inet \\\nn-vnet= 0-in \\\n'{ }'\n" + "nft \\\nadd \\\nchain \\\nbridge \\\nlibvirt_nwfilter_ethernet \\\nn-= vnet0-out \\\n'{ }'\n" + "nft \\\nadd \\\nchain \\\nbridge \\\nlibvirt_nwfilter_inet \\\nn-vnet= 0-out \\\n'{ }'\n", +}; + + +static GHashTable * +virNWFilterCreateVarsFrom(GHashTable *vars1, + GHashTable *vars2) +{ + g_autoptr(GHashTable) res =3D virHashNew(virNWFilterVarValueHashFree); + + if (virNWFilterHashTablePutAll(vars1, res) < 0) + return NULL; + + if (virNWFilterHashTablePutAll(vars2, res) < 0) + return NULL; + + return g_steal_pointer(&res); +} + + +static void +virNWFilterRuleInstFree(virNWFilterRuleInst *inst) +{ + if (!inst) + return; + + g_clear_pointer(&inst->vars, g_hash_table_unref); + g_free(inst); +} + + +static void +virNWFilterInstReset(virNWFilterInst *inst) +{ + size_t i; + + for (i =3D 0; i < inst->nfilters; i++) + virNWFilterDefFree(inst->filters[i]); + VIR_FREE(inst->filters); + inst->nfilters =3D 0; + + for (i =3D 0; i < inst->nrules; i++) + virNWFilterRuleInstFree(inst->rules[i]); + VIR_FREE(inst->rules); + inst->nrules =3D 0; +} + + +static int +virNWFilterDefToInst(const char *xml, + GHashTable *vars, + virNWFilterInst *inst); + +static int +virNWFilterRuleDefToRuleInst(virNWFilterDef *def, + virNWFilterRuleDef *rule, + GHashTable *vars, + virNWFilterInst *inst) +{ + virNWFilterRuleInst *ruleinst; + int ret =3D -1; + + ruleinst =3D g_new0(virNWFilterRuleInst, 1); + + ruleinst->chainSuffix =3D def->chainsuffix; + ruleinst->chainPriority =3D def->chainPriority; + ruleinst->def =3D rule; + ruleinst->priority =3D rule->priority; + ruleinst->vars =3D virHashNew(virNWFilterVarValueHashFree); + + if (virNWFilterHashTablePutAll(vars, ruleinst->vars) < 0) + goto cleanup; + + VIR_APPEND_ELEMENT(inst->rules, inst->nrules, ruleinst); + + ret =3D 0; + cleanup: + virNWFilterRuleInstFree(ruleinst); + return ret; +} + + +static int +virNWFilterIncludeDefToRuleInst(virNWFilterIncludeDef *inc, + GHashTable *vars, + virNWFilterInst *inst) +{ + g_autoptr(GHashTable) tmpvars =3D NULL; + int ret =3D -1; + g_autofree char *xml =3D NULL; + + xml =3D g_strdup_printf("%s/nwfilterxml2firewalldata/%s.xml", abs_srcd= ir, + inc->filterref); + + /* create a temporary hashmap for depth-first tree traversal */ + if (!(tmpvars =3D virNWFilterCreateVarsFrom(inc->params, + vars))) + goto cleanup; + + if (virNWFilterDefToInst(xml, + tmpvars, + inst) < 0) + goto cleanup; + + ret =3D 0; + cleanup: + if (ret < 0) + virNWFilterInstReset(inst); + return ret; +} + +static int +virNWFilterDefToInst(const char *xml, + GHashTable *vars, + virNWFilterInst *inst) +{ + size_t i; + int ret =3D -1; + virNWFilterDef *def =3D virNWFilterDefParse(NULL, xml, 0); + + if (!def) + return -1; + + VIR_APPEND_ELEMENT_COPY(inst->filters, inst->nfilters, def); + + for (i =3D 0; i < def->nentries; i++) { + if (def->filterEntries[i]->rule) { + if (virNWFilterRuleDefToRuleInst(def, + def->filterEntries[i]->rule, + vars, + inst) < 0) + goto cleanup; + } else if (def->filterEntries[i]->include) { + if (virNWFilterIncludeDefToRuleInst(def->filterEntries[i]->inc= lude, + vars, + inst) < 0) + goto cleanup; + } + } + + ret =3D 0; + cleanup: + if (ret < 0) + virNWFilterInstReset(inst); + return ret; +} + + +static void testRemoveCommonRules(char *rules) +{ + size_t i; + char *offset =3D rules; + + for (i =3D 0; i < G_N_ELEMENTS(commonRules); i++) { + char *tmp =3D strstr(offset, commonRules[i]); + size_t len =3D strlen(commonRules[i]); + if (tmp) { + memmove(tmp, tmp + len, (strlen(tmp) + 1) - len); + offset =3D tmp; + } + } +} + + +static int testSetOneParameter(GHashTable *vars, + const char *name, + const char *value) +{ + virNWFilterVarValue *val; + + if ((val =3D virHashLookup(vars, name)) =3D=3D NULL) { + val =3D virNWFilterVarValueCreateSimpleCopyValue(value); + if (!val) + return -1; + if (virHashUpdateEntry(vars, name, val) < 0) { + virNWFilterVarValueFree(val); + return -1; + } + } else { + if (virNWFilterVarValueAddValueCopy(val, value) < 0) + return -1; + } + + return 0; +} + +static int testSetDefaultParameters(GHashTable *vars) +{ + if (testSetOneParameter(vars, "IPSETNAME", "tck_test") < 0 || + testSetOneParameter(vars, "A", "1.1.1.1") || + testSetOneParameter(vars, "A", "2.2.2.2") || + testSetOneParameter(vars, "A", "3.3.3.3") || + testSetOneParameter(vars, "A", "3.3.3.3") || + testSetOneParameter(vars, "B", "80") || + testSetOneParameter(vars, "B", "90") || + testSetOneParameter(vars, "B", "80") || + testSetOneParameter(vars, "B", "80") || + testSetOneParameter(vars, "C", "1080") || + testSetOneParameter(vars, "C", "1090") || + testSetOneParameter(vars, "C", "1100") || + testSetOneParameter(vars, "C", "1110")) + return -1; + return 0; +} + +static void +testCommandDryRunCallback(const char *const*args, + const char *const*env G_GNUC_UNUSED, + const char *input G_GNUC_UNUSED, + char **output, + char **error G_GNUC_UNUSED, + int *status, + void *opaque G_GNUC_UNUSED) +{ + if (STRNEQ(args[0], "nft")) { + return; + } + + /* simulate an empty existing set rules */ + if (STREQ(args[1], "list") && STREQ(args[2], "tables")) { + *output =3D g_strdup("table nothing\n"); + *status =3D EXIT_SUCCESS; + } else if (STREQ(args[1], "list") && STREQ(args[2], "chains")) { + *output =3D g_strdup("chain nothing\n"); + *status =3D EXIT_SUCCESS; + } +} + +static int testCompareXMLToArgvFiles(const char *xml, + const char *cmdline) +{ + g_autofree char *actualargv =3D NULL; + g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; + g_autoptr(GHashTable) vars =3D virHashNew(virNWFilterVarValueHashFree); + virNWFilterInst inst =3D { 0 }; + int ret =3D -1; + g_autoptr(virCommandDryRunToken) dryRunToken =3D virCommandDryRunToken= New(); + + virCommandSetDryRun(dryRunToken, &buf, true, true, testCommandDryRunCa= llback, NULL); + + if (testSetDefaultParameters(vars) < 0) + goto cleanup; + + if (virNWFilterDefToInst(xml, + vars, + &inst) < 0) + goto cleanup; + + if (nftables_driver.applyNewRules("vnet0", inst.rules, inst.nrules) < = 0) + goto cleanup; + + actualargv =3D virBufferContentAndReset(&buf); + + testRemoveCommonRules(actualargv); + + if (virTestCompareToFileFull(actualargv, cmdline, false) < 0) + goto cleanup; + + ret =3D 0; + + cleanup: + virNWFilterInstReset(&inst); + return ret; +} + +struct testInfo { + const char *name; +}; + + +static int +testCompareXMLToIPTablesHelper(const void *data) +{ + int result =3D -1; + const struct testInfo *info =3D data; + g_autofree char *xml =3D NULL; + g_autofree char *args =3D NULL; + + xml =3D g_strdup_printf("%s/nwfilterxml2firewalldata/%s.xml", + abs_srcdir, info->name); + + args =3D g_strdup_printf("%s/nwfilterxml2firewalldata/%s-%s.nftables.a= rgs", + abs_srcdir, info->name, RULESTYPE); + + result =3D testCompareXMLToArgvFiles(xml, args); + + return result; +} + + +static int +mymain(void) +{ + int ret =3D 0; + +# define DO_TEST(name) \ + do { \ + static struct testInfo info =3D { \ + name, \ + }; \ + if (virTestRun("NWFilter XML-2-firewall " name, \ + testCompareXMLToIPTablesHelper, &info) < 0) \ + ret =3D -1; \ + } while (0) + + DO_TEST("ah"); + DO_TEST("ah-ipv6"); + DO_TEST("all"); + DO_TEST("all-ipv6"); + DO_TEST("arp"); + DO_TEST("comment"); + DO_TEST("conntrack"); + DO_TEST("esp"); + DO_TEST("esp-ipv6"); + DO_TEST("example-1"); + DO_TEST("example-2"); + DO_TEST("hex-data"); + DO_TEST("icmp-direction2"); + DO_TEST("icmp-direction3"); + DO_TEST("icmp-direction"); + DO_TEST("icmp"); + DO_TEST("icmpv6"); + DO_TEST("igmp"); + DO_TEST("ip"); + DO_TEST("ipt-no-macspoof"); + DO_TEST("ipv6"); + DO_TEST("iter1"); + DO_TEST("iter2"); + DO_TEST("iter3"); + DO_TEST("mac"); + DO_TEST("rarp"); + DO_TEST("sctp"); + DO_TEST("sctp-ipv6"); + DO_TEST("stp"); + DO_TEST("target2"); + DO_TEST("target"); + DO_TEST("tcp"); + DO_TEST("tcp-ipv6"); + DO_TEST("udp"); + DO_TEST("udp-ipv6"); + DO_TEST("udplite"); + DO_TEST("udplite-ipv6"); + DO_TEST("vlan"); + + return ret =3D=3D 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIR_TEST_MAIN_PRELOAD(mymain, VIR_TEST_MOCK("virfirewall")) + +#else /* ! defined (__linux__) */ + +int main(void) +{ + return EXIT_AM_SKIP; +} + +#endif /* ! defined (__linux__) */ --=20 2.43.0 From nobody Sat May 30 15:29:22 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) client-ip=38.145.34.151; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1779125588; cv=none; d=zohomail.com; s=zohoarc; b=fSLmZ4CYdXcp0D+j19NBqRTMIVSaTtM9ani/7VbfBk8TMjnJM4diQ/zgxLugToPLWiiDOM7iF5kHJKBaiBVFqWOt2PWw/ky/Br1flF8yGvTKKyb8TAKx+rvqnxxPGS0i2iNxNBRpbP9wrC9SbVWzFSUdDQyD5SYqBouDFkGdW8Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1779125588; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=JzLwO2Z+U8ILeGuhRATaU/1U6oW8ZitjZr2vfwOoKkU=; b=HT7n9pmYAYKri5y3UULIoatOQOzlPL5jPjZuI/10r0qd9P9dnQegFTzMAHb9Kuf7923fOwBwyGSbnLZ1+0uSMpYPCt9UMLiukmcCeFcIcq5HvMVXqCsCbnYAH3iNX0CUZkyjEqqG79BAZZ8gkZuYokR8oIINae9v3aM3DgZDqtw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [38.145.34.151]) by mx.zohomail.com with SMTPS id 1779125588505127.06093659959993; Mon, 18 May 2026 10:33:08 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 4F5BE418E9; Mon, 18 May 2026 13:33:07 -0400 (EDT) Received: from [172.19.199.5] (unknown [10.16.107.18]) by lists.libvirt.org (Postfix) with ESMTP id E2C4741B3E; Mon, 18 May 2026 13:30:11 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 9A2BC419C7; Mon, 18 May 2026 13:30:02 -0400 (EDT) Received: from mx11.osci.io (polly.osci.io [38.145.34.174]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 8D76245E11 for ; Mon, 18 May 2026 12:04:53 -0400 (EDT) Received: by mx11.osci.io (Postfix, from userid 994) id B509068593; Mon, 18 May 2026 08:31:57 -0400 (EDT) Received: from mail-ej1-x62b.google.com (mail-ej1-x62b.google.com [IPv6:2a00:1450:4864:20::62b]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by mx11.osci.io (Postfix) with ESMTPS id 0777768575 for ; Mon, 18 May 2026 08:31:57 -0400 (EDT) Received: by mail-ej1-x62b.google.com with SMTP id a640c23a62f3a-bd21ffaca79so458526566b.0 for ; Mon, 18 May 2026 05:31:56 -0700 (PDT) Received: from thinkiepadje.home (2a02-a470-a384-0-b529-3d3d-353-106e.fixed6.kpn.net. [2a02:a470:a384:0:b529:3d3d:353:106e]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bd4f4e4d54dsm553354066b.47.2026.05.18.05.29.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 May 2026 05:29:55 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=4.0.1 X-Greylist: delayed 62 seconds by postgrey-1.37 at lists.libvirt.org; Mon, 18 May 2026 12:04:53 EDT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779107396; x=1779712196; darn=lists.libvirt.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=JzLwO2Z+U8ILeGuhRATaU/1U6oW8ZitjZr2vfwOoKkU=; b=iL3m126jlftmP0h0i1QQ4tktD5hQ/ex7JiYQeZeZmvFTM35fbi2lO6NM8bLHD3Psmy FgZPzrjqhGbuHd/+D7p7axmng8D+db7QctkT86bFh95h4IqaHaWJeLYeDTPNv050024y nUPbjQzJ2Z4wsljwpcp0F7HQ7hBLkQDkStWGglWnl9hYxlVzLThZrvSXbjGtz1EyErpO Gwahyy1fWf+EOroNr/gWTI+yerJ7n1+lEfhNTUcnNM1OwCP1S+U5sasbciX4AzH8CCCb 6Cdc1cExWcFZvH754X5Rrd8IEXvoCAOclv+apTFY0igXFMaGqwkDo3Hj752PIpF0K9xe lkTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779107396; x=1779712196; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=JzLwO2Z+U8ILeGuhRATaU/1U6oW8ZitjZr2vfwOoKkU=; b=UZp0aI2ZqVy65C29+6sRyXih3t0mzd3vw08hMx49cD5+r1kUNanKBaKrmLeYswcxu6 gy9hPRmZvTtgyoSOwMjs7R9kfdTdD16pWJaRAMv++pVTJa8sAkB05l3spS3JsybGUCtq MMO3ITrrwSuZB0r6KkTcxW9m6+EJ/fyL6VYw6T1/EPSFUFPU21hZGJH1t3i7LLYLMpK2 RV+aYTpUbLhdhZf2oSD4Yl3fhpRn5gCwAYYlQKgv6PfAga34IeA/Y0XDQlyw9dvbQLVa v35DQctMcnWUQgEjcFjJ4N+jAeCMlEO24a0hqTHGkBLIPxTBIgBRiaXmE5w1fi3xhBeO 4FqA== X-Gm-Message-State: AOJu0Yxng7FzbsKYKUQCVWHovo9Q+rMbpo1FPBj9ntAeJHuB3wbx/QQI Kn6zP5traAJlI9aZyYQOtY4g0YiqjIKtBrjcQAyr0qRS96ORy/czKQtjNysd X-Gm-Gg: Acq92OFf4BXwsplRF5DLylkyiZ6yuTQD9J1Q3U9O+3MfMlMddCCC8F2Zof4ld0GsTfX heOdek1G/8Bg+91dAOSSuCpBnNfpilTCToXZb7hLFRNv3KUm/GvUDw1iRF24rKKoudUZBuV1/yD kJ9UUSZ45q/zXVqSQp5erQuUkVoiEpAHYMZpiy3tPuyUphA29ClzeUtRyYqWU1EqU8je8ZJnnSM FieUNgscC7tKruIL4DaSi/ca6girNStmTF3Fkl99L5L0YfutOvD/vt632NNuE3n8OA9f9wuAWFA IwVXT97kUlsMzjnbsWiqwiv623u8udVtsIpTWagjqHwvKUbbLLObX0Eqy5VFnpXUCFw9se/bN2D j+IomP4vQiCIvrRPeN83UjCaqNEr86R+zXnd6G5PHUvOKPQg46s1JlIeZl11M+OVyewxCGGVlL7 iGQS9OLlXbmHqtEnsUcrgJbJBbszKtCGx8wAjXV4RFYaZ7Cf4mGEzLDWQvAqqCFotsUEwnsOXM0 /ukZa8OIMZm89hxaC1J20o= X-Received: by 2002:a17:907:2d92:b0:bc1:c4d:cc70 with SMTP id a640c23a62f3a-bd51534c87bmr5441566b.2.1779107395802; Mon, 18 May 2026 05:29:55 -0700 (PDT) From: Dion Bosschieter To: devel@lists.libvirt.org Subject: [PATCH v7 4/4] nwfilter: add used firewall backend to nwfilterbinding Date: Mon, 18 May 2026 14:25:46 +0200 Message-ID: <20260518122547.163157-5-dionbosschieter@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260518122547.163157-1-dionbosschieter@gmail.com> References: <20260518122547.163157-1-dionbosschieter@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: KS46DZJ7Z3KE6DTRWLFGYP3FAQG4HA45 X-Message-ID-Hash: KS46DZJ7Z3KE6DTRWLFGYP3FAQG4HA45 X-MailFrom: SRS0=UfGQ=DP=gmail.com=dionbosschieter@osci.io X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: jean-louis@dupond.be, Dion Bosschieter X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1779125589307158500 Content-Type: text/plain; charset="utf-8" Updates nwfilterbinding.rng to support the 'backend' XML element. Defaults the def->backend field to the existing ebiptables firewall backend inside nwfilter_gentech_driver.c. This new element allows us to check the definition's firewall backend again= st the current firewall backend and remove old existing rules via the previous fir= ewall backend. This switch between firewall backends happens inside virNWFilterSwitchTechDriver. Updated virnwfilterbindingxml2xmltest to test parsing and formatting of the new nwfilterbinding backend element. Signed-off-by: Dion Bosschieter --- src/conf/schemas/nwfilterbinding.rng | 7 ++ src/conf/virnwfilterbindingdef.c | 17 +++- src/conf/virnwfilterbindingdef.h | 1 + src/nwfilter/nwfilter_driver.c | 1 + src/nwfilter/nwfilter_gentech_driver.c | 79 +++++++++++++++---- .../filter-vars.xml | 1 + .../simple-backend.xml | 10 +++ tests/virnwfilterbindingxml2xmltest.c | 1 + 8 files changed, 100 insertions(+), 17 deletions(-) create mode 100644 tests/virnwfilterbindingxml2xmldata/simple-backend.xml diff --git a/src/conf/schemas/nwfilterbinding.rng b/src/conf/schemas/nwfilt= erbinding.rng index c91312b09d..16ed745e0f 100644 --- a/src/conf/schemas/nwfilterbinding.rng +++ b/src/conf/schemas/nwfilterbinding.rng @@ -44,6 +44,13 @@ + + + + + + + diff --git a/src/conf/virnwfilterbindingdef.c b/src/conf/virnwfilterbinding= def.c index fe45c84347..ddd8a7e0a9 100644 --- a/src/conf/virnwfilterbindingdef.c +++ b/src/conf/virnwfilterbindingdef.c @@ -26,7 +26,6 @@ #include "virnwfilterbindingdef.h" #include "viruuid.h" =20 - #define VIR_FROM_THIS VIR_FROM_NWFILTER =20 void @@ -40,6 +39,7 @@ virNWFilterBindingDefFree(virNWFilterBindingDef *def) g_free(def->linkdevname); g_free(def->filter); g_clear_pointer(&def->filterparams, g_hash_table_unref); + g_free(def->backend); =20 g_free(def); } @@ -67,6 +67,8 @@ virNWFilterBindingDefCopy(virNWFilterBindingDef *src) if (virNWFilterHashTablePutAll(src->filterparams, ret->filterparams) <= 0) return NULL; =20 + ret->backend =3D g_strdup(src->backend); + return g_steal_pointer(&ret); } =20 @@ -143,8 +145,18 @@ virNWFilterBindingDefParseXML(xmlXPathContextPtr ctxt) =20 node =3D virXPathNode("./filterref", ctxt); if (node && - !(ret->filterparams =3D virNWFilterParseParamAttributes(node))) + !(ret->filterparams =3D virNWFilterParseParamAttributes(node))) { goto cleanup; + } + + if (virXPathNode("./backend", ctxt)) { + ret->backend =3D virXPathString("string(./backend/@name)", ctxt); + if (!ret->backend) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("filter binding has no firewall backend= name")); + goto cleanup; + } + } =20 return ret; =20 @@ -211,6 +223,7 @@ virNWFilterBindingDefFormatBuf(virBuffer *buf, if (virNWFilterFormatParamAttributes(buf, def->filterparams, def->filt= er) < 0) return -1; =20 + virBufferEscapeString(buf, "\n", def->backend); virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "\n"); =20 diff --git a/src/conf/virnwfilterbindingdef.h b/src/conf/virnwfilterbinding= def.h index 272ad686a0..16465df56d 100644 --- a/src/conf/virnwfilterbindingdef.h +++ b/src/conf/virnwfilterbindingdef.h @@ -36,6 +36,7 @@ struct _virNWFilterBindingDef { virMacAddr mac; char *filter; GHashTable *filterparams; + char *backend; }; =20 =20 diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c index 66f5fa7c18..9b981ddcbf 100644 --- a/src/nwfilter/nwfilter_driver.c +++ b/src/nwfilter/nwfilter_driver.c @@ -725,6 +725,7 @@ nwfilterBindingCreateXML(virConnectPtr conn, def =3D virNWFilterBindingDefParse(xml, NULL, flags); if (!def) return NULL; + def->backend =3D g_strdup(virFirewallBackendTypeToString(cfg->firewall= Backend)); =20 if (virNWFilterBindingCreateXMLEnsureACL(conn, def) < 0) goto cleanup; diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter= _gentech_driver.c index 29f80a8677..9dc99e848b 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -70,6 +70,20 @@ int virNWFilterTechDriversInit(bool privileged, virNWFil= terDriverConfig *config) } =20 =20 +static virNWFilterTechDriver * +virNWFilterTechDriversByName(const char *firewallBackend) +{ + size_t i =3D 0; + + for (i =3D 0; i < G_N_ELEMENTS(filter_tech_drivers); i++) { + if (STREQ(filter_tech_drivers[i]->name, firewallBackend)) + return filter_tech_drivers[i]; + } + + return 0; +} + + void virNWFilterTechDriversShutdown(void) { size_t i =3D 0; @@ -786,6 +800,33 @@ virNWFilterRollbackUpdateFilter(virNWFilterBindingDef = *binding) return techdriver->tearNewRules(binding->portdevname); } =20 +static int +virNWFilterSwitchTechDriver(virNWFilterDriverState *driver, + virNWFilterBindingObj *binding, + virNWFilterBindingDef *def) +{ + int ret =3D 0; + virNWFilterTechDriver *oldTechDriver =3D virNWFilterTechDriversByName(= def->backend); + g_autoptr(virNWFilterDriverConfig) cfg =3D virNWFilterDriverGetConfig(= driver); + + VIR_DEBUG("Detected change in nwfilter firewall backend '%1$s' -> '%2$= s', cleaning up '%1$s'", + def->backend, + virFirewallBackendTypeToString(driver->config->firewallBacke= nd)); + + // first we'll apply the rules with the new tech driver + if ((ret =3D virNWFilterInstantiateFilter(driver, def)) < 0) + return ret; + + // then we'll cleanup the rules from the old driver + if ((ret =3D oldTechDriver->allTeardown(def->portdevname)) < 0) + return ret; + + // update binding backend + def->backend =3D g_strdup(virFirewallBackendTypeToString(driver->confi= g->firewallBackend)); + + // save changed binding xml file + return virNWFilterBindingObjSave(binding, cfg->bindingDir); +} =20 static int virNWFilterTearOldFilter(virNWFilterBindingDef *binding) @@ -854,40 +895,49 @@ enum { =20 static int virNWFilterBuildOne(virNWFilterDriverState *driver, - virNWFilterBindingDef *binding, + virNWFilterBindingObj *binding, GHashTable *skipInterfaces, int step) { bool skipIface; int ret =3D 0; - VIR_DEBUG("Building filter for portdev=3D%s step=3D%d", binding->portd= evname, step); + virNWFilterBindingDef *def =3D virNWFilterBindingObjGetDef(binding); + + VIR_DEBUG("Building filter for portdev=3D%s step=3D%d", def->portdevna= me, step); =20 switch (step) { case STEP_APPLY_NEW: ret =3D virNWFilterUpdateInstantiateFilter(driver, - binding, + def, &skipIface); if (ret =3D=3D 0 && skipIface) { /* filter tree unchanged -- no update needed */ ret =3D virHashAddEntry(skipInterfaces, - binding->portdevname, + def->portdevname, (void *)~0); } break; - case STEP_ROLLBACK: - if (!virHashLookup(skipInterfaces, binding->portdevname)) - ret =3D virNWFilterRollbackUpdateFilter(binding); + if (!virHashLookup(skipInterfaces, def->portdevname)) + ret =3D virNWFilterRollbackUpdateFilter(def); break; - case STEP_SWITCH: - if (!virHashLookup(skipInterfaces, binding->portdevname)) - ret =3D virNWFilterTearOldFilter(binding); + if (!virHashLookup(skipInterfaces, def->portdevname)) + ret =3D virNWFilterTearOldFilter(def); break; - case STEP_APPLY_CURRENT: - ret =3D virNWFilterInstantiateFilter(driver, - binding); + // prev is always ebiptables if unset + if (def->backend =3D=3D NULL) + def->backend =3D g_strdup(ebiptables_driver.name); + + // detect change in backend + if (STRNEQ(def->backend, + virFirewallBackendTypeToString(driver->config->firewallBackend= ))) { + ret =3D virNWFilterSwitchTechDriver(driver, binding, def); + } else { + ret =3D virNWFilterInstantiateFilter(driver, def); + } + break; } =20 @@ -905,9 +955,8 @@ static int virNWFilterBuildIter(virNWFilterBindingObj *binding, void *opaque) { struct virNWFilterBuildData *data =3D opaque; - virNWFilterBindingDef *def =3D virNWFilterBindingObjGetDef(binding); =20 - return virNWFilterBuildOne(data->driver, def, + return virNWFilterBuildOne(data->driver, binding, data->skipInterfaces, data->step); } =20 diff --git a/tests/virnwfilterbindingxml2xmldata/filter-vars.xml b/tests/vi= rnwfilterbindingxml2xmldata/filter-vars.xml index dcff9640ce..5d4cb2bebf 100644 --- a/tests/virnwfilterbindingxml2xmldata/filter-vars.xml +++ b/tests/virnwfilterbindingxml2xmldata/filter-vars.xml @@ -8,4 +8,5 @@ + diff --git a/tests/virnwfilterbindingxml2xmldata/simple-backend.xml b/tests= /virnwfilterbindingxml2xmldata/simple-backend.xml new file mode 100644 index 0000000000..7b91448fbb --- /dev/null +++ b/tests/virnwfilterbindingxml2xmldata/simple-backend.xml @@ -0,0 +1,10 @@ + + + memtest + d54df46f-1ab5-4a22-8618-4560ef5fac2c + + + + + + diff --git a/tests/virnwfilterbindingxml2xmltest.c b/tests/virnwfilterbindi= ngxml2xmltest.c index bde21968fe..907755bd56 100644 --- a/tests/virnwfilterbindingxml2xmltest.c +++ b/tests/virnwfilterbindingxml2xmltest.c @@ -92,6 +92,7 @@ mymain(void) } while (0) =20 DO_TEST("simple"); + DO_TEST("simple-backend"); DO_TEST("filter-vars"); =20 return ret =3D=3D 0 ? EXIT_SUCCESS : EXIT_FAILURE; --=20 2.43.0