iptables and ipset use short ipv6 notation,
we need to normalize them

Signed-off-by: Alexandre Derumier <aderum...@odiso.com>
---
 src/PVE/Firewall.pm |   31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm
index e2342d7..68c368a 100644
--- a/src/PVE/Firewall.pm
+++ b/src/PVE/Firewall.pm
@@ -17,6 +17,7 @@ use IO::File;
 use Net::IP;
 use PVE::Tools qw(run_command lock_file dir_glob_foreach);
 use Encode;
+use Socket qw(AF_INET6 inet_ntop inet_pton);
 
 my $hostfw_conf_filename = "/etc/pve/local/host.fw";
 my $pvefw_conf_dir = "/etc/pve/firewall";
@@ -2215,10 +2216,11 @@ sub parse_alias {
 
     if ($line =~ m/^(\S+)\s(\S+)$/) {
        my ($name, $cidr) = ($1, $2);
-       $cidr =~ s|/32$||;
-       $cidr =~ s|/128$||;
-       pve_verify_ipv4_or_cidr($cidr);
+
+       $cidr = ip_normalize($cidr);
        my $ipversion = get_ip_version($cidr);
+
+       pve_verify_ipv4_or_cidr($cidr);
        my $data = {
            name => $name,
            cidr => $cidr,
@@ -2374,7 +2376,7 @@ sub generic_fw_config_parser {
                if ($cidr =~ m/^${ip_alias_pattern}$/) {
                    resolve_alias($cluster_conf, $res, $cidr); # make sure 
alias exists
                } else {
-                   $cidr =~ s|/32$||;
+                   $cidr = ip_normalize($cidr);
                    pve_verify_ipv4_or_cidr_or_alias($cidr);
                }
            };
@@ -2734,7 +2736,7 @@ sub generate_ipset {
                $cidr = resolve_alias($clusterfw_conf, $fw_conf, 
$entry->{cidr});
            }
            my $ipversion = get_ip_version($cidr);
-           $cidr = compress_ipv6(lc($cidr));
+           $cidr = ip_normalize($cidr);
 
            $nethash->{$ipversion}->{$cidr} = { cidr => $cidr, nomatch => 
$entry->{nomatch} };
        };
@@ -3356,17 +3358,18 @@ sub update {
     run_locked($code);
 }
 
-# Replace longest run of null blocks with a double colon
-sub compress_ipv6 {
+sub ip_normalize {
     my $ip = shift;
-    if (my @runs = $ip =~ /((?:(?:^|:)(?:0000))+:?)/g ) {
-        my $max = $runs[0];
-        for (@runs[1..$#runs]) {
-            $max = $_ if length($max) < length;
-        }
-        $ip =~ s/$max/::/;
+
+    #http://backreference.org/2013/03/01/ipv6-address-normalization/
+    my $ipv6 = inet_pton(AF_INET6, lc($ip));
+    if (defined($ipv6)) {
+       $ip = inet_ntop(AF_INET6, $ipv6);
+        $ip =~ s|/128$||;
+    } else {
+        $ip =~ s|/32$||;
     }
-    $ip =~ s/:0{1,3}/:/g;
     return $ip;
 }
+
 1;
-- 
1.7.10.4

_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to