From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 35A5B706EC for ; Thu, 24 Jun 2021 15:35:37 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 0BAF4C2B7 for ; Thu, 24 Jun 2021 15:35:02 +0200 (CEST) Received: from kvmformation3.odiso.net (globalOdiso.M6Lille.odiso.net [89.248.211.242]) by firstgate.proxmox.com (Proxmox) with ESMTP id 172DCC26A for ; Thu, 24 Jun 2021 15:34:43 +0200 (CEST) Received: by kvmformation3.odiso.net (Postfix, from userid 0) id 64FABDE211; Thu, 24 Jun 2021 15:34:26 +0200 (CEST) From: Alexandre Derumier To: pve-devel@lists.proxmox.com Date: Thu, 24 Jun 2021 15:34:19 +0200 Message-Id: <20210624133425.3624704-2-aderumier@odiso.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210624133425.3624704-1-aderumier@odiso.com> References: <20210624133425.3624704-1-aderumier@odiso.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 1.441 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% HEADER_FROM_DIFFERENT_DOMAINS 0.25 From and EnvelopeFrom 2nd level mail domains are different KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KHOP_HELO_FCRDNS 0.399 Relay HELO differs from its IP's reverse DNS NO_DNS_FOR_FROM 0.001 Envelope sender has no MX or A DNS records T_SPF_HELO_TEMPERROR 0.01 SPF: test of HELO record failed (temperror) T_SPF_TEMPERROR 0.01 SPF: test of record failed (temperror) Subject: [pve-devel] [PATCH qemu-server 1/7] add ipam module 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: , X-List-Received-Date: Thu, 24 Jun 2021 13:35:37 -0000 This is the same code than lxc, it can be move to a common module later Signed-off-by: Alexandre Derumier --- PVE/QemuServer/Ipam.pm | 158 ++++++++++++++++++++++++++++++++++++++++ PVE/QemuServer/Makefile | 1 + 2 files changed, 159 insertions(+) create mode 100644 PVE/QemuServer/Ipam.pm diff --git a/PVE/QemuServer/Ipam.pm b/PVE/QemuServer/Ipam.pm new file mode 100644 index 0000000..37b1595 --- /dev/null +++ b/PVE/QemuServer/Ipam.pm @@ -0,0 +1,158 @@ +package PVE::QemuServer::Ipam; + +use strict; +use warnings; + +my $have_sdn; +eval { + require PVE::Network::SDN::Zones; + $have_sdn = 1; +}; + +sub is_static_ip { + my ($ip) = @_; + + return 1 if $ip !~ m/(dhcp|manual|auto)$/; +} + + +sub ip_has_changed { + my ($oldip, $ip) = @_; + + return 1 if !$oldip && $ip; + return 1 if !$ip && $oldip; + return 1 if $ip && $oldip && $ip ne $oldip; +} + +my $add_net_ip = sub { + my ($version, $net, $oldnet, $hostname, $oldhostname, $description) = @_; + + my $oldbridge = $oldnet->{bridge}; + my $bridge = $net->{bridge}; + my $mac = $net->{hwaddr}; + my $ipfield = $version == 4 ? "ip" : "ip6"; + my $ip = $net->{$ipfield}; + my $oldip = $oldnet->{$ipfield}; + my $subnets = PVE::Network::SDN::Vnets::get_subnets($bridge); + return if !keys %{$subnets}; + + eval { + if (!$ip) { + my $next_free_ip = PVE::Network::SDN::Vnets::get_next_free_cidr($bridge, $hostname, $mac, $description, $version); + $net->{$ipfield} = $next_free_ip if $next_free_ip; + } elsif (is_static_ip($ip)) { + if (!ip_has_changed($oldip, $ip)) { + #update ip attributes if no ip address change + PVE::Network::SDN::Vnets::update_cidr($bridge, $ip, $hostname, $oldhostname, $mac, $description); + } else { + PVE::Network::SDN::Vnets::add_cidr($bridge, $ip, $hostname, $mac, $description); + } + } + }; + if ($@) { + die $@; + } +}; + + +my $del_net_ip = sub { + my ($version, $oldnet, $net, $hostname, $description) = @_; + + my $oldbridge = $oldnet->{bridge}; + my $bridge = $net->{bridge}; + my $ip = $version == 4 ? $net->{ip} : $net->{ip6}; + my $oldip = $version == 4 ? $oldnet->{ip} : $oldnet->{ip6}; + + return if !$oldip || !is_static_ip($oldip); + + my $subnets = PVE::Network::SDN::Vnets::get_subnets($oldbridge); + return if !keys %{$subnets}; + + eval { + PVE::Network::SDN::Vnets::del_cidr($oldbridge, $oldip, $hostname, $description) if !$bridge || $bridge ne $oldbridge || !$ip || $ip ne $oldip; + }; + warn $@ if $@; +}; + + +my $update_net_gateway = sub { + my ($version, $net) = @_; + + my $bridge = $net->{bridge}; + my $netip = $version == 4 ? $net->{ip} : $net->{ip6}; + my $gwfield = $version == 4 ? "gw" : "gw6"; + + return if (!$netip || !is_static_ip($netip)); + + my $subnets = PVE::Network::SDN::Vnets::get_subnets($bridge); + return if !keys %{$subnets}; + + #update gateway + my ($ip, $mask) = split(/\//, $netip); + my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $mask, $subnets); + my $gw = $subnet->{gateway} if $subnet->{gateway}; + $net->{$gwfield} = $gw if $gw; + +}; + +sub destroy_net_ip { + my ($conf) = @_; + + return if !$have_sdn; + + foreach my $opt (keys %$conf) { + next if $opt !~ m/^net(\d+)$/; + my $netid = $1; + my $oldnet = PVE::LXC::Config->parse_lxc_network($conf->{$opt}); + my $hostname = $conf->{hostname}; + my $description = ''; + delete_net_ip($hostname, $oldnet, undef, $description); + } +} + +sub update_net_ip { + my ($net, $oldnet, $hostname, $oldhostname, $description) = @_; + + return if !$have_sdn; + + eval { + &$add_net_ip(4, $net, $oldnet, $hostname, $oldhostname, $description); + }; + if ($@) { + $net->{ip} = $oldnet->{ip}; + die "can't change ip4: $@\n"; + } + + eval { + &$add_net_ip(6, $net, $oldnet, $hostname, $oldhostname, $description); + }; + if ($@) { + my $err = $@; + #if error, delete previously added ipv4 + eval { + PVE::Network::SDN::Vnets::del_cidr($net->{bridge}, $net->{ip}, $hostname, $description) if ip_has_changed($oldnet->{ip}, $net->{ip}); + }; + $net->{ip6} = $oldnet->{ip6}; + $net->{ip} = $oldnet->{ip}; + + die "error change ipv6: $err\n"; + } + + delete_net_ip($oldhostname, $oldnet, $net, $description); + + &$update_net_gateway(4, $net); + &$update_net_gateway(6, $net); +} + + + +sub delete_net_ip { + my ($hostname, $oldnet, $net, $description) = @_; + + return if !$have_sdn; + + &$del_net_ip(4, $oldnet, $net, $hostname, $description); + &$del_net_ip(6, $oldnet, $net, $hostname, $description); +} + +1; \ No newline at end of file diff --git a/PVE/QemuServer/Makefile b/PVE/QemuServer/Makefile index e4ed184..0292383 100644 --- a/PVE/QemuServer/Makefile +++ b/PVE/QemuServer/Makefile @@ -11,6 +11,7 @@ SOURCES=PCI.pm \ CPUConfig.pm \ CGroup.pm \ Drive.pm \ + Ipam.pm \ .PHONY: install install: ${SOURCES} -- 2.20.1