]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - config/firewall/rules.pl
Merge remote-tracking branch 'amarx/firewall-dnat' into next
[ipfire-2.x.git] / config / firewall / rules.pl
index 2c314d16e5d320fc0a6499669f722974e161979a..e0f69554e847d7949fc28b50e657d1cf6101ed9e 100755 (executable)
@@ -291,24 +291,30 @@ sub buildrules {
 
                        foreach my $src (@sources) {
                                # Skip invalid source.
+                               next unless (defined $src);
                                next unless ($src);
 
                                # Sanitize source.
-                               my $source = $src;
+                               my $source = @$src[0];
                                if ($source ~~ @ANY_ADDRESSES) {
                                        $source = "";
                                }
 
+                               my $source_intf = @$src[1];
+
                                foreach my $dst (@destinations) {
                                        # Skip invalid rules.
+                                       next unless (defined $dst);
                                        next if (!$dst || ($dst eq "none"));
 
                                        # Sanitize destination.
-                                       my $destination = $dst;
+                                       my $destination = @$dst[0];
                                        if ($destination ~~ @ANY_ADDRESSES) {
                                                $destination = "";
                                        }
 
+                                       my $destination_intf = @$dst[1];
+
                                        # Array with iptables arguments.
                                        my @options = ();
 
@@ -325,12 +331,20 @@ sub buildrules {
                                                push(@source_options, ("-s", $source));
                                        }
 
+                                       if ($source_intf) {
+                                               push(@source_options, ("-i", $source_intf));
+                                       }
+
                                        # Prepare destination options.
                                        my @destination_options = ();
                                        if ($destination) {
                                                push(@destination_options, ("-d", $destination));
                                        }
 
+                                       if ($destination_intf) {
+                                               push(@destination_options, ("-o", $destination_intf));
+                                       }
+
                                        # Add time constraint options.
                                        push(@options, @time_options);
 
@@ -354,20 +368,21 @@ sub buildrules {
 
                                                # Destination NAT
                                                if ($NAT_MODE eq "DNAT") {
-                                                       # Make port-forwardings useable from the internal networks.
-                                                       my @internal_addresses = &fwlib::get_internal_firewall_ip_addresses(1);
-                                                       unless ($nat_address ~~ @internal_addresses) {
-                                                               &add_dnat_mangle_rules($nat_address, @options);
-                                                       }
-
                                                        my @nat_options = ();
                                                        if ($protocol ne "all") {
                                                                my @nat_protocol_options = &get_protocol_options($hash, $key, $protocol, 1);
                                                                push(@nat_options, @nat_protocol_options);
                                                        }
+                                                       push(@nat_options, @time_options);
+
+                                                       # Make port-forwardings useable from the internal networks.
+                                                       my @internal_addresses = &fwlib::get_internal_firewall_ip_addresses(1);
+                                                       unless ($nat_address ~~ @internal_addresses) {
+                                                               &add_dnat_mangle_rules($nat_address, $source_intf, @nat_options);
+                                                       }
+
                                                        push(@nat_options, @source_options);
                                                        push(@nat_options, ("-d", $nat_address));
-                                                       push(@nat_options, @time_options);
 
                                                        my $dnat_port;
                                                        if ($protocol_has_ports) {
@@ -680,6 +695,7 @@ sub get_dnat_target_port {
 
 sub add_dnat_mangle_rules {
        my $nat_address = shift;
+       my $interface = shift;
        my @options = @_;
 
        my $mark = 0;
@@ -690,6 +706,8 @@ sub add_dnat_mangle_rules {
                next unless (exists $defaultNetworks{$zone . "_NETADDRESS"});
                next unless (exists $defaultNetworks{$zone . "_NETMASK"});
 
+               next if ($interface && $interface ne $defaultNetworks{$zone . "_DEV"});
+
                my @mangle_options = @options;
 
                my $netaddress = $defaultNetworks{$zone . "_NETADDRESS"};