}
}
+$SIG{'__WARN__'} = sub {
+ my $err = $@;
+ my $t = $_[0];
+ chomp $t;
+ add_trace("$t\n");
+ $@ = $err;
+};
+
sub nf_dev_match {
my ($devre, $dev) = @_;
next if $cstate =~ m/NEW/;
- die "please implement cstate test '$cstate'";
+ die "cstate test '$cstate' not implemented\n";
}
if ($rule =~ s/^-m addrtype --src-type (\S+)\s*//) {
my $atype = $1;
- die "missing srctype" if !$pkg->{srctype};
+ die "missing source address type (srctype)\n"
+ if !$pkg->{srctype};
return undef if $atype ne $pkg->{srctype};
}
if ($rule =~ s/^-m addrtype --dst-type (\S+)\s*//) {
my $atype = $1;
- die "missing dsttype" if !$pkg->{dsttype};
+ die "missing destination address type (dsttype)\n"
+ if !$pkg->{dsttype};
return undef if $atype ne $pkg->{dsttype};
}
if ($rule =~ s/^-i (\S+)\s*//) {
my $devre = $1;
- die "missing iface_in" if !$pkg->{iface_in};
+ die "missing interface (iface_in)\n" if !$pkg->{iface_in};
return undef if !nf_dev_match($devre, $pkg->{iface_in});
next;
}
if ($rule =~ s/^-o (\S+)\s*//) {
my $devre = $1;
- die "missing iface_out" if !$pkg->{iface_out};
+ die "missing interface (iface_out)\n" if !$pkg->{iface_out};
return undef if !nf_dev_match($devre, $pkg->{iface_out});
next;
}
- if ($rule =~ s/^-p (tcp|udp)\s*//) {
+ if ($rule =~ s/^-p (tcp|udp|igmp|icmp)\s*//) {
die "missing proto" if !$pkg->{proto};
return undef if $pkg->{proto} ne $1; # no match
next;
next;
}
- if ($rule =~ s/^-m set --match-set (\S+) src\s*//) {
+ if ($rule =~ s/^-m set (!\s+)?--match-set (\S+) src\s*//) {
die "missing source" if !$pkg->{source};
- my $ipset = $ipset_ruleset->{$1};
- die "no such ip set '$1'" if !$ipset;
- return undef if !ipset_match($1, $ipset, $pkg->{source});
+ my $neg = $1;
+ my $ipset = $ipset_ruleset->{$2};
+ die "no such ip set '$2'" if !$ipset;
+ if ($neg) {
+ return undef if ipset_match($1, $ipset, $pkg->{source});
+ } else {
+ return undef if !ipset_match($1, $ipset, $pkg->{source});
+ }
next;
}
}
sub extract_vm_info {
- my ($vmdata, $vmid) = @_;
+ my ($vmdata, $vmid, $netnum) = @_;
my $info = { type => 'vm', vmid => $vmid };
my $conf = $vmdata->{qemu}->{$vmid} || die "no such VM '$vmid'";
- my $net = PVE::QemuServer::parse_net($conf->{net0});
+ my $net = PVE::QemuServer::parse_net($conf->{"net$netnum"});
$info->{macaddr} = $net->{macaddr} || die "unable to get mac address";
$info->{bridge} = $net->{bridge} || die "unable to get bridge";
- $info->{fwbr} = "fwbr${vmid}i0";
- $info->{tapdev} = "tap${vmid}i0";
- $info->{fwln} = "fwln${vmid}i0";
- $info->{fwpr} = "fwpr${vmid}p0";
+ $info->{fwbr} = "fwbr${vmid}i$netnum";
+ $info->{tapdev} = "tap${vmid}i$netnum";
+ $info->{fwln} = "fwln${vmid}i$netnum";
+ $info->{fwpr} = "fwpr${vmid}p$netnum";
return $info;
}
} else {
die "implement me";
}
- } elsif ($from =~ m/^vm(\d+)$/) {
+ } elsif ($from =~ m/^vm(\d+)(i(\d))?$/) {
my $vmid = $1;
- $from_info = extract_vm_info($vmdata, $vmid);
+ my $netnum = $3 || 0;
+ $from_info = extract_vm_info($vmdata, $vmid, $netnum);
$start_state = 'fwbr-out';
$pkg->{mac_source} = $from_info->{macaddr};
} else {
}
} elsif ($to =~ m/^vm(\d+)$/) {
my $vmid = $1;
- $target = extract_vm_info($vmdata, $vmid);
+ $target = extract_vm_info($vmdata, $vmid, 0);
$target->{iface} = $target->{tapdev};
} else {
die "unable to parse \"to => '$to'\"\n";