- if ($rule->{dport}) {
- if ($proto eq 'icmp') {
- # Note: we use dport to store --icmp-type
- die "unknown icmp-type '$rule->{dport}'\n"
- if $rule->{dport} !~ /^\d+$/ && !defined($icmp_type_names->{$rule->{dport}});
- push @cmd, "-m icmp --icmp-type $rule->{dport}";
- } elsif ($proto eq 'icmpv6') {
- # Note: we use dport to store --icmpv6-type
- die "unknown icmpv6-type '$rule->{dport}'\n"
- if $rule->{dport} !~ /^\d+$/ && !defined($icmpv6_type_names->{$rule->{dport}});
- push @cmd, "-m icmpv6 --icmpv6-type $rule->{dport}";
- } elsif (!$PROTOCOLS_WITH_PORTS->{$proto}) {
- die "protocol $proto does not have ports\n";
- } else {
- if ($nbdport > 1) {
- if ($multiport == 2) {
- push @cmd, "--ports $rule->{dport}";
- } else {
- push @cmd, "--dports $rule->{dport}";
- }
+ if (defined $rule->{match}) {
+ push @match, $rule->{match};
+ } else {
+ push @match, "-i $rule->{iface_in}" if $rule->{iface_in};
+ push @match, "-o $rule->{iface_out}" if $rule->{iface_out};
+
+ if ($rule->{source}) {
+ push @match, ipt_gen_src_or_dst_match($rule->{source}, 's', $ipversion, $cluster_conf, $fw_conf);
+ }
+ if ($rule->{dest}) {
+ push @match, ipt_gen_src_or_dst_match($rule->{dest}, 'd', $ipversion, $cluster_conf, $fw_conf);
+ }
+
+ if (my $proto = $rule->{proto}) {
+ push @match, "-p $proto";
+
+ my $multidport = defined($rule->{dport}) && parse_port_name_number_or_range($rule->{dport}, 1);
+ my $multisport = defined($rule->{sport}) && parse_port_name_number_or_range($rule->{sport}, 0);
+
+ my $add_dport = sub {
+ return if !$rule->{dport};
+
+ if ($proto eq 'icmp') {
+ # Note: we use dport to store --icmp-type
+ die "unknown icmp-type '$rule->{dport}'\n"
+ if $rule->{dport} !~ /^\d+$/ && !defined($icmp_type_names->{$rule->{dport}});
+ push @match, "-m icmp --icmp-type $rule->{dport}";
+ } elsif ($proto eq 'icmpv6') {
+ # Note: we use dport to store --icmpv6-type
+ die "unknown icmpv6-type '$rule->{dport}'\n"
+ if $rule->{dport} !~ /^\d+$/ && !defined($icmpv6_type_names->{$rule->{dport}});
+ push @match, "-m icmpv6 --icmpv6-type $rule->{dport}";
+ } elsif (!$PROTOCOLS_WITH_PORTS->{$proto}) {
+ die "protocol $proto does not have ports\n";
+ } elsif ($multidport) {
+ push @match, "--match multiport", "--dports $rule->{dport}";