Physdev module support
authorJamie Cameron <jcameron@webmin.com>
Sat, 26 Jun 2010 08:03:08 +0000 (01:03 -0700)
committerJamie Cameron <jcameron@webmin.com>
Sat, 26 Jun 2010 08:03:08 +0000 (01:03 -0700)
firewall/CHANGELOG
firewall/edit_rule.cgi
firewall/firewall-lib.pl
firewall/lang/en
firewall/save_rule.cgi

index 35843e5..67fe627 100644 (file)
@@ -35,3 +35,4 @@ Added a button to move rules to another chain.
 Added a button to rename an existing custom chain.
 ---- Changes since 1.510 ----
 Better handle the case where a rule has a --comment format description, but # format comments are enabled.
+Added support for physdev module options, for matching based on the bridged interface.
index df6085c..5ed9720 100755 (executable)
@@ -310,6 +310,7 @@ if ($rule->{'chain'} eq 'OUTPUT') {
 
 print "<tr> <td colspan=2><hr></td> </tr>\n";
 
+# Connection states
 print "<tr> <td valign=top><b>$text{'edit_state'}</b></td>\n";
 print "<td><table cellpadding=0 cellspacing=0><tr><td valign=top>",
       &print_mode("state", $rule->{'state'}),"</td>\n";
@@ -322,14 +323,40 @@ foreach $s ('NEW', 'ESTABLISHED', 'RELATED', 'INVALID', 'UNTRACKED') {
        }
 print "</select></td></tr></table></td> </tr>\n";
 
+# Type of service
 print "<tr> <td><b>$text{'edit_tos'}</b></td>\n";
 print "<td>",&print_mode("tos", $rule->{'tos'}),"\n";
 print &tos_input("tos", $rule->{'tos'}->[1]),"</td> </tr>\n";
 
 print "<tr> <td colspan=2><hr></td> </tr>\n";
 
+# Input physical device
+print "<tr> <td><b>$text{'edit_physdevin'}</b></td>\n";
+print "<td>",&print_mode("physdevin", $rule->{'physdev-in'}),"\n";
+print &interface_choice("physdevin", $rule->{'physdev-in'}->[1]);
+print "</td> </tr>\n";
+
+# Output physical device
+print "<tr> <td><b>$text{'edit_physdevout'}</b></td>\n";
+print "<td>",&print_mode("physdevout", $rule->{'physdev-out'}),"\n";
+print &interface_choice("physdevout", $rule->{'physdev-out'}->[1]);
+print "</td> </tr>\n";
+
+# Physdev match modes
+print "<tr> <td><b>$text{'edit_physdevisin'}</b></td>\n";
+print "<td>",&print_mode("physdevisin", $rule->{'physdev-is-in'},
+                        $text{'yes'}, $text{'no'}),"</td> </tr>\n";
+print "<tr> <td><b>$text{'edit_physdevisout'}</b></td>\n";
+print "<td>",&print_mode("physdevisout", $rule->{'physdev-is-out'},
+                        $text{'yes'}, $text{'no'}),"</td> </tr>\n";
+print "<tr> <td><b>$text{'edit_physdevisbridged'}</b></td>\n";
+print "<td>",&print_mode("physdevisbridged", $rule->{'physdev-is-bridged'},
+                        $text{'yes'}, $text{'no'}),"</td> </tr>\n";
+
+print "<tr> <td colspan=2><hr></td> </tr>\n";
+
 # Show unknown modules
-@mods = grep { !/^(tcp|udp|icmp|multiport|mac|limit|owner|state|tos|comment)$/ } map { $_->[1] } @{$rule->{'m'}};
+@mods = grep { !/^(tcp|udp|icmp|multiport|mac|limit|owner|state|tos|comment|physdev)$/ } map { $_->[1] } @{$rule->{'m'}};
 print "<tr> <td><b>$text{'edit_mods'}</b></td>\n";
 printf "<td colspan=3><input name=mods size=50 value='%s'></td> </tr>\n",
        join(" ", @mods);
index 71544b4..dc52545 100755 (executable)
@@ -31,7 +31,12 @@ else {
                 '--pid-owner', '--sid-owner', '--state', '--tos', '-j',
                 '--to-ports', '--to-destination', '--to-source',
                 '--reject-with', '--dports', '--sports',
-                '--comment', '--physdev-is-bridged');
+                '--comment',
+                '--physdev-is-bridged',
+                '--physdev-is-in',
+                '--physdev-is-out',
+                '--physdev-in',
+                '--physdev-out');
 
 # get_iptables_save([file])
 # Parse the iptables save file into a list of tables 
@@ -186,6 +191,7 @@ else {
 }
 
 # describe_rule(&rule)
+# Returns a human-readable description of some rule conditions
 sub describe_rule
 {
 local (@c, $d);
@@ -194,7 +200,7 @@ foreach $d ('p', 's', 'd', 'i', 'o', 'f', 'dport',
            'icmp-type', 'mac-source', 'limit', 'limit-burst',
            'ports', 'uid-owner', 'gid-owner',
            'pid-owner', 'sid-owner', 'state', 'tos',
-           'dports', 'sports') {
+           'dports', 'sports', 'physdev-in', 'physdev-out') {
        if ($_[0]->{$d}) {
                local ($n, @v) = @{$_[0]->{$d}};
                @v = map { uc($_) } @v if ($d eq 'p');
index e5fa821..74ef302 100644 (file)
@@ -117,6 +117,10 @@ desc_state=state of connection is $1
 desc_state!=state of connection is not $1
 desc_tos=type of service field is $1
 desc_tos!=type of service field is not $1
+desc_physdev-in=input physical interface is $1
+desc_physdev-in!=input physical interface is not $1
+desc_physdev-out=output physical interface is $1
+desc_physdev-out!=output physical interface is not $1
 desc_conds=If $1
 desc_and=and
 desc_always=Always
@@ -189,6 +193,11 @@ edit_args=Additional parameters
 edit_mods=Additional IPtables modules
 edit_rwith=Reject with ICMP type
 edit_rwithtype=Type $1
+edit_physdevin=Incoming physical interface
+edit_physdevout=Outgoing physical interface
+edit_physdevisin=Packet incoming on bridge interface
+edit_physdevisout=Packet outgoing on bridge interface
+edit_physdevisbridged=Packet is being bridged
 
 save_err=Failed to save rule
 save_echain=Missing or invalid chain to run
@@ -232,6 +241,8 @@ save_espfrom=Invalid starting port for SNAT
 save_espto=Missing or invalid ending port for SNAT
 save_estates=No connection states selected
 save_ecanjump=You are not allowed to use this action
+save_ephysdevin=Missing or invalid incoming physical interface
+save_ephysdevout=Missing or invalid outgoing physical interface
 
 delete_title=Delete Chain
 delete_rusure=Are you sure you want to delete the chain $1 ? $2 rules within it will be deleted.
index b45874c..66cb43d 100755 (executable)
@@ -308,6 +308,7 @@ else {
                        }
                }
 
+       # Save connection states and TOS
        if (&parse_mode("state", $rule, "state")) {
                @states = split(/\0/, $in{'state'});
                @states || &error($text{'save_estates'});
@@ -319,6 +320,35 @@ else {
                push(@mods, "tos");
                }
 
+       # Parse physical input and output interfaces
+       if (&parse_mode("physdevin", $rule, "physdev-in")) {
+               $in{'physdevin'} ne '' || $in{'physdevin_other'} =~ /^\S+$/ ||
+                       &error($text{'save_ephysdevin'});
+               $rule->{'physdev-in'}->[1] =
+                 $in{'physdevin'} eq '' || $in{'physdevin'} eq 'other' ?
+                       $in{'physdevin_other'} : $in{'physdevin'};
+               push(@mods, "physdev");
+               }
+       if (&parse_mode("physdevout", $rule, "physdev-out")) {
+               $in{'physdevout'} ne '' || $in{'physdevout_other'} =~ /^\S+$/ ||
+                       &error($text{'save_ephysdevout'});
+               $rule->{'physdev-out'}->[1] =
+                 $in{'physdevout'} eq '' || $in{'physdevout'} eq 'other' ?
+                       $in{'physdevout_other'} : $in{'physdevout'};
+               push(@mods, "physdev");
+               }
+
+       # Parse physdev match modes
+       if (&parse_mode("physdevisin", $rule, "physdev-is-in")) {
+               push(@mods, "physdev");
+               }
+       if (&parse_mode("physdevisout", $rule, "physdev-is-out")) {
+               push(@mods, "physdev");
+               }
+       if (&parse_mode("physdevisbridged", $rule, "physdev-is-bridged")) {
+               push(@mods, "physdev");
+               }
+
        # Add custom paramters and modules
        $rule->{'args'} = $in{'args'};
        push(@mods, split(/\s+/, $in{'mods'}));