]> git.proxmox.com Git - pve-firewall.git/blobdiff - src/PVE/Firewall.pm
rename link+ to fwln+
[pve-firewall.git] / src / PVE / Firewall.pm
index ac89966308cd3979ae5db90e778bde44d1d0ddaf..9098c0ecb8748034edd746701075a5d351eafd85 100644 (file)
@@ -814,7 +814,7 @@ sub copy_opject_with_digest {
        $sha->add($k, ':', $v, "\n");
     }
 
-    my $digest = $sha->b64digest;
+    my $digest = $sha->hexdigest;
 
     $res->{digest} = $digest;
 
@@ -838,7 +838,7 @@ sub copy_list_with_digest {
        push @$res, $data;
     }
 
-    my $digest = $sha->b64digest;
+    my $digest = $sha->hexdigest;
 
     foreach my $entry (@$res) {
        $entry->{digest} = $digest;
@@ -1102,7 +1102,7 @@ sub iptables_get_chains {
 
        return 1 if $name =~ m/^venet0-\d+-(:?IN|OUT)$/;
 
-       return 1 if $name =~ m/^vmbr\d+(v\d+)?-(:?FW|IN|OUT|IPS)$/;
+       return 1 if $name =~ m/^fwbr\d+(v\d+)?-(:?FW|IN|OUT|IPS)$/;
        return 1 if $name =~ m/^GROUP-(:?[^\s\-]+)-(:?IN|OUT)$/;
 
        return undef;
@@ -1398,50 +1398,7 @@ sub ruleset_addlog {
 
     $logrule = "$rule $logrule" if defined($rule);
 
-    ruleset_addrule($ruleset, $chain, $logrule)
-}
-
-sub generate_bridge_chains {
-    my ($ruleset, $hostfw_conf, $bridge, $routing_table, $bridges_config) = @_;
-
-    my $options = $hostfw_conf->{options} || {};
-
-    die "error: detected direct route to bridge '$bridge'\n"
-       if !$options->{allow_bridge_route} && $routing_table->{$bridge};
-
-    if (!ruleset_chain_exist($ruleset, "$bridge-FW")) {
-       ruleset_create_chain($ruleset, "$bridge-FW");
-       ruleset_addrule($ruleset, "PVEFW-FORWARD", "-o $bridge -m physdev --physdev-is-out -j $bridge-FW");
-       ruleset_addrule($ruleset, "PVEFW-FORWARD", "-i $bridge -m physdev --physdev-is-in -j $bridge-FW");
-    }
-
-    if (!ruleset_chain_exist($ruleset, "$bridge-OUT")) {
-       ruleset_create_chain($ruleset, "$bridge-OUT");
-
-       if($options->{optimize}){
-           foreach my $interface (@{$bridges_config->{$bridge}}) {
-               ruleset_addrule($ruleset, "$bridge-OUT", "-m physdev --physdev-is-bridged --physdev-in $interface -g PVEFW-SET-ACCEPT-MARK");
-           }
-       }
-
-       ruleset_addrule($ruleset, "$bridge-FW", "-m physdev --physdev-is-in -j $bridge-OUT");
-       ruleset_insertrule($ruleset, "PVEFW-INPUT", "-i $bridge -m physdev --physdev-is-in -j $bridge-OUT");
-    }
-
-    if (!ruleset_chain_exist($ruleset, "$bridge-IN")) {
-       ruleset_create_chain($ruleset, "$bridge-IN");
-
-       if($options->{optimize}){
-           foreach my $interface (@{$bridges_config->{$bridge}}) {
-               ruleset_addrule($ruleset, "$bridge-IN", "-m physdev --physdev-is-bridged --physdev-out $interface -j ACCEPT");
-           }
-       }
-
-       ruleset_addrule($ruleset, "$bridge-FW", "-m physdev --physdev-is-out -j $bridge-IN");
-       ruleset_addrule($ruleset, "$bridge-FW", "-m mark --mark 1 -j ACCEPT");
-       # accept traffic to unmanaged bridge ports
-       ruleset_addrule($ruleset, "$bridge-FW", "-m physdev --physdev-is-out -j ACCEPT ");
-    }
+    ruleset_addrule($ruleset, $chain, $logrule);
 }
 
 sub ruleset_add_chain_policy {
@@ -1471,16 +1428,31 @@ sub ruleset_add_chain_policy {
     }
 }
 
+sub ruleset_chain_add_conn_filters {
+    my ($ruleset, $chain, $accept) = @_;
+
+    ruleset_addrule($ruleset, $chain, "-m conntrack --ctstate INVALID -j DROP");
+    ruleset_addrule($ruleset, $chain, "-m conntrack --ctstate RELATED,ESTABLISHED -j $accept");
+}
+
+sub ruleset_chain_add_input_filters {
+    my ($ruleset, $chain, $options) = @_;
+
+    if (!(defined($options->{nosmurfs}) && $options->{nosmurfs} == 0)) {
+       ruleset_addrule($ruleset, $chain, "-m conntrack --ctstate INVALID,NEW -j PVEFW-smurfs");
+    }
+
+    if ($options->{tcpflags}) {
+       ruleset_addrule($ruleset, $chain, "-p tcp -j PVEFW-tcpflags");
+    }
+}
+
 sub ruleset_create_vm_chain {
     my ($ruleset, $chain, $options, $host_options, $macaddr, $direction) = @_;
 
     ruleset_create_chain($ruleset, $chain);
     my $accept = generate_nfqueue($options);
 
-    if (!(defined($host_options->{nosmurfs}) && $host_options->{nosmurfs} == 0)) {
-       ruleset_addrule($ruleset, $chain, "-m conntrack --ctstate INVALID,NEW -j PVEFW-smurfs");
-    }
-
     if (!(defined($options->{dhcp}) && $options->{dhcp} == 0)) {
        if ($direction eq 'OUT') {
            ruleset_generate_rule($ruleset, $chain, { action => 'PVEFW-SET-ACCEPT-MARK',
@@ -1491,17 +1463,6 @@ sub ruleset_create_vm_chain {
        }
     }
 
-    if ($host_options->{tcpflags}) {
-       ruleset_addrule($ruleset, $chain, "-p tcp -j PVEFW-tcpflags");
-    }
-
-    ruleset_addrule($ruleset, $chain, "-m conntrack --ctstate INVALID -j DROP");
-    if ($direction eq 'OUT') {
-       ruleset_addrule($ruleset, $chain, "-m conntrack --ctstate RELATED,ESTABLISHED -g PVEFW-SET-ACCEPT-MARK");
-    } else {
-       ruleset_addrule($ruleset, $chain, "-m conntrack --ctstate RELATED,ESTABLISHED -j $accept");
-    }
-
     if ($direction eq 'OUT') {
        if (defined($macaddr) && !(defined($options->{macfilter}) && $options->{macfilter} == 0)) {
            ruleset_addrule($ruleset, $chain, "-m mac ! --mac-source $macaddr -j DROP");
@@ -1571,21 +1532,16 @@ sub generate_nfqueue {
 }
 
 sub ruleset_generate_vm_ipsrules {
-    my ($ruleset, $options, $direction, $iface, $bridge) = @_;
+    my ($ruleset, $options, $direction, $iface) = @_;
 
     if ($options->{ips} && $direction eq 'IN') {
        my $nfqueue = generate_nfqueue($options);
 
-       if (!ruleset_chain_exist($ruleset, "$bridge-IPS")) {
+       if (!ruleset_chain_exist($ruleset, "PVEFW-IPS")) {
            ruleset_create_chain($ruleset, "PVEFW-IPS");
        }
 
-       if (!ruleset_chain_exist($ruleset, "$bridge-IPS")) {
-           ruleset_create_chain($ruleset, "$bridge-IPS");
-           ruleset_insertrule($ruleset, "PVEFW-IPS", "-o $bridge -m physdev --physdev-is-out -j $bridge-IPS");
-       }
-
-        ruleset_addrule($ruleset, "$bridge-IPS", "-m physdev --physdev-out $iface --physdev-is-bridged -j $nfqueue");
+        ruleset_addrule($ruleset, "PVEFW-IPS", "-m physdev --physdev-out $iface --physdev-is-bridged -j $nfqueue");
     }
 }
 
@@ -1621,24 +1577,13 @@ sub generate_venet_rules_direction {
     my $accept_action = $direction eq 'OUT' ? "PVEFW-SET-ACCEPT-MARK" : $accept;
     ruleset_add_chain_policy($ruleset, $chain, $vmid, $policy, $loglevel, $accept_action);
 
-    # plug into FORWARD, INPUT and OUTPUT chain
     if ($direction eq 'OUT') {
-       ruleset_generate_rule_insert($ruleset, "PVEFW-FORWARD", {
-           action => $chain,
-           source => $ip,
-           iface_in => 'venet0'});
-
-       ruleset_generate_rule_insert($ruleset, "PVEFW-INPUT", {
+       ruleset_generate_rule_insert($ruleset, "PVEFW-VENET-OUT", {
            action => $chain,
            source => $ip,
            iface_in => 'venet0'});
     } else {
-       ruleset_generate_rule($ruleset, "PVEFW-FORWARD", {
-           action => $chain,
-           dest => $ip,
-           iface_out => 'venet0'});
-
-       ruleset_generate_rule($ruleset, "PVEFW-OUTPUT", {
+       ruleset_generate_rule($ruleset, "PVEFW-VENET-IN", {
            action => $chain,
            dest => $ip,
            iface_out => 'venet0'});
@@ -1646,7 +1591,7 @@ sub generate_venet_rules_direction {
 }
 
 sub generate_tap_rules_direction {
-    my ($ruleset, $cluster_conf, $hostfw_conf, $iface, $netid, $macaddr, $vmfw_conf, $vmid, $bridge, $direction) = @_;
+    my ($ruleset, $cluster_conf, $hostfw_conf, $iface, $netid, $macaddr, $vmfw_conf, $vmid, $direction) = @_;
 
     my $lc_direction = lc($direction);
 
@@ -1662,7 +1607,7 @@ sub generate_tap_rules_direction {
 
     ruleset_generate_vm_rules($ruleset, $rules, $cluster_conf, $tapchain, $netid, $direction, $options);
 
-    ruleset_generate_vm_ipsrules($ruleset, $options, $direction, $iface, $bridge);
+    ruleset_generate_vm_ipsrules($ruleset, $options, $direction, $iface);
 
     # implement policy
     my $policy;
@@ -1679,11 +1624,11 @@ sub generate_tap_rules_direction {
 
     # plug the tap chain to bridge chain
     if ($direction eq 'IN') {
-       ruleset_addrule($ruleset, "$bridge-IN",
-                          "-m physdev --physdev-is-bridged --physdev-out $iface -j $tapchain");
+       ruleset_addrule($ruleset, "PVEFW-FWBR-IN",
+                       "-m physdev --physdev-is-bridged --physdev-out $iface -j $tapchain");
     } else {
-       ruleset_addrule($ruleset, "$bridge-OUT",
-                          "-m physdev --physdev-in $iface -j $tapchain");
+       ruleset_addrule($ruleset, "PVEFW-FWBR-OUT",
+                       "-m physdev --physdev-is-bridged --physdev-in $iface -j $tapchain");
     }
 }
 
@@ -1701,17 +1646,11 @@ sub enable_host_firewall {
 
     my $loglevel = get_option_log_level($options, "log_level_in");
 
-    if (!(defined($options->{nosmurfs}) && $options->{nosmurfs} == 0)) {
-       ruleset_addrule($ruleset, $chain, "-m conntrack --ctstate INVALID,NEW -j PVEFW-smurfs");
-    }
+    ruleset_addrule($ruleset, $chain, "-i lo -j ACCEPT");
 
-    if ($options->{tcpflags}) {
-       ruleset_addrule($ruleset, $chain, "-p tcp -j PVEFW-tcpflags");
-    }
+    ruleset_chain_add_conn_filters($ruleset, $chain, 'ACCEPT');
+    ruleset_chain_add_input_filters($ruleset, $chain, $options);
 
-    ruleset_addrule($ruleset, $chain, "-m conntrack --ctstate INVALID -j DROP");
-    ruleset_addrule($ruleset, $chain, "-m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT");
-    ruleset_addrule($ruleset, $chain, "-i lo -j ACCEPT");
     ruleset_addrule($ruleset, $chain, "-m addrtype --dst-type MULTICAST -j ACCEPT");
     ruleset_addrule($ruleset, $chain, "-p udp -m conntrack --ctstate NEW --dport 5404:5405 -j ACCEPT");
     ruleset_addrule($ruleset, $chain, "-p udp -m udp --dport 9000 -j ACCEPT");  #corosync
@@ -1735,9 +1674,10 @@ sub enable_host_firewall {
 
     $loglevel = get_option_log_level($options, "log_level_out");
 
-    ruleset_addrule($ruleset, $chain, "-m conntrack --ctstate INVALID -j DROP");
-    ruleset_addrule($ruleset, $chain, "-m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT");
     ruleset_addrule($ruleset, $chain, "-o lo -j ACCEPT");
+
+    ruleset_chain_add_conn_filters($ruleset, $chain, 'ACCEPT');
+
     ruleset_addrule($ruleset, $chain, "-m addrtype --dst-type MULTICAST -j ACCEPT");
     ruleset_addrule($ruleset, $chain, "-p udp -m conntrack --ctstate NEW --dport 5404:5405 -j ACCEPT");
     ruleset_addrule($ruleset, $chain, "-p udp -m udp --dport 9000 -j ACCEPT"); #corosync
@@ -1913,7 +1853,7 @@ sub parse_hostfw_option {
 
     my $loglevels = "emerg|alert|crit|err|warning|notice|info|debug|nolog";
 
-    if ($line =~ m/^(enable|nosmurfs|tcpflags|allow_bridge_route|optimize):\s*(0|1)\s*$/i) {
+    if ($line =~ m/^(enable|nosmurfs|tcpflags|optimize):\s*(0|1)\s*$/i) {
        $opt = lc($1);
        $value = int($2);
     } elsif ($line =~ m/^(log_level_in|log_level_out|tcp_flags_log_level|smurf_log_level):\s*(($loglevels)\s*)?$/i) {
@@ -2234,28 +2174,14 @@ sub read_local_vm_config {
     return $vmdata;
 };
 
-sub read_bridges_config {
-
-    my $bridgehash = {};
-
-    dir_glob_foreach('/sys/class/net', 'vmbr(\d+)', sub {
-        my ($bridge) = @_;
-
-       dir_glob_foreach("/sys/class/net/$bridge/brif", '((eth|bond)(\d+)(\.(\d+))?)', sub {
-           my ($interface) = @_;
-           push @{$bridgehash->{$bridge}}, $interface;
-       });
-    });
-
-    return $bridgehash;
-};
-
 sub load_vmfw_conf {
-    my ($vmid) = @_;
+    my ($vmid, $dir) = @_;
 
     my $vmfw_conf = {};
 
-    my $filename = "/etc/pve/firewall/$vmid.fw";
+    $dir = "/etc/pve/firewall" if !defined($dir);
+
+    my $filename = "$dir/$vmid.fw";
     if (my $fh = IO::File->new($filename, O_RDONLY)) {
        $vmfw_conf = parse_vm_fw_rules($filename, $fh);
     }
@@ -2360,7 +2286,7 @@ sub save_vmfw_conf {
     my $options = $vmfw_conf->{options};
     $raw .= &$format_options($options) if scalar(keys %$options);
 
-    my $rules = $vmfw_conf->{rules};
+    my $rules = $vmfw_conf->{rules} || [];
     if (scalar(@$rules)) {
        $raw .= "[RULES]\n\n";
        $raw .= &$format_rules($rules, 1);
@@ -2372,11 +2298,12 @@ sub save_vmfw_conf {
 }
 
 sub read_vm_firewall_configs {
-    my ($vmdata) = @_;
+    my ($vmdata, $dir) = @_;
+
     my $vmfw_configs = {};
 
     foreach my $vmid (keys %{$vmdata->{qemu}}, keys %{$vmdata->{openvz}}) {
-       my $vmfw_conf = load_vmfw_conf($vmid);
+       my $vmfw_conf = load_vmfw_conf($vmid, $dir);
        next if !$vmfw_conf->{options}; # skip if file does not exists
        $vmfw_configs->{$vmid} = $vmfw_conf;
     }
@@ -2519,39 +2446,14 @@ sub read_pvefw_status {
     return $status;
 }
 
-# fixme: move to pve-common PVE::ProcFSTools
-sub read_proc_net_route {
-    my $filename = "/proc/net/route";
-
-    my $res = {};
-
-    my $fh = IO::File->new ($filename, "r");
-    return $res if !$fh;
-
-    my $int_to_quad = sub {
-       return join '.' => map { ($_[0] >> 8*(3-$_)) % 256 } (3, 2, 1, 0);
-    };
-
-    while (defined(my $line = <$fh>)) {
-       next if $line =~/^Iface\s+Destination/; # skip head
-       my ($iface, $dest, $gateway, $metric, $mask, $mtu) = (split(/\s+/, $line))[0,1,2,6,7,8];
-       push @{$res->{$iface}}, {
-           dest => &$int_to_quad(hex($dest)),
-           gateway => &$int_to_quad(hex($gateway)),
-           mask => &$int_to_quad(hex($mask)),
-           metric => $metric,
-           mtu => $mtu,
-       };
-    }
-
-    return $res;
-}
-
 sub load_clusterfw_conf {
+    my ($filename) = @_;
+
+    $filename = $clusterfw_conf_filename if !defined($filename);
 
     my $cluster_conf = {};
-     if (my $fh = IO::File->new($clusterfw_conf_filename, O_RDONLY)) {
-       $cluster_conf = parse_cluster_fw_rules($clusterfw_conf_filename, $fh);
+    if (my $fh = IO::File->new($filename, O_RDONLY)) {
+       $cluster_conf = parse_cluster_fw_rules($filename, $fh);
     }
 
     return $cluster_conf;
@@ -2604,10 +2506,13 @@ sub save_clusterfw_conf {
 }
 
 sub load_hostfw_conf {
+    my ($filename) = @_;
+
+    $filename = $hostfw_conf_filename if !defined($filename);
 
     my $hostfw_conf = {};
-    if (my $fh = IO::File->new($hostfw_conf_filename, O_RDONLY)) {
-       $hostfw_conf = parse_host_fw_rules($hostfw_conf_filename, $fh);
+    if (my $fh = IO::File->new($filename, O_RDONLY)) {
+       $hostfw_conf = parse_host_fw_rules($filename, $fh);
     }
     return $hostfw_conf;
 }
@@ -2631,17 +2536,30 @@ sub save_hostfw_conf {
 }
 
 sub compile {
-    my ($cluster_conf, $hostfw_conf) = @_;
+    my ($cluster_conf, $hostfw_conf, $vmdata) = @_;
 
-    $cluster_conf = load_clusterfw_conf() if !$cluster_conf;
-    $hostfw_conf = load_hostfw_conf() if !$hostfw_conf;
+    my $vmfw_configs;
 
-    my $vmdata = read_local_vm_config();
-    my $vmfw_configs = read_vm_firewall_configs($vmdata);
+    if ($vmdata) { # test mode
+       my $testdir = $vmdata->{testdir} || die "no test directory specified";
+       my $filename = "$testdir/cluster.fw";
+       die "missing test file '$filename'\n" if ! -f $filename;
+       $cluster_conf = load_clusterfw_conf($filename);
+
+       $filename = "$testdir/host.fw";
+       die "missing test file '$filename'\n" if ! -f $filename;
+       $hostfw_conf = load_hostfw_conf($filename);
+
+       $vmfw_configs = read_vm_firewall_configs($vmdata, $testdir);
+    } else { # normal operation
+       $cluster_conf = load_clusterfw_conf() if !$cluster_conf;
+
+       $hostfw_conf = load_hostfw_conf() if !$hostfw_conf;
+
+       $vmdata = read_local_vm_config();
+       $vmfw_configs = read_vm_firewall_configs($vmdata);
+    }
 
-    my $routing_table = read_proc_net_route();
-    
-    my $bridges_config = read_bridges_config();
 
     my $ipset_ruleset = {};
     generate_ipset_chains($ipset_ruleset, $cluster_conf);
@@ -2652,15 +2570,44 @@ sub compile {
     ruleset_create_chain($ruleset, "PVEFW-OUTPUT");
 
     ruleset_create_chain($ruleset, "PVEFW-FORWARD");
-
+    
     my $hostfw_options = $hostfw_conf->{options} || {};
 
+    # fixme: what log level should we use here?
+    my $loglevel = get_option_log_level($hostfw_options, "log_level_out");
+
+    ruleset_chain_add_conn_filters($ruleset, "PVEFW-FORWARD", "ACCEPT");
+
+    if ($cluster_conf->{ipset}->{blacklist}){
+       ruleset_addlog($ruleset, "PVEFW-FORWARD", 0, "DROP: ", $loglevel, "-m set --match-set PVEFW-blacklist src");
+       ruleset_addrule($ruleset, "PVEFW-FORWARD", "-m set --match-set PVEFW-blacklist src -j DROP");
+    }
+
+    ruleset_create_chain($ruleset, "PVEFW-VENET-OUT");
+    ruleset_addrule($ruleset, "PVEFW-FORWARD", "-i venet0 -j PVEFW-VENET-OUT");
+    ruleset_addrule($ruleset, "PVEFW-INPUT", "-i venet0 -j PVEFW-VENET-OUT");
+
+    ruleset_create_chain($ruleset, "PVEFW-FWBR-IN");
+    ruleset_chain_add_input_filters($ruleset, "PVEFW-FWBR-IN", $hostfw_options);
+
+    ruleset_addrule($ruleset, "PVEFW-FORWARD", "-m physdev --physdev-is-bridged --physdev-in fwln+ -j PVEFW-FWBR-IN");
+
+    ruleset_create_chain($ruleset, "PVEFW-FWBR-OUT");
+    ruleset_addrule($ruleset, "PVEFW-FORWARD", "-m physdev --physdev-is-bridged --physdev-out fwln+ -j PVEFW-FWBR-OUT");
+
+    ruleset_create_chain($ruleset, "PVEFW-VENET-IN");
+    ruleset_chain_add_input_filters($ruleset, "PVEFW-VENET-IN", $hostfw_options);
+
+    ruleset_addrule($ruleset, "PVEFW-FORWARD", "-o venet0 -j PVEFW-VENET-IN");
+
     generate_std_chains($ruleset, $hostfw_options);
 
     my $hostfw_enable = !(defined($hostfw_options->{enable}) && ($hostfw_options->{enable} == 0));
 
     enable_host_firewall($ruleset, $hostfw_conf, $cluster_conf) if $hostfw_enable;
 
+    ruleset_addrule($ruleset, "PVEFW-OUTPUT", "-o venet0 -j PVEFW-VENET-IN");
+
     # generate firewall rules for QEMU VMs
     foreach my $vmid (keys %{$vmdata->{qemu}}) {
        my $conf = $vmdata->{qemu}->{$vmid};
@@ -2674,18 +2621,11 @@ sub compile {
            next if !$net;
            my $iface = "tap${vmid}i$1";
 
-           my $bridge = $net->{bridge};
-           next if !$bridge; # fixme: ?
-
-           $bridge .= "v$net->{tag}" if $net->{tag};
-
-           generate_bridge_chains($ruleset, $hostfw_conf, $bridge, $routing_table, $bridges_config);
-
            my $macaddr = $net->{macaddr};
            generate_tap_rules_direction($ruleset, $cluster_conf, $hostfw_conf, $iface, $netid, $macaddr,
-                                        $vmfw_conf, $vmid, $bridge, 'IN');
+                                        $vmfw_conf, $vmid, 'IN');
            generate_tap_rules_direction($ruleset, $cluster_conf, $hostfw_conf, $iface, $netid, $macaddr,
-                                        $vmfw_conf, $vmid, $bridge, 'OUT');
+                                        $vmfw_conf, $vmid, 'OUT');
        }
     }
 
@@ -2699,6 +2639,7 @@ sub compile {
 
        if ($conf->{ip_address} && $conf->{ip_address}->{value}) {
            my $ip = $conf->{ip_address}->{value};
+           $ip =~ s/\s/,/g;  
            generate_venet_rules_direction($ruleset, $cluster_conf, $hostfw_conf, $vmfw_conf, $vmid, $ip, 'IN');
            generate_venet_rules_direction($ruleset, $cluster_conf, $hostfw_conf, $vmfw_conf, $vmid, $ip, 'OUT');
        }
@@ -2707,47 +2648,21 @@ sub compile {
            my $netif = PVE::OpenVZ::parse_netif($conf->{netif}->{value});
            foreach my $netid (keys %$netif) {
                my $d = $netif->{$netid};
-               my $bridge = $d->{bridge};
-               if (!$bridge) {
-                   warn "no bridge device for CT $vmid iface '$netid'\n";
-                   next; # fixme?
-               }
-
-               generate_bridge_chains($ruleset, $hostfw_conf, $bridge, $routing_table, $bridges_config);
 
                my $macaddr = $d->{mac};
                my $iface = $d->{host_ifname};
                generate_tap_rules_direction($ruleset, $cluster_conf, $hostfw_conf, $iface, $netid, $macaddr,
-                                            $vmfw_conf, $vmid, $bridge, 'IN');
+                                            $vmfw_conf, $vmid, 'IN');
                generate_tap_rules_direction($ruleset, $cluster_conf, $hostfw_conf, $iface, $netid, $macaddr,
-                                            $vmfw_conf, $vmid, $bridge, 'OUT');
+                                            $vmfw_conf, $vmid, 'OUT');
            }
        }
     }
 
-    if($hostfw_options->{optimize}){
-
-       my $accept = ruleset_chain_exist($ruleset, "PVEFW-IPS") ? "PVEFW-IPS" : "ACCEPT";
-       ruleset_insertrule($ruleset, "PVEFW-FORWARD", "-m conntrack --ctstate RELATED,ESTABLISHED -j $accept");
-       ruleset_insertrule($ruleset, "PVEFW-FORWARD", "-m conntrack --ctstate INVALID -j DROP");
+    if(ruleset_chain_exist($ruleset, "PVEFW-IPS")){
+       ruleset_insertrule($ruleset, "PVEFW-FORWARD", "-m conntrack --ctstate RELATED,ESTABLISHED -j PVEFW-IPS");
     }
 
-    # fixme: what log level should we use here?
-    my $loglevel = get_option_log_level($hostfw_options, "log_level_out");
-
-    # fixme: should we really block inter-bridge traffic?
-
-    # always allow traffic from containers?
-    ruleset_addrule($ruleset, "PVEFW-FORWARD", "-i venet0 -j RETURN");
-
-    # disable interbridge routing
-    ruleset_addrule($ruleset, "PVEFW-FORWARD", "-o vmbr+ -j PVEFW-Drop");
-    ruleset_addrule($ruleset, "PVEFW-FORWARD", "-i vmbr+ -j PVEFW-Drop");
-    ruleset_addlog($ruleset, "PVEFW-FORWARD", 0, "DROP: ", $loglevel, "-o vmbr+");
-    ruleset_addlog($ruleset, "PVEFW-FORWARD", 0, "DROP: ", $loglevel, "-i vmbr+");
-    ruleset_addrule($ruleset, "PVEFW-FORWARD", "-o vmbr+ -j DROP");
-    ruleset_addrule($ruleset, "PVEFW-FORWARD", "-i vmbr+ -j DROP");
-
     return ($ruleset, $ipset_ruleset);
 }