return ($opt, $value);
}
+sub resolve_alias {
+ my ($clusterfw_conf, $fw_conf, $cidr) = @_;
+
+ if ($cidr !~ m/^\d/) {
+ my $alias = lc($cidr);
+ my $e = $fw_conf->{aliases}->{$alias} if $fw_conf;
+ $e = $clusterfw_conf->{aliases}->{$alias} if !$e && $clusterfw_conf;
+ return $e->{cidr} if $e;
+
+ die "no such alias '$cidr'\n";
+ }
+
+ return $cidr;
+}
+
sub parse_alias {
my ($line) = @_;
return undef;
}
-sub generic_fw_rules_parser {
+sub generic_fw_config_parser {
my ($filename, $fh, $verbose, $cluster_conf, $empty_conf, $rule_env) = @_;
my $section;
my $res = $empty_conf;
- my $ipset_option = get_standard_option('ipset-name');
-
while (defined(my $line = <$fh>)) {
next if $line =~ m/^#/;
next if $line =~ m/^\s*$/;
$line =~ m/^(\!)?\s*(\S+)\s*$/;
my $nomatch = $1;
my $cidr = $2;
+ my $errors;
- if($cidr !~ m/^${ip_alias_pattern}$/) {
- $cidr =~ s|/32$||;
+ if ($nomatch && !$feature_ipset_nomatch) {
+ $errors->{nomatch} = "nomatch not supported by kernel";
+ }
- eval { pve_verify_ipv4_or_cidr($cidr); };
- if (my $err = $@) {
- warn "$prefix: $cidr - $err";
- next;
+ eval {
+ if ($cidr =~ m/^${ip_alias_pattern}$/) {
+ resolve_alias($cluster_conf, $res, $cidr); # make sure alias exists
+ } else {
+ $cidr =~ s|/32$||;
+ pve_verify_ipv4_or_cidr_or_alias($cidr);
}
+ };
+ if (my $err = $@) {
+ $errors->{cidr} = $err;
}
my $entry = { cidr => $cidr };
$entry->{nomatch} = 1 if $nomatch;
$entry->{comment} = $comment if $comment;
+ $entry->{errors} = $errors if $errors;
push @{$res->{$section}->{$group}}, $entry;
} else {
return $res;
}
-sub parse_host_fw_rules {
+sub parse_hostfw_config {
my ($filename, $fh, $cluster_conf, $verbose) = @_;
my $empty_conf = { rules => [], options => {}};
- return generic_fw_rules_parser($filename, $fh, $verbose, $cluster_conf, $empty_conf, 'host');
+ return generic_fw_config_parser($filename, $fh, $verbose, $cluster_conf, $empty_conf, 'host');
}
-sub parse_vm_fw_rules {
+sub parse_vmfw_config {
my ($filename, $fh, $cluster_conf, $rule_env, $verbose) = @_;
my $empty_conf = {
ipset_comments => {},
};
- return generic_fw_rules_parser($filename, $fh, $verbose, $cluster_conf, $empty_conf, $rule_env);
+ return generic_fw_config_parser($filename, $fh, $verbose, $cluster_conf, $empty_conf, $rule_env);
}
-sub parse_cluster_fw_rules {
+sub parse_clusterfw_config {
my ($filename, $fh, $verbose) = @_;
my $section;
ipset_comments => {},
};
- return generic_fw_rules_parser($filename, $fh, $verbose, $empty_conf, $empty_conf, 'cluster');
+ return generic_fw_config_parser($filename, $fh, $verbose, $empty_conf, $empty_conf, 'cluster');
}
sub run_locked {
my $filename = "$dir/$vmid.fw";
if (my $fh = IO::File->new($filename, O_RDONLY)) {
- $vmfw_conf = parse_vm_fw_rules($filename, $fh, $cluster_conf, $rule_env, $verbose);
+ $vmfw_conf = parse_vmfw_config($filename, $fh, $cluster_conf, $rule_env, $verbose);
$vmfw_conf->{vmid} = $vmid;
}
# remove duplicates
my $nethash = {};
foreach my $entry (@$options) {
- my $cidr = $entry->{cidr};
- if ($cidr =~ m/^${ip_alias_pattern}$/) {
- my $alias = lc($cidr);
- my $e = $fw_conf->{aliases}->{$alias} if $fw_conf;
- $e = $clusterfw_conf->{aliases}->{$alias} if !$e && $clusterfw_conf;
- if ($e) {
- $entry->{cidr} = $e->{cidr};
- $nethash->{$entry->{cidr}} = $entry;
- } else {
- warn "no such alias '$cidr'\n";
- }
- } else {
- $nethash->{$entry->{cidr}} = $entry;
- }
+ eval {
+ my $cidr = resolve_alias($clusterfw_conf, $fw_conf, $entry->{cidr});
+ $nethash->{$cidr} = { cidr => $cidr, nomatch => $entry->{nomatch} };
+ };
+ warn $@ if $@;
}
foreach my $cidr (sort keys %$nethash) {
my $cluster_conf = {};
if (my $fh = IO::File->new($filename, O_RDONLY)) {
- $cluster_conf = parse_cluster_fw_rules($filename, $fh, $verbose);
+ $cluster_conf = parse_clusterfw_config($filename, $fh, $verbose);
}
return $cluster_conf;
my $hostfw_conf = {};
if (my $fh = IO::File->new($filename, O_RDONLY)) {
- $hostfw_conf = parse_host_fw_rules($filename, $fh, $cluster_conf, $verbose);
+ $hostfw_conf = parse_hostfw_config($filename, $fh, $cluster_conf, $verbose);
}
return $hostfw_conf;
}