From nobody Wed Feb 11 03:34:54 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; 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 8.43.85.245 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=1770721421; cv=none; d=zohomail.com; s=zohoarc; b=YR6iTEWzdtje0cq7KSOcsIhMrtyXw/RfBuN+ilTSAb3qhO60c/p4o62caGy+Am7iGD0AdIfeWCPUXLYMnBRWPO3G1V1FhzgbuKv/oe4QESOVtdHkKhliB7UOXY4ZSgDfGXJ9Knw0VirsPAjTj+IshtzvmCeHrUjBVddbo59x/+Y= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1770721421; 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=zgYCVU5aOTtPh0kjTaow4fYksoK3YLbFFUFxYKxbYyk=; b=NUqentJNDEFRCLVGLqPDlMLxsyIHNl9O5ZrA458W7pnZdbjO/psokoMVuxaJ5FRplJBPZzEnshnYHiq4DImdtdAhfiMtBTECW0zYyEpQ5cAyKuz73CLtHPiAyGmAXuQAiuFUTadFRQohrzNff2HfugjBrfj8LaigKCjOUbWCplg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 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 [8.43.85.245]) by mx.zohomail.com with SMTPS id 1770721421168749.5528438750503; Tue, 10 Feb 2026 03:03:41 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id 460F844136; Tue, 10 Feb 2026 06:03:40 -0500 (EST) Received: from [172.19.199.6] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id BE3384405C; Tue, 10 Feb 2026 05:56:15 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id 7D2FB3FB97; Tue, 10 Feb 2026 05:18:06 -0500 (EST) Received: from mail-ed1-f47.google.com (mail-ed1-f47.google.com [209.85.208.47]) (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 5AA404409B for ; Tue, 10 Feb 2026 05:16:57 -0500 (EST) Received: by mail-ed1-f47.google.com with SMTP id 4fb4d7f45d1cf-65a25c3a86eso48297a12.2 for ; Tue, 10 Feb 2026 02:16:57 -0800 (PST) Received: from thinkiepadje.. ([217.21.255.154]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b8eda74a515sm492331466b.2.2026.02.10.02.16.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Feb 2026 02:16:55 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-5.3 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,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_PASS autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1770718616; x=1771323416; 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=zgYCVU5aOTtPh0kjTaow4fYksoK3YLbFFUFxYKxbYyk=; b=ZCc0B2UMcLFkp79FklJrWaZIGvs8W/xuWCliYdE2RX9Om8TST/IxwsYfXwgsF2tPsp otHKGXZz9KPwELLTWfyl9WubSWlSIzgd8Ff2TI1XSuU6UfA5/DwvB6M4P0XlCLluikBo 8WPc/k4DN3YPensMRjQZHMzUD2mgop0+A2jW4bi1gJx4rOI1O5JyKGbanHWcjo08oRkP LhBzSGxjc5E4Nv+qV2Gh8dtde7UDKt01Hn4QXhdM7j9HXVBhAm7NA1OMvRXoi+UFpXn+ kaTBVzn8cwC97NAETsWL2i4Fo07sWo2IBG2Rmy8d3NxO4YIV5+dz6uCuBtSiDoHuzqBk z4Cg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770718616; x=1771323416; 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=zgYCVU5aOTtPh0kjTaow4fYksoK3YLbFFUFxYKxbYyk=; b=Ac1+Hg9m+VVTm0otYAFuu+KkxTJBOEVUHN1d/cpGKcf3fiO4ADnO/rISc+FdHbjAg4 AAK2eKzkP66u0B8IVBaWM0+oJuM+ojSc0/hVJLjMy70Ist+44ExcgCMtnEYDPxqrQBJs pGRYfPlLeVJxEpeJuR5LJuQQKkexexqWKrURGyRYkDMIe6VqpsHmWVWSRSslLkgW1sp+ MoO2K33OySQ44Gde9yFBJ0uHXxk0BPD4ZGFs4dHDZTzOkfRmPfZl50+ja7FKpAQABbh5 HLj0jZ4h6ODu7lRCc6AVg6q/rSMnSh51QcY8loHBKM+ct2zwB5vac3kqKnmuTaWz15+9 BB1A== X-Gm-Message-State: AOJu0YyahUPDWpQeP0/kBvID+bwYJzHymWbdPi33AdfyBCdbBvLPKe9m D9xTaTJHzDEPZDVpyrSY+Sa/TMH0rOmlLYdQhWMhiqByEEr99Pr6mi1rPKa7 X-Gm-Gg: AZuq6aLuQzttcfiUqlrC1oze3Cqql1fp0SoOaIQx/VY3Rd6XMHER152atWxY8K8Aap+ SchA3Psu/1FULAzeJGu6TCP5jqFlPh1p/WcE/JhDjHjFG+mkB3tdjW1ibMOIB70BddTCxVJcxBj LKpW53N5FzwnCtZojBHuu8aKn8Fiee9HRv08kZ3fn/EGxNePJ+mvy0mUDUk84hspW8ch3SxnbXR q4glbtfi+rObeRmEHir1c4ukkSjwlw6mvRfZoyezDXqNCe1V8u4hCDOgCGNgdKaTD9gAUxC3ut+ PslH8BLIe9Ph37sevd14J/JzeTBlZAIE+x/wBOm2EqBOLuYWDofD9q2zngBTenrbyVRLiZ85Em6 f0f425ggNOfBetw49uPBsBCMv/sy27yAphLvqYWt6ZNRQ8oY53ATlO4LbJsaMXncozldZBdd8lO lGJVkrKKgJgjM7z7y0Mcjfx3EVULZmWdcB X-Received: by 2002:a17:907:9454:b0:b80:5ae7:5d94 with SMTP id a640c23a62f3a-b8f5438275cmr84430666b.7.1770718615655; Tue, 10 Feb 2026 02:16:55 -0800 (PST) From: Dion Bosschieter To: devel@lists.libvirt.org Subject: [PATCH v4 2/5] nwfilter: move shared nwfilter driver functions into nwfilter_tech_driver.c Date: Tue, 10 Feb 2026 11:16:26 +0100 Message-ID: <20260210101629.1084065-3-dionbosschieter@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260210101629.1084065-1-dionbosschieter@gmail.com> References: <20260210101629.1084065-1-dionbosschieter@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: 2NEFATNCMEUTJJ2O3EM2AMFZDLYOKMXF X-Message-ID-Hash: 2NEFATNCMEUTJJ2O3EM2AMFZDLYOKMXF X-MailFrom: dionbosschieter@gmail.com 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: 1770721422891158500 Content-Type: text/plain; charset="utf-8" Introduce nwfilter_tech_driver.c which holds shared non driver specific methods. The following logic can be reused by new nwfilter drivers, which are not ebiptables specific: - data type print logic, used for constructing ascii cli arguments out of nwfilter data; - chain jump proto type l3_proto_idx logic; - virNWFilterRule sorting. Signed-off-by: Dion Bosschieter --- src/nwfilter/meson.build | 1 + src/nwfilter/nwfilter_ebiptables_driver.c | 263 +--------------------- src/nwfilter/nwfilter_tech_driver.c | 250 ++++++++++++++++++++ src/nwfilter/nwfilter_tech_driver.h | 52 ++++- 4 files changed, 301 insertions(+), 265 deletions(-) create mode 100644 src/nwfilter/nwfilter_tech_driver.c diff --git a/src/nwfilter/meson.build b/src/nwfilter/meson.build index de3d202267..9e8a4797c5 100644 --- a/src/nwfilter/meson.build +++ b/src/nwfilter/meson.build @@ -1,6 +1,7 @@ nwfilter_driver_sources =3D [ 'nwfilter_driver.c', 'nwfilter_gentech_driver.c', + 'nwfilter_tech_driver.c', 'nwfilter_dhcpsnoop.c', 'nwfilter_ebiptables_driver.c', 'nwfilter_learnipaddr.c', diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfil= ter_ebiptables_driver.c index c7f6141cd9..6769a2fb42 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -25,7 +25,6 @@ #include #include #include -#include =20 #include "internal.h" =20 @@ -35,6 +34,7 @@ #include "virerror.h" #include "nwfilter_conf.h" #include "nwfilter_ebiptables_driver.h" +#include "nwfilter_tech_driver.h" #include "virfile.h" #include "configmake.h" #include "virstring.h" @@ -83,25 +83,6 @@ static void ebiptablesDriverShutdown(void); static int ebtablesCleanAll(const char *ifname); static int ebiptablesAllTeardown(const char *ifname); =20 -struct virNWFilterUShortMap { - unsigned short attr; - const char *val; -}; - - -enum virNWFilterProtoIdx { - VIR_NWFILTER_PROTO_IDX_IPV4 =3D 0, - VIR_NWFILTER_PROTO_IDX_IPV6, - VIR_NWFILTER_PROTO_IDX_ARP, - VIR_NWFILTER_PROTO_IDX_RARP, - VIR_NWFILTER_PROTO_IDX_MAC, - VIR_NWFILTER_PROTO_IDX_VLAN, - VIR_NWFILTER_PROTO_IDX_STP, - VIR_NWFILTER_PROTO_IDX_LAST -}; - -#define virNWFilterUShortMapEntryIdx(IDX, ATT, VAL) [IDX] =3D { .attr =3D = ATT, .val =3D VAL } - /* 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 @@ -118,7 +99,6 @@ static const struct virNWFilterUShortMap l3_protocols[] = =3D { virNWFilterUShortMapEntryIdx(VIR_NWFILTER_PROTO_IDX_LAST, 0, = NULL), }; =20 - static char chainprefixes_host[3] =3D { CHAINPREFIX_HOST_IN, CHAINPREFIX_HOST_OUT, @@ -137,12 +117,6 @@ typedef struct { const char *targetChain; } iptablesBaseChainFW; =20 -typedef struct { - const char *ifname; - int nrules; - virNWFilterRuleInst **rules; -} virNWFilterChainCreateCallbackData; - static iptablesBaseChainFW fw_base_chains[] =3D { {"FORWARD", "1", VIRT_IN_CHAIN}, {"FORWARD", "2", VIRT_OUT_CHAIN}, @@ -150,206 +124,6 @@ static iptablesBaseChainFW fw_base_chains[] =3D { {"INPUT", "1", HOST_IN_CHAIN}, }; =20 -static int -virNWFilterPrintVar(virNWFilterVarCombIter *vars, - char *buf, int bufsize, - nwItemDesc *item, - bool *done) -{ - *done =3D false; - - if ((item->flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) { - const char *val; - - val =3D virNWFilterVarCombIterGetVarValue(vars, item->varAccess); - if (!val) { - /* error has been reported */ - return -1; - } - - if (virStrcpy(buf, val, bufsize) < 0) { - const char *varName; - - varName =3D virNWFilterVarAccessGetVarName(item->varAccess); - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Buffer too small to print variable '%1$s' in= to"), - varName); - return -1; - } - - *done =3D true; - } - return 0; -} - - -static int -_virNWFilterPrintDataType(virNWFilterVarCombIter *vars, - char *buf, int bufsize, - nwItemDesc *item, - bool asHex, bool directionIn) -{ - bool done; - g_autofree char *data =3D NULL; - uint8_t ctr; - g_auto(virBuffer) vb =3D VIR_BUFFER_INITIALIZER; - g_autofree char *flags =3D NULL; - - if (virNWFilterPrintVar(vars, buf, bufsize, item, &done) < 0) - return -1; - - if (done) - return 0; - - switch (item->datatype) { - case DATATYPE_IPADDR: - data =3D virSocketAddrFormat(&item->u.ipaddr); - if (!data) - return -1; - if (g_snprintf(buf, bufsize, "%s", data) >=3D bufsize) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("buffer too small for IP address")); - return -1; - } - break; - - case DATATYPE_IPV6ADDR: - data =3D virSocketAddrFormat(&item->u.ipaddr); - if (!data) - return -1; - - if (g_snprintf(buf, bufsize, "%s", data) >=3D bufsize) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("buffer too small for IPv6 address")); - return -1; - } - break; - - case DATATYPE_MACADDR: - case DATATYPE_MACMASK: - if (bufsize < VIR_MAC_STRING_BUFLEN) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Buffer too small for MAC address")); - return -1; - } - - virMacAddrFormat(&item->u.macaddr, buf); - break; - - case DATATYPE_IPV6MASK: - case DATATYPE_IPMASK: - if (g_snprintf(buf, bufsize, "%d", - item->u.u8) >=3D bufsize) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Buffer too small for uint8 type")); - return -1; - } - break; - - case DATATYPE_UINT32: - case DATATYPE_UINT32_HEX: - if (g_snprintf(buf, bufsize, asHex ? "0x%x" : "%u", - item->u.u32) >=3D bufsize) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Buffer too small for uint32 type")); - return -1; - } - break; - - case DATATYPE_UINT16: - case DATATYPE_UINT16_HEX: - if (g_snprintf(buf, bufsize, asHex ? "0x%x" : "%d", - item->u.u16) >=3D bufsize) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Buffer too small for uint16 type")); - return -1; - } - break; - - case DATATYPE_UINT8: - case DATATYPE_UINT8_HEX: - if (g_snprintf(buf, bufsize, asHex ? "0x%x" : "%d", - item->u.u8) >=3D bufsize) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Buffer too small for uint8 type")); - return -1; - } - break; - - case DATATYPE_IPSETNAME: - if (virStrcpy(buf, item->u.ipset.setname, bufsize) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Buffer to small for ipset name")); - return -1; - } - break; - - case DATATYPE_IPSETFLAGS: - for (ctr =3D 0; ctr < item->u.ipset.numFlags; ctr++) { - if (ctr !=3D 0) - virBufferAddLit(&vb, ","); - if ((item->u.ipset.flags & (1 << ctr))) { - if (directionIn) - virBufferAddLit(&vb, "dst"); - else - virBufferAddLit(&vb, "src"); - } else { - if (directionIn) - virBufferAddLit(&vb, "src"); - else - virBufferAddLit(&vb, "dst"); - } - } - - flags =3D virBufferContentAndReset(&vb); - - if (virStrcpy(buf, flags, bufsize) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Buffer too small for IPSETFLAGS type")); - return -1; - } - break; - - case DATATYPE_STRING: - case DATATYPE_STRINGCOPY: - case DATATYPE_BOOLEAN: - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Cannot print data type %1$x"), item->datatype); - return -1; - case DATATYPE_LAST: - default: - virReportEnumRangeError(virNWFilterAttrDataType, item->datatype); - return -1; - } - - return 0; -} - - -static int -virNWFilterPrintDataType(virNWFilterVarCombIter *vars, - char *buf, int bufsize, - nwItemDesc *item) -{ - return _virNWFilterPrintDataType(vars, buf, bufsize, item, 0, 0); -} - -static int -virNWFilterPrintDataTypeDirection(virNWFilterVarCombIter *vars, - char *buf, int bufsize, - nwItemDesc *item, bool directionIn) -{ - return _virNWFilterPrintDataType(vars, buf, bufsize, item, 0, directio= nIn); -} - -static int -virNWFilterPrintDataTypeAsHex(virNWFilterVarCombIter *vars, - char *buf, int bufsize, - nwItemDesc *item) -{ - return _virNWFilterPrintDataType(vars, buf, bufsize, item, 1, 0); -} - =20 static int ebtablesHandleEthHdr(virFirewall *fw, @@ -3041,41 +2815,6 @@ ebtablesCleanAll(const char *ifname) } =20 =20 -static int -virNWFilterRuleInstSort(const void *a, const void *b) -{ - const virNWFilterRuleInst *insta =3D a; - const virNWFilterRuleInst *instb =3D b; - const char *root =3D virNWFilterChainSuffixTypeToString( - VIR_NWFILTER_CHAINSUFFIX_ROOT); - bool root_a =3D STREQ(insta->chainSuffix, root); - bool root_b =3D STREQ(instb->chainSuffix, 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 int -virNWFilterRuleInstSortPtr(const void *a, - const void *b, - void *opaque G_GNUC_UNUSED) -{ - virNWFilterRuleInst * const *insta =3D a; - virNWFilterRuleInst * const *instb =3D b; - return virNWFilterRuleInstSort(*insta, *instb); -} - - static int ebiptablesFilterOrderSort(const void *va, const void *vb, diff --git a/src/nwfilter/nwfilter_tech_driver.c b/src/nwfilter/nwfilter_te= ch_driver.c new file mode 100644 index 0000000000..cfe016aef0 --- /dev/null +++ b/src/nwfilter/nwfilter_tech_driver.c @@ -0,0 +1,250 @@ +/* + * nwfilter_tech_driver.c: common/shared functions used in nwfilter gentec= h drivers + * + * 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 "nwfilter_tech_driver.h" +#include "nwfilter_conf.h" + +#define VIR_FROM_THIS VIR_FROM_NWFILTER + +int virNWFilterRuleInstSort(const void *a, const void *b) +{ + const virNWFilterRuleInst *insta =3D a; + const virNWFilterRuleInst *instb =3D b; + const char *root =3D virNWFilterChainSuffixTypeToString( + VIR_NWFILTER_CHAINSUFFIX_ROOT); + bool root_a =3D STREQ(insta->chainSuffix, root); + bool root_b =3D STREQ(instb->chainSuffix, 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; +} + + +int virNWFilterRuleInstSortPtr(const void *a, + const void *b, + void *opaque G_GNUC_UNUSED) +{ + virNWFilterRuleInst * const *insta =3D a; + virNWFilterRuleInst * const *instb =3D b; + return virNWFilterRuleInstSort(*insta, *instb); +} + +int virNWFilterPrintVar(virNWFilterVarCombIter *vars, + char *buf, int bufsize, + nwItemDesc *item, + bool *done) +{ + *done =3D false; + + if ((item->flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) { + const char *val; + + val =3D virNWFilterVarCombIterGetVarValue(vars, item->varAccess); + if (!val) { + /* error has been reported */ + return -1; + } + + if (virStrcpy(buf, val, bufsize) < 0) { + const char *varName; + + varName =3D virNWFilterVarAccessGetVarName(item->varAccess); + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Buffer too small to print variable '%1$s' in= to"), + varName); + return -1; + } + + *done =3D true; + } + return 0; +} + +static int +_virNWFilterPrintDataType(virNWFilterVarCombIter *vars, + char *buf, int bufsize, + nwItemDesc *item, + bool asHex, bool directionIn) +{ + bool done; + g_autofree char *data =3D NULL; + uint8_t ctr; + g_auto(virBuffer) vb =3D VIR_BUFFER_INITIALIZER; + g_autofree char *flags =3D NULL; + + if (virNWFilterPrintVar(vars, buf, bufsize, item, &done) < 0) + return -1; + + if (done) + return 0; + + switch (item->datatype) { + case DATATYPE_IPADDR: + data =3D virSocketAddrFormat(&item->u.ipaddr); + if (!data) + return -1; + if (g_snprintf(buf, bufsize, "%s", data) >=3D bufsize) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("buffer too small for IP address")); + return -1; + } + break; + + case DATATYPE_IPV6ADDR: + data =3D virSocketAddrFormat(&item->u.ipaddr); + if (!data) + return -1; + + if (g_snprintf(buf, bufsize, "%s", data) >=3D bufsize) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("buffer too small for IPv6 address")); + return -1; + } + break; + + case DATATYPE_MACADDR: + case DATATYPE_MACMASK: + if (bufsize < VIR_MAC_STRING_BUFLEN) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Buffer too small for MAC address")); + return -1; + } + + virMacAddrFormat(&item->u.macaddr, buf); + break; + + case DATATYPE_IPV6MASK: + case DATATYPE_IPMASK: + if (g_snprintf(buf, bufsize, "%d", + item->u.u8) >=3D bufsize) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Buffer too small for uint8 type")); + return -1; + } + break; + + case DATATYPE_UINT32: + case DATATYPE_UINT32_HEX: + if (g_snprintf(buf, bufsize, asHex ? "0x%x" : "%u", + item->u.u32) >=3D bufsize) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Buffer too small for uint32 type")); + return -1; + } + break; + + case DATATYPE_UINT16: + case DATATYPE_UINT16_HEX: + if (g_snprintf(buf, bufsize, asHex ? "0x%x" : "%d", + item->u.u16) >=3D bufsize) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Buffer too small for uint16 type")); + return -1; + } + break; + + case DATATYPE_UINT8: + case DATATYPE_UINT8_HEX: + if (g_snprintf(buf, bufsize, asHex ? "0x%x" : "%d", + item->u.u8) >=3D bufsize) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Buffer too small for uint8 type")); + return -1; + } + break; + + case DATATYPE_IPSETNAME: + if (virStrcpy(buf, item->u.ipset.setname, bufsize) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Buffer to small for ipset name")); + return -1; + } + break; + + case DATATYPE_IPSETFLAGS: + for (ctr =3D 0; ctr < item->u.ipset.numFlags; ctr++) { + if (ctr !=3D 0) + virBufferAddLit(&vb, ","); + if ((item->u.ipset.flags & (1 << ctr))) { + if (directionIn) + virBufferAddLit(&vb, "dst"); + else + virBufferAddLit(&vb, "src"); + } else { + if (directionIn) + virBufferAddLit(&vb, "src"); + else + virBufferAddLit(&vb, "dst"); + } + } + + flags =3D virBufferContentAndReset(&vb); + + if (virStrcpy(buf, flags, bufsize) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Buffer too small for IPSETFLAGS type")); + return -1; + } + break; + + case DATATYPE_STRING: + case DATATYPE_STRINGCOPY: + case DATATYPE_BOOLEAN: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Cannot print data type %1$x"), item->datatype); + return -1; + case DATATYPE_LAST: + default: + virReportEnumRangeError(virNWFilterAttrDataType, item->datatype); + return -1; + } + + return 0; +} + +int virNWFilterPrintDataType(virNWFilterVarCombIter *vars, + char *buf, int bufsize, + nwItemDesc *item) +{ + return _virNWFilterPrintDataType(vars, buf, bufsize, item, 0, 0); +} + +int virNWFilterPrintDataTypeDirection(virNWFilterVarCombIter *vars, + char *buf, int bufsize, + nwItemDesc *item, bool directionIn) +{ + return _virNWFilterPrintDataType(vars, buf, bufsize, item, 0, directio= nIn); +} + +int virNWFilterPrintDataTypeAsHex(virNWFilterVarCombIter *vars, + char *buf, int bufsize, + nwItemDesc *item) +{ + return _virNWFilterPrintDataType(vars, buf, bufsize, item, 1, 0); +} diff --git a/src/nwfilter/nwfilter_tech_driver.h b/src/nwfilter/nwfilter_te= ch_driver.h index a4af0bf6d5..8f9d605529 100644 --- a/src/nwfilter/nwfilter_tech_driver.h +++ b/src/nwfilter/nwfilter_tech_driver.h @@ -24,9 +24,7 @@ #pragma once =20 #include "virnwfilterobj.h" - -typedef struct _virNWFilterTechDriver virNWFilterTechDriver; - +#include "virstring.h" =20 typedef struct _virNWFilterRuleInst virNWFilterRuleInst; struct _virNWFilterRuleInst { @@ -38,6 +36,31 @@ struct _virNWFilterRuleInst { }; =20 =20 +typedef struct _virNWFilterChainCreateCallbackData virNWFilterChainCreateC= allbackData; +struct _virNWFilterChainCreateCallbackData { + const char *ifname; + int nrules; + virNWFilterRuleInst **rules; +}; + +struct virNWFilterUShortMap { + unsigned short attr; + const char *val; +}; + +enum virNWFilterProtoIdx { + VIR_NWFILTER_PROTO_IDX_IPV4 =3D 0, + VIR_NWFILTER_PROTO_IDX_IPV6, + VIR_NWFILTER_PROTO_IDX_ARP, + VIR_NWFILTER_PROTO_IDX_RARP, + VIR_NWFILTER_PROTO_IDX_MAC, + VIR_NWFILTER_PROTO_IDX_VLAN, + VIR_NWFILTER_PROTO_IDX_STP, + VIR_NWFILTER_PROTO_IDX_LAST +}; + +#define virNWFilterUShortMapEntryIdx(IDX, ATT, VAL) [IDX] =3D { .attr =3D = ATT, .val =3D VAL } + typedef int (*virNWFilterTechDrvInit)(bool privileged); typedef void (*virNWFilterTechDrvShutdown)(void); =20 @@ -69,6 +92,7 @@ enum techDrvFlags { TECHDRV_FLAG_INITIALIZED =3D (1 << 0), }; =20 +typedef struct _virNWFilterTechDriver virNWFilterTechDriver; struct _virNWFilterTechDriver { const char *name; enum techDrvFlags flags; @@ -87,3 +111,25 @@ struct _virNWFilterTechDriver { virNWFilterDropAllRules applyDropAllRules; virNWFilterRemoveBasicRules removeBasicRules; }; + +int virNWFilterRuleInstSort(const void *a, const void *b); + +int virNWFilterRuleInstSortPtr(const void *a, + const void *b, + void *opaque); +int virNWFilterPrintVar(virNWFilterVarCombIter *vars, + char *buf, int bufsize, + nwItemDesc *item, + bool *done); + +int virNWFilterPrintDataType(virNWFilterVarCombIter *vars, + char *buf, int bufsize, + nwItemDesc *item); + +int virNWFilterPrintDataTypeDirection(virNWFilterVarCombIter *vars, + char *buf, int bufsize, + nwItemDesc *item, bool directionIn); + +int virNWFilterPrintDataTypeAsHex(virNWFilterVarCombIter *vars, + char *buf, int bufsize, + nwItemDesc *item); --=20 2.43.0