---
 src/PVE/Firewall.pm |   33 +++++++++++++++++++++++----------
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm
index 2bdff20..a3b4ccb 100644
--- a/src/PVE/Firewall.pm
+++ b/src/PVE/Firewall.pm
@@ -960,6 +960,11 @@ sub compute_ipfilter_ipset_name {
 sub parse_address_list {
     my ($str) = @_;
 
+    # if it is a not
+    if ($str =~ m/^!\s*(.*)/) {
+       $str = $1;
+    }
+
     if ($str =~ m/^(\+)(\S+)$/) { # ipset ref
        die "ipset name too long\n" if length($str) > ($max_ipset_name_length + 
1);
        return;
@@ -1634,16 +1639,20 @@ sub ruleset_generate_cmdstr {
     my $source = $rule->{source};
     my $dest = $rule->{dest};
 
+    my $negate = "";
     if ($source) {
+        if ($source =~ s/^!\s*//) {
+            $negate = "! ";
+        }
         if ($source =~ m/^\+/) {
            if ($source =~ m/^\+(${ipset_name_pattern})$/) {
                my $name = $1;
                if ($fw_conf && $fw_conf->{ipset}->{$name}) {
                    my $ipset_chain = 
compute_ipset_chain_name($fw_conf->{vmid}, $name, $ipversion);
-                   push @cmd, "-m set --match-set ${ipset_chain} src";
+                   push @cmd, "-m set ${negate}--match-set ${ipset_chain} src";
                } elsif ($cluster_conf && $cluster_conf->{ipset}->{$name}) {
                    my $ipset_chain = compute_ipset_chain_name(0, $name, 
$ipversion);
-                   push @cmd, "-m set --match-set ${ipset_chain} src";
+                   push @cmd, "-m set ${negate}--match-set ${ipset_chain} src";
                } else {
                    die "no such ipset '$name'\n";
                }
@@ -1657,22 +1666,26 @@ sub ruleset_generate_cmdstr {
            die "no such alias '$source'\n" if !$e;
            push @cmd, "-s $e->{cidr}";
         } elsif ($source =~ m/\-/){
-           push @cmd, "-m iprange --src-range $source";
+           push @cmd, "-m iprange ${negate}--src-range $source";
        } else {
-           push @cmd, "-s $source";
+           push @cmd, "${negate}-s $source";
         }
     }
 
+    $negate = "";
     if ($dest) {
+        if ($dest =~ s/^!\s*//) {
+            $negate = "! ";
+        }
         if ($dest =~ m/^\+/) {
            if ($dest =~ m/^\+(${ipset_name_pattern})$/) {
                my $name = $1;
                if ($fw_conf && $fw_conf->{ipset}->{$name}) {
                    my $ipset_chain = 
compute_ipset_chain_name($fw_conf->{vmid}, $name, $ipversion);
-                   push @cmd, "-m set --match-set ${ipset_chain} dst";
+                   push @cmd, "-m set ${negate}--match-set ${ipset_chain} dst";
                } elsif ($cluster_conf && $cluster_conf->{ipset}->{$name}) {
                    my $ipset_chain = compute_ipset_chain_name(0, $name, 
$ipversion);
-                   push @cmd, "-m set --match-set ${ipset_chain} dst";
+                   push @cmd, "-m set ${negate}--match-set ${ipset_chain} dst";
                } else {
                    die "no such ipset '$name'\n";
                }
@@ -1686,9 +1699,9 @@ sub ruleset_generate_cmdstr {
            die "no such alias '$dest'\n" if !$e;
            push @cmd, "-d $e->{cidr}";
         } elsif ($dest =~ 
m/^(\d+)\.(\d+).(\d+).(\d+)\-(\d+)\.(\d+).(\d+).(\d+)$/){
-           push @cmd, "-m iprange --dst-range $dest";
+           push @cmd, "-m iprange ${negate}--dst-range $dest";
        } else {
-           push @cmd, "-d $dest";
+           push @cmd, "${negate}-d $dest";
         }
     }
 
@@ -2400,11 +2413,11 @@ sub parse_fw_rule {
            $rule->{sport} = $1;
            next;
        }
-       if ($line =~ s/^-source (\S+)\s*//) {
+       if ($line =~ s/^-source\s+((!\s*)?\S+)\s*//) {
            $rule->{source} = $1;
            next;
        }
-       if ($line =~ s/^-dest (\S+)\s*//) {
+       if ($line =~ s/^-dest\s+((!\s*)?\S+)\s*//) {
            $rule->{dest} = $1;
            next;
        }
-- 
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