+
+ return $rules;
+};
+
+sub verify_rule {
+ my ($rule, $allow_groups) = @_;
+
+ my $type = $rule->{type};
+
+ raise_param_exc({ type => "missing property"}) if !$type;
+ raise_param_exc({ action => "missing property"}) if !$rule->{action};
+
+ if ($type eq 'in' || $type eq 'out') {
+ raise_param_exc({ action => "unknown action '$rule->{action}'"})
+ if $rule->{action} !~ m/^(ACCEPT|DROP|REJECT)$/;
+ } elsif ($type eq 'group') {
+ raise_param_exc({ type => "security groups not allowed"})
+ if !$allow_groups;
+ raise_param_exc({ action => "invalid characters in security group name"})
+ if $rule->{action} !~ m/^${security_group_pattern}$/;
+ } else {
+ raise_param_exc({ type => "unknown rule type '$type'"});
+ }
+
+ # fixme: verify $rule->{iface}?
+
+ if ($rule->{macro}) {
+ my $preferred_name = $pve_fw_preferred_macro_names->{lc($rule->{macro})};
+ raise_param_exc({ macro => "unknown macro '$rule->{macro}'"}) if !$preferred_name;
+ $rule->{macro} = $preferred_name;
+ }
+
+ if ($rule->{dport}) {
+ eval { parse_port_name_number_or_range($rule->{dport}); };
+ raise_param_exc({ dport => $@ }) if $@;
+ }
+
+ if ($rule->{sport}) {
+ eval { parse_port_name_number_or_range($rule->{sport}); };
+ raise_param_exc({ sport => $@ }) if $@;
+ }
+
+ if ($rule->{source}) {
+ eval { parse_address_list($rule->{source}); };
+ raise_param_exc({ source => $@ }) if $@;
+ }
+
+ if ($rule->{dest}) {
+ eval { parse_address_list($rule->{dest}); };
+ raise_param_exc({ dest => $@ }) if $@;
+ }
+
+ if ($rule->{macro}) {
+ &$apply_macro($rule->{macro}, $rule, 1);
+ }
+
+ return $rule;