From nobody Tue Jan 21 07:32:07 2025 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=fail; 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=fail(p=none dis=none) header.from=solinno.co.uk Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 173634311580867.44972714745973; Wed, 8 Jan 2025 05:31:55 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 996) id ED5F2131E; Wed, 8 Jan 2025 08:31:53 -0500 (EST) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id BBEC01272; Wed, 8 Jan 2025 08:31:29 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 996) id 02252E7A; Wed, 8 Jan 2025 08:31:27 -0500 (EST) Received: from doppler.solinno.uk (doppler.solinno.uk [81.2.106.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 613C6E7A for ; Wed, 8 Jan 2025 08:31:26 -0500 (EST) Received: from plato.solinno.co.uk (plato.dyn.solinno.co.uk [192.168.2.203]) by doppler.solinno.uk (Postfix) with ESMTPSA id 910F562004; Wed, 8 Jan 2025 13:31:25 +0000 (GMT) Received: by plato.solinno.co.uk (Postfix, from userid 1000) id 5F66A40; Wed, 08 Jan 2025 13:31:41 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.6 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_PASS autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=solinno.co.uk; s=mail; t=1736343085; bh=AILS8ggqQPpep3f/UZpot8z3NnkQ6j9DbU0EZBvUm3I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Z+rbKbGhF7Cex6SpCgoarUArth4bB7cUf7oNiQ4dda//npnmLH4kwj0e036LeHqh7 /O6I4JxoPa6LXIpYw4enwPHf96OLS8DvVJ1oiGc7h0loCEwGtvbeSi/2V5j6pIJ4cp i/0tYDrKRBB/I4GOAAwDgAs5FvFkth1SnKhqVOww= From: Leigh Brown To: devel@lists.libvirt.org, Laine Stump Subject: [PATCH v4 1/4] util: add netlink bridge vlan filtering Date: Wed, 8 Jan 2025 13:31:27 +0000 Message-ID: <20250108133130.182335-2-leigh@solinno.co.uk> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250108133130.182335-1-leigh@solinno.co.uk> References: <20250108133130.182335-1-leigh@solinno.co.uk> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: 523RGCFWCZ2OFKEMHLCVF47SY5OBMEJX X-Message-ID-Hash: 523RGCFWCZ2OFKEMHLCVF47SY5OBMEJX X-MailFrom: leigh@solinno.co.uk X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: Leigh Brown X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Computed bodyhash is different from the expected one) X-ZM-MESSAGEID: 1736343116984116600 Content-Type: text/plain; charset="utf-8" Enable capability to add and remove vlan filters for a standard linux bridge using netlink. New function virNetlinkBridgeVlanFilterSet can be used to add or remove a vlan filter to a given bridge interface. Signed-off-by: Leigh Brown Reviewed-by: Laine Stump --- src/util/virnetlink.c | 66 +++++++++++++++++++++++++++++++++++++++++++ src/util/virnetlink.h | 7 +++++ 2 files changed, 73 insertions(+) diff --git a/src/util/virnetlink.c b/src/util/virnetlink.c index 24cd69a385..206646d9d7 100644 --- a/src/util/virnetlink.c +++ b/src/util/virnetlink.c @@ -701,6 +701,72 @@ virNetlinkDelLink(const char *ifname, virNetlinkTalkFa= llback fallback) return 0; } =20 +/** + * virNetlinkBridgeVlanFilterSet: + * + * @ifname: name of the link + * @cmd: netlink command, either RTM_SETLINK or RTM_DELLINK + * @flags: flags to use when adding the vlan filter + * @vid: vlan id to add or remove + * @error: netlink error code + * + * Add or remove a vlan filter from an interface associated with a + * bridge. + * + * Returns 0 on success, -1 on error. Additionally, if the @error is + * non-zero, then a netlink failure occurred, but no error message + * is generated leaving it up to the caller to handle the condition. + */ +int +virNetlinkBridgeVlanFilterSet(const char *ifname, + int cmd, + const unsigned short flags, + const short vid, + int *error) +{ + struct ifinfomsg ifm =3D { .ifi_family =3D PF_BRIDGE }; + struct bridge_vlan_info vinfo =3D { .flags =3D flags, .vid =3D vid }; + struct nlattr *afspec =3D NULL; + g_autoptr(virNetlinkMsg) nl_msg =3D NULL; + g_autofree struct nlmsghdr *resp =3D NULL; + unsigned int resp_len =3D 0; + + *error =3D 0; + + if (vid < 1 || vid > 4095) { + virReportError(ERANGE, _("vlanid out of range: %1$d"), vid); + return -1; + } + + if (!(cmd =3D=3D RTM_SETLINK || cmd =3D=3D RTM_DELLINK)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid vlan filter command %1$d"), cmd); + return -1; + } + + if (virNetDevGetIndex(ifname, &ifm.ifi_index) < 0) + return -1; + + nl_msg =3D virNetlinkMsgNew(cmd, NLM_F_REQUEST); + + NETLINK_MSG_APPEND(nl_msg, sizeof(ifm), &ifm); + + NETLINK_MSG_NEST_START(nl_msg, afspec, IFLA_AF_SPEC); + NETLINK_MSG_PUT(nl_msg, IFLA_BRIDGE_VLAN_INFO, sizeof(vinfo), &vinfo); + NETLINK_MSG_NEST_END(nl_msg, afspec); + + if (virNetlinkTalk(ifname, nl_msg, 0, 0, &resp, &resp_len, error, NULL= ) < 0) + return -1; + + if (resp->nlmsg_type !=3D NLMSG_ERROR && resp->nlmsg_type !=3D NLMSG_D= ONE) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("malformed netlink response message")); + return -1; + } + + return 0; +} + /** * virNetlinkGetNeighbor: * diff --git a/src/util/virnetlink.h b/src/util/virnetlink.h index 75192f645f..327fb426a1 100644 --- a/src/util/virnetlink.h +++ b/src/util/virnetlink.h @@ -25,6 +25,7 @@ #if defined(WITH_LIBNL) =20 # include +# include =20 typedef struct nl_msg virNetlinkMsg; G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNetlinkMsg, nlmsg_free); @@ -76,6 +77,12 @@ typedef int (*virNetlinkTalkFallback)(const char *ifname= ); =20 int virNetlinkDelLink(const char *ifname, virNetlinkTalkFallback fallback); =20 +int virNetlinkBridgeVlanFilterSet(const char *ifname, + int cmd, + const unsigned short flags, + const short vid, + int *error); + int virNetlinkGetErrorCode(struct nlmsghdr *resp, unsigned int recvbuflen); =20 int virNetlinkDumpLink(const char *ifname, int ifindex, --=20 2.39.5