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 D1DBB1FF141 for ; Tue, 05 May 2026 11:22:19 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id D848921044; Tue, 5 May 2026 11:22:17 +0200 (CEST) Message-ID: <4665ed28-5ca2-4b1c-9729-5cb8d574e73d@proxmox.com> Date: Tue, 5 May 2026 11:22:08 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH pve-network v4 24/47] sdn: add prefix lists module To: pve-devel@lists.proxmox.com References: <20260504160350.395470-1-s.hanreich@proxmox.com> <20260504160350.395470-25-s.hanreich@proxmox.com> Content-Language: en-US From: Stefan Hanreich In-Reply-To: <20260504160350.395470-25-s.hanreich@proxmox.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.344 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 KAM_MAILER 2 Automated Mailer Tag Left in Email SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [subnets.pm,dns.pm,subnetplugin.pm,controllers.pm,prefixlists.pm,vnetplugin.pm,dhcp.pm,fabrics.pm,ipams.pm,vnets.pm,frr.pm,zones.pm] Message-ID-Hash: 5D6324AZIXI7QQRCMST2LP3UZQJJD4DK X-Message-ID-Hash: 5D6324AZIXI7QQRCMST2LP3UZQJJD4DK X-MailFrom: s.hanreich@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: On 5/4/26 6:02 PM, Stefan Hanreich wrote: > Defines helpers for common operations (reading / writing > configuration) as well as the required formats / schema definitions > for the route map API. > > Signed-off-by: Stefan Hanreich > --- > src/PVE/Network/SDN/Makefile | 14 ++- > src/PVE/Network/SDN/PrefixLists.pm | 134 +++++++++++++++++++++++++++++ > 2 files changed, 147 insertions(+), 1 deletion(-) > create mode 100644 src/PVE/Network/SDN/PrefixLists.pm > > diff --git a/src/PVE/Network/SDN/Makefile b/src/PVE/Network/SDN/Makefile > index d1ffef9..fa6702e 100644 > --- a/src/PVE/Network/SDN/Makefile > +++ b/src/PVE/Network/SDN/Makefile > @@ -1,4 +1,16 @@ > -SOURCES=Vnets.pm VnetPlugin.pm Zones.pm Controllers.pm Subnets.pm SubnetPlugin.pm Ipams.pm Dns.pm Dhcp.pm Fabrics.pm Frr.pm > +SOURCES=Vnets.pm\ > + VnetPlugin.pm\ > + Zones.pm\ > + Controllers.pm\ > + Subnets.pm\ > + SubnetPlugin.pm\ > + Ipams.pm\ > + Dns.pm\ > + Dhcp.pm\ > + Fabrics.pm\ > + Frr.pm\ > + RouteMaps.pm\ > + PrefixLists.pm > seems like I messed up the changes in the Makefile in this and the following commits - will fix! > PERL5DIR=${DESTDIR}/usr/share/perl5 > diff --git a/src/PVE/Network/SDN/PrefixLists.pm b/src/PVE/Network/SDN/PrefixLists.pm > new file mode 100644 > index 0000000..ced2ebf > --- /dev/null > +++ b/src/PVE/Network/SDN/PrefixLists.pm > @@ -0,0 +1,134 @@ > +package PVE::Network::SDN::PrefixLists; > + > +use strict; > +use warnings; > + > +use PVE::Cluster qw(cfs_register_file cfs_read_file cfs_lock_file cfs_write_file); > +use PVE::JSONSchema qw(get_standard_option); > +use PVE::INotify; > +use PVE::Network::SDN; > +use PVE::RS::SDN::PrefixLists; > + > +PVE::JSONSchema::register_format( > + 'pve-sdn-prefix-list-id', > + sub { > + my ($id, $noerr) = @_; > + > + if ($id =~ m/^(only_default|only_default_v6|loopbacks_ips)$/) { > + return undef if $noerr; > + die "prefix list ID '$id' is currently reserved and cannot be used\n"; > + } > + > + if ($id !~ m/^[a-zA-Z0-9][a-zA-Z0-9-_]{0,30}[a-zA-Z0-9]?$/i) { > + return undef if $noerr; > + die "prefix list ID '$id' contains illegal characters\n"; > + } > + > + return $id; > + }, > +); > + > +PVE::JSONSchema::register_standard_option( > + 'pve-sdn-prefix-list-id', > + { > + description => "The SDN prefix list identifier", > + type => 'string', > + format => 'pve-sdn-prefix-list-id', > + }, > +); > + > +cfs_register_file( > + 'sdn/prefix-lists.cfg', \&parse_prefix_lists_config, \&write_prefix_lists_config, > +); > + > +sub parse_prefix_lists_config { > + my ($filename, $raw) = @_; > + return $raw // ''; > +} > + > +sub write_prefix_lists_config { > + my ($filename, $config) = @_; > + return $config // ''; > +} > + > +sub config { > + my ($running) = @_; > + > + if ($running) { > + my $running_config = PVE::Network::SDN::running_config(); > + > + # if the config hasn't yet been applied after the introduction of > + # prefix lists then the key does not exist in the running config so we > + # default to an empty hash > + my $prefix_lists_config = $running_config->{'prefix-lists'}->{ids} // {}; > + return PVE::RS::SDN::PrefixLists->running_config($prefix_lists_config); > + } > + > + my $prefix_lists_config = cfs_read_file("sdn/prefix-lists.cfg"); > + return PVE::RS::SDN::PrefixLists->config($prefix_lists_config); > +} > + > +sub write_config { > + my ($config) = @_; > + cfs_write_file("sdn/prefix-lists.cfg", $config->to_raw(), 1); > +} > + > +sub prefix_list_properties { > + my ($update) = @_; > + > + my $properties = { > + digest => get_standard_option('pve-config-digest'), > + entries => { > + type => 'array', > + optional => 1, > + items => { > + type => 'string', > + format => { > + action => { > + type => 'string', > + enum => ['permit', 'deny'], > + }, > + prefix => { > + type => 'string', > + format => 'CIDR', > + }, > + le => { > + type => 'integer', > + minimum => 0, > + maximum => 128, > + optional => 1, > + }, > + ge => { > + type => 'integer', > + minimum => 0, > + maximum => 128, > + optional => 1, > + }, > + seq => { > + type => 'integer', > + minimum => 0, > + maximum => 2**32 - 1, > + optional => 1, > + }, > + }, > + }, > + }, > + }; > + > + if ($update) { > + $properties->{delete} = { > + type => 'array', > + optional => 1, > + items => { > + type => 'string', > + enum => ['entries'], > + }, > + }; > + } else { > + $properties->{id} = get_standard_option('pve-sdn-prefix-list-id'); > + } > + > + return $properties; > +} > + > +1;