+}
+
+sub generate_nfqueue {
+ my ($options) = @_;
+
+ my $action = "";
+ if($options->{ips}){
+ $action = "NFQUEUE";
+ if($options->{ips_queues} && $options->{ips_queues} =~ m/^(\d+)(:(\d+))?$/) {
+ if(defined($3) && defined($1)) {
+ $action .= " --queue-balance $1:$3";
+ }elsif (defined($1)) {
+ $action .= " --queue-num $1";
+ }
+ }
+ $action .= " --queue-bypass";
+ }else{
+ $action = "ACCEPT";
+ }
+
+ return $action;
+}
+
+sub ruleset_generate_vm_ipsrules {
+ my ($ruleset, $options, $direction, $iface, $bridge) = @_;
+
+ if ($options->{ips} && $direction eq 'IN') {
+ my $nfqueue = generate_nfqueue($options);
+
+ if (!ruleset_chain_exist($ruleset, "$bridge-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");
+ }
+}
+
+sub generate_venet_rules_direction {
+ my ($ruleset, $cluster_conf, $vmfw_conf, $vmid, $ip, $direction) = @_;
+
+ parse_address_list($ip); # make sure we have a valid $ip list
+
+ my $lc_direction = lc($direction);
+
+ my $rules = $vmfw_conf->{rules};
+
+ my $options = $vmfw_conf->{options};
+ my $loglevel = get_option_log_level($options, "log_level_${lc_direction}");
+
+ my $chain = "venet0-$vmid-$direction";
+
+ ruleset_create_vm_chain($ruleset, $chain, $options, undef, $direction);
+
+ ruleset_generate_vm_rules($ruleset, $rules, $cluster_conf, $chain, 'venet', $direction);
+
+ # implement policy
+ my $policy;
+
+ if ($direction eq 'OUT') {
+ $policy = $options->{policy_out} || 'ACCEPT'; # allow everything by default
+ } else {
+ $policy = $options->{policy_in} || 'DROP'; # allow nothing by default
+ }
+
+ my $accept = generate_nfqueue($options);
+ 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", {
+ 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", {
+ action => $chain,
+ dest => $ip,
+ iface_out => 'venet0'});
+ }
+}
+
+sub generate_tap_rules_direction {
+ my ($ruleset, $cluster_conf, $iface, $netid, $macaddr, $vmfw_conf, $vmid, $bridge, $direction) = @_;
+
+ my $lc_direction = lc($direction);
+
+ my $rules = $vmfw_conf->{rules};
+
+ my $options = $vmfw_conf->{options};
+ my $loglevel = get_option_log_level($options, "log_level_${lc_direction}");
+
+ my $tapchain = "$iface-$direction";
+
+ ruleset_create_vm_chain($ruleset, $tapchain, $options, $macaddr, $direction);
+
+ ruleset_generate_vm_rules($ruleset, $rules, $cluster_conf, $tapchain, $netid, $direction, $options);
+
+ ruleset_generate_vm_ipsrules($ruleset, $options, $direction, $iface, $bridge);