From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id D808B1FF161 for ; Wed, 6 Nov 2024 16:13:08 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id A93CA11618; Wed, 6 Nov 2024 16:13:17 +0100 (CET) Date: Wed, 6 Nov 2024 16:12:44 +0100 From: Wolfgang Bumiller To: Stefan Hanreich Message-ID: References: <20241010155637.255451-1-s.hanreich@proxmox.com> <20241010155637.255451-15-s.hanreich@proxmox.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20241010155637.255451-15-s.hanreich@proxmox.com> X-SPAM-LEVEL: Spam detection results: 0 AWL 0.081 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: Re: [pve-devel] [PATCH proxmox-ve-rs v2 14/25] sdn: ipam: add method for generating ipsets X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox VE development discussion Cc: pve-devel@lists.proxmox.com Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" On Thu, Oct 10, 2024 at 05:56:26PM GMT, Stefan Hanreich wrote: > For every guest that has at least one entry in the IPAM we generate an > ipset with the name `+sdn/guest-ipam-{vmid}`. The ipset contains all > IPs from all zones for a guest with {vmid}. > > Signed-off-by: Stefan Hanreich > --- > .../src/firewall/types/address.rs | 9 ++++ > proxmox-ve-config/src/sdn/ipam.rs | 54 ++++++++++++++++++- > 2 files changed, 62 insertions(+), 1 deletion(-) > > diff --git a/proxmox-ve-config/src/firewall/types/address.rs b/proxmox-ve-config/src/firewall/types/address.rs > index a7bb6ad..e5a3709 100644 > --- a/proxmox-ve-config/src/firewall/types/address.rs > +++ b/proxmox-ve-config/src/firewall/types/address.rs > @@ -108,6 +108,15 @@ impl From for Cidr { > } > } > > +impl From for Cidr { > + fn from(value: IpAddr) -> Self { > + match value { > + IpAddr::V4(addr) => Ipv4Cidr::from(addr).into(), > + IpAddr::V6(addr) => Ipv6Cidr::from(addr).into(), > + } > + } > +} > + > const IPV4_LENGTH: u8 = 32; > > #[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq, Hash)] > diff --git a/proxmox-ve-config/src/sdn/ipam.rs b/proxmox-ve-config/src/sdn/ipam.rs > index 682bbe7..075c0f3 100644 > --- a/proxmox-ve-config/src/sdn/ipam.rs > +++ b/proxmox-ve-config/src/sdn/ipam.rs > @@ -8,7 +8,11 @@ use std::{ > use serde::Deserialize; > > use crate::{ > - firewall::types::Cidr, > + common::Allowlist, > + firewall::types::{ > + ipset::{IpsetEntry, IpsetScope}, > + Cidr, Ipset, > + }, > guest::{types::Vmid, vm::MacAddress}, > sdn::{SdnNameError, SubnetName, ZoneName}, > }; > @@ -309,6 +313,54 @@ impl Ipam { > } > } > > +impl Ipam { > + /// generates an [`Ipset`] for all guests with at least one entry in the IPAM > + /// > + /// # Arguments > + /// * `filter` - A [`Allowlist`] for which IPsets should get returned > + /// > + /// It contains all IPs in all VNets, that a guest has stored in IPAM. > + /// Ipset name is of the form `guest-ipam-` > + pub fn ipsets<'a>( > + &self, > + filter: impl Into>>, ^ Why the `impl Into`? All our current uses should work for just the Option directly (and then we can also drop the named lifetime). > + ) -> impl Iterator + '_ { > + let filter = filter.into(); > + > + self.entries > + .iter() > + .flat_map(|(_, entries)| entries.iter()) > + .filter_map(|entry| { > + if let IpamData::Vm(data) = &entry.data() { > + if filter > + .map(|list| list.is_allowed(&data.vmid)) > + .unwrap_or(true) Let's bump MSRV to 1.82 and use if filter.is_none_or(|list| list.is_allowed(&data.vmid)) { ? :) > + { > + return Some(data); > + } > + } > + > + None > + }) > + .fold(HashMap::::new(), |mut acc, entry| { > + match acc.get_mut(&entry.vmid) { > + Some(ipset) => { > + ipset.push(IpsetEntry::from(entry.ip)); > + } > + None => { > + let ipset_name = format!("guest-ipam-{}", entry.vmid); > + let mut ipset = Ipset::from_parts(IpsetScope::Sdn, ipset_name); > + ipset.push(IpsetEntry::from(entry.ip)); > + acc.insert(entry.vmid, ipset); > + } > + }; Mhhhh. The `ipset.upsh()` is identical in both cases, and vmid is a simple Copy type, so we could use the entry api for this: acc.entry(entry.vmid) .or_insert_with(|| { Ipset::from_parts(IpsetScope::Sdn, format!("guest-ipam-{}", entry.vmid)) }) .push(IpsetEntry::from(entry.ip)); > + > + acc > + }) > + .into_values() > + } > +} > + > impl TryFrom for Ipam { > type Error = IpamError; > > -- > 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel