if (!ruleset_chain_exist($ruleset, "$bridge-IN")) {
ruleset_create_chain($ruleset, "$bridge-IN");
ruleset_addrule($ruleset, "$bridge-FW", "-m physdev --physdev-is-bridged --physdev-is-out -j $bridge-IN");
+ ruleset_addrule($ruleset, "$bridge-FW", "-m mark --mark 1 -j ACCEPT");
}
}
sub generate_tap_rules_direction {
- my ($ruleset, $group_rules, $iface, $netid, $macaddr, $rules, $bridge, $direction) = @_;
+ my ($ruleset, $group_rules, $iface, $netid, $macaddr, $vmfw_conf, $bridge, $direction) = @_;
+
+ my $rules = $vmfw_conf->{lc($direction)};
+ my $options = $vmfw_conf->{options};
my $tapchain = "$iface-$direction";
generate_group_rules($ruleset, $group_rules, $2);
}
ruleset_generate_rule($ruleset, $tapchain, $rule);
- ruleset_addrule($ruleset, $tapchain, "-m mark --mark 1 -g $bridge-IN")
+ ruleset_addrule($ruleset, $tapchain, "-m mark --mark 1 -j RETURN")
if $direction eq 'OUT';
} else {
- $rule->{action} = "$bridge-IN" if $rule->{action} eq 'ACCEPT' && $direction eq 'OUT';
+ $rule->{action} = "PVEFW-SET-ACCEPT-MARK" if $rule->{action} eq 'ACCEPT' && $direction eq 'OUT';
ruleset_generate_rule($ruleset, $tapchain, $rule);
}
}
}
- ruleset_addrule($ruleset, $tapchain, "-j LOG --log-prefix \"$tapchain-dropped: \" --log-level 4");
- ruleset_addrule($ruleset, $tapchain, "-j DROP");
+ # implement policy
+ my $policy;
+
+ if ($direction eq 'OUT') {
+ $policy = $options->{'policy-out'} || 'ACCEPT'; # allow everything by default
+ } else {
+ $policy = $options->{'policy-in'} || 'DROP'; # allow everything by default
+ }
+
+ if ($policy eq 'ACCEPT') {
+ if ($direction eq 'OUT') {
+ ruleset_addrule($ruleset, $tapchain, "-g PVEFW-SET-ACCEPT-MARK");
+ } else {
+ ruleset_addrule($ruleset, $tapchain, "-j ACCEPT");
+ }
+ } elsif ($policy eq 'DROP') {
+ ruleset_addrule($ruleset, $tapchain, "-j LOG --log-prefix \"$tapchain-dropped: \" --log-level 4");
+ ruleset_addrule($ruleset, $tapchain, "-j DROP");
+ } elsif ($policy eq 'REJECT') {
+ ruleset_addrule($ruleset, $tapchain, "-j LOG --log-prefix \"$tapchain-reject: \" --log-level 4");
+ ruleset_addrule($ruleset, $tapchain, "-j REJECT");
+ } else {
+ # should not happen
+ die "internal error: unknown policy '$policy'";
+ }
# plug the tap chain to bridge chain
my $physdevdirection = $direction eq 'IN' ? "out" : "in";
# generate firewall rules for QEMU VMs
foreach my $vmid (keys %{$vmdata->{qemu}}) {
my $conf = $vmdata->{qemu}->{$vmid};
-
- next if !$rules->{$vmid};
- my $options = $rules->{$vmid}->{options};
- next if defined($options->{enable}) && ($options->{enable} == 0);
+ my $vmfw_conf = $rules->{$vmid};
+ next if !$vmfw_conf;
+ next if defined($vmfw_conf->{options}->{enable}) && ($vmfw_conf->{options}->{enable} == 0);
foreach my $netid (keys %$conf) {
next if $netid !~ m/^net(\d+)$/;
generate_bridge_chains($ruleset, $bridge);
my $macaddr = $net->{macaddr};
- generate_tap_rules_direction($ruleset, $group_rules, $iface, $netid, $macaddr, $rules->{$vmid}->{in}, $bridge, 'IN');
- generate_tap_rules_direction($ruleset, $group_rules, $iface, $netid, $macaddr, $rules->{$vmid}->{out}, $bridge, 'OUT');
+ generate_tap_rules_direction($ruleset, $group_rules, $iface, $netid, $macaddr, $vmfw_conf, $bridge, 'IN');
+ generate_tap_rules_direction($ruleset, $group_rules, $iface, $netid, $macaddr, $vmfw_conf, $bridge, 'OUT');
}
}